diff --git a/dist/changes-1.1.0 b/dist/changes-1.1.0
index d19bcc0d8c5df511b7255ac21813d7a34f6bd814..ca31d5783c2470901e45d092b21b4ec9a59f153d 100644
--- a/dist/changes-1.1.0
+++ b/dist/changes-1.1.0
@@ -13,11 +13,9 @@ General
    * Completely reworked editor split mechanism.
 
 Editing
-   * Completion for constructors in variable initialization.
    * Some support for Obj-C++ //TODO: what does that mean more concrete?
    * Some support for doxygen style comments //TODO: what does that mean more concrete?
-   * More intelligent adding of braces.
-   * Improved function argument completion.
+   * Improved function argument hint.
    * More checkpoints in editor history.
    * Ctrl-click for jumping to a symbol definition.
    * Context help for form editor widgets.
@@ -40,12 +38,12 @@ Debugging
    * Make strategy to load shared objects configurable (auto-solib-add).
    * Maximum stack depth configurable.
    * Improved interaction in the Locals&Watchers view.
-   * Experimental cdb debugger.
 
 Wizards
    * It is now possible to choose file suffixes in the options dialog.
    * Code of language change event is now generated correctly (added call
      to base class).
+   * Generated header guards now adapt to file extension.
 
 Designer
    * Added signal/slot editor.
diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp
index 64f6bc1e012532105259f4f39852acb5aa698af8..f5a0edd66bc9c780cdf285e76e81a9c69dbc0e18 100644
--- a/src/libs/cplusplus/LookupContext.cpp
+++ b/src/libs/cplusplus/LookupContext.cpp
@@ -223,14 +223,13 @@ QList<Symbol *> LookupContext::resolve(Name *name, const QList<Scope *> &visible
                         continue;
 
                     if (q->nameCount() > 1) {
-                        Name *classOrNamespaceName = 0;
-
-                        if (q->nameCount() == 1)
-                            classOrNamespaceName = q->nameAt(0);
-                        else
-                            classOrNamespaceName = control()->qualifiedNameId(q->names(),
-                                                                              q->nameCount() - 1);
+                        Name *classOrNamespaceName = control()->qualifiedNameId(q->names(),
+                                                                                q->nameCount() - 1);
 
+                        if (Identifier *classOrNamespaceNameId = identifier(classOrNamespaceName)) {
+                            if (classOrNamespaceNameId->isEqualTo(id))
+                                continue;
+                        }
 
                         const QList<Symbol *> resolvedClassOrNamespace =
                                 resolveClassOrNamespace(classOrNamespaceName, visibleScopes);
@@ -455,7 +454,7 @@ void LookupContext::expandFunction(Scope *scope,
         expandedScopes->append(function->arguments());
     if (QualifiedNameId *q = function->name()->asQualifiedNameId()) {
         Name *nestedNameSpec = 0;
-        if (q->nameCount() == 1 && q->isGlobal())
+        if (q->nameCount() == 1)
             nestedNameSpec = q->nameAt(0);
         else
             nestedNameSpec = control()->qualifiedNameId(q->names(), q->nameCount() - 1,
diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp
index 8e79b50f6aa381e27dbda7c185948998394129ad..48542bad97faee523f63ed78eb6a45708268e7ac 100644
--- a/src/plugins/coreplugin/editormanager/editormanager.cpp
+++ b/src/plugins/coreplugin/editormanager/editormanager.cpp
@@ -1336,13 +1336,16 @@ void EditorManager::updateActions()
     m_d->m_revertToSavedAction->setEnabled(curEditor != 0
         && !curEditor->file()->fileName().isEmpty() && curEditor->file()->isModified());
 
-    m_d->m_saveAsAction->setText(tr("Save %1 As...").arg(fName));
-    m_d->m_saveAction->setText(tr("&Save %1").arg(fName));
-    m_d->m_revertToSavedAction->setText(tr("Revert %1 to Saved").arg(fName));
+    QString quotedName;
+    if (!fName.isEmpty())
+        quotedName = '"' + fName + '"';
+    m_d->m_saveAsAction->setText(tr("Save %1 As...").arg(quotedName));
+    m_d->m_saveAction->setText(tr("&Save %1").arg(quotedName));
+    m_d->m_revertToSavedAction->setText(tr("Revert %1 to Saved").arg(quotedName));
 
 
     m_d->m_closeCurrentEditorAction->setEnabled(curEditor != 0);
-    m_d->m_closeCurrentEditorAction->setText(tr("Close %1").arg(fName));
+    m_d->m_closeCurrentEditorAction->setText(tr("Close %1").arg(quotedName));
     m_d->m_closeAllEditorsAction->setEnabled(openedCount > 0);
 
     m_d->m_gotoNextDocHistoryAction->setEnabled(m_d->m_editorHistory.count() > 0);
diff --git a/src/plugins/coreplugin/editormanager/editorview.cpp b/src/plugins/coreplugin/editormanager/editorview.cpp
index 92ed402dcbc4743f9e30bba1a1058ab24029e546..930a20c2dfd4291cd85b6b969a9c1b129dc3091d 100644
--- a/src/plugins/coreplugin/editormanager/editorview.cpp
+++ b/src/plugins/coreplugin/editormanager/editorview.cpp
@@ -419,11 +419,11 @@ EditorView::EditorView(EditorModel *model, QWidget *parent) :
         m_statusWidgetButton->setText(tr("Placeholder"));
         hbox->addWidget(m_statusWidgetButton);
 
+        m_statusHLine->setVisible(false);
         m_statusWidget->setVisible(false);
         tl->addWidget(m_statusHLine);
         tl->addWidget(m_statusWidget);
     }
-
 }
 
 EditorView::~EditorView()
diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp
index 1593b6118c2eda68fd402b269f7df27dd0da9a5a..a6fbcfc03044ecfe0d5652f591fa01aee777087f 100644
--- a/src/plugins/cppeditor/cppeditor.cpp
+++ b/src/plugins/cppeditor/cppeditor.cpp
@@ -602,22 +602,6 @@ CPPEditor::Link CPPEditor::findLinkAt(const QTextCursor &cursor,
     if (!doc)
         return link;
 
-    // Handle include directives
-    const unsigned lineno = cursor.blockNumber() + 1;
-    foreach (const Document::Include &incl, doc->includes()) {
-        if (incl.line() == lineno && incl.resolved()) {
-            link.fileName = incl.fileName();
-            link.pos = cursor.block().position();
-            link.length = cursor.block().length();
-            return link;
-        }
-    }
-
-    // Find the last symbol up to the cursor position
-    Symbol *lastSymbol = doc->findSymbolAt(line, column);
-    if (!lastSymbol)
-        return link;
-
     QTextCursor tc = cursor;
 
     static TokenUnderCursor tokenUnderCursor;
@@ -625,14 +609,27 @@ CPPEditor::Link CPPEditor::findLinkAt(const QTextCursor &cursor,
     QTextBlock block;
     const SimpleToken tk = tokenUnderCursor(tc, &block);
 
-    if (tk.isLiteral() || tk.isComment()) {
-        // Drop out if we're at a number, string or comment
-        return link;
+    // Handle include directives
+    if (tk.is(T_STRING_LITERAL) || tk.is(T_ANGLE_STRING_LITERAL)) {
+        const unsigned lineno = cursor.blockNumber() + 1;
+        foreach (const Document::Include &incl, doc->includes()) {
+            if (incl.line() == lineno && incl.resolved()) {
+                link.fileName = incl.fileName();
+                link.pos = cursor.block().position() + tk.position() + 1;
+                link.length = tk.length() - 2;
+                return link;
+            }
+        }
     }
 
     if (tk.isNot(T_IDENTIFIER))
         return link;
 
+    // Find the last symbol up to the cursor position
+    Symbol *lastSymbol = doc->findSymbolAt(line, column);
+    if (!lastSymbol)
+        return link;
+
     const int nameStart = tk.position();
     const int nameLength = tk.length();
     const int endOfName = nameStart + nameLength;
@@ -668,7 +665,7 @@ CPPEditor::Link CPPEditor::findLinkAt(const QTextCursor &cursor,
                 def = findDefinition(symbol);
 
             link = linkToSymbol(def ? def : symbol);
-            link.pos = nameStart;
+            link.pos = block.position() + nameStart;
             link.length = nameLength;
             return link;
 
diff --git a/src/plugins/cpptools/cppcodecompletion.cpp b/src/plugins/cpptools/cppcodecompletion.cpp
index 9a9dd71ec3cbcf49652f243a47acf90398f7ffdc..981c48f01c8cb990af7e877cf30892902bb57f36 100644
--- a/src/plugins/cpptools/cppcodecompletion.cpp
+++ b/src/plugins/cpptools/cppcodecompletion.cpp
@@ -383,9 +383,9 @@ void FunctionArgumentWidget::updateHintText()
 
     const QDesktopWidget *desktop = QApplication::desktop();
 #ifdef Q_OS_MAC
-    const QRect screen = desktop->availableGeometry(desktop->screenNumber(m_popupFrame));
+    const QRect screen = desktop->availableGeometry(desktop->screenNumber(m_editor->widget()));
 #else
-    const QRect screen = desktop->screenGeometry(desktop->screenNumber(m_popupFrame));
+    const QRect screen = desktop->screenGeometry(desktop->screenNumber(m_editor->widget()));
 #endif
 
     const QSize sz = m_popupFrame->sizeHint();
diff --git a/src/plugins/debugger/debuggeractions.cpp b/src/plugins/debugger/debuggeractions.cpp
index 95f9c3b1104213ec36739c3b68d3de30d142595e..fc963d0798f25e5bc64c48ea03db538c27417f2e 100644
--- a/src/plugins/debugger/debuggeractions.cpp
+++ b/src/plugins/debugger/debuggeractions.cpp
@@ -314,6 +314,10 @@ DebuggerSettings *theDebuggerSettings()
     item->setDefaultValue(20);
     instance->insertItem(MaximalStackDepth, item);
 
+    item = new SavedAction(instance);
+    item->setText(QObject::tr("Reload full stack"));
+    instance->insertItem(ExpandStack, item);
+
     item = new SavedAction(instance);
     item->setText(QObject::tr("Execute line"));
     instance->insertItem(ExecuteCommand, item);
diff --git a/src/plugins/debugger/debuggeractions.h b/src/plugins/debugger/debuggeractions.h
index 31e04199f534c7195af11e9cd560bbc54ae27f55..cb51e551aa0315ad23dc7fad4dc7df606691d2d4 100644
--- a/src/plugins/debugger/debuggeractions.h
+++ b/src/plugins/debugger/debuggeractions.h
@@ -79,6 +79,7 @@ enum DebuggerActionCode
 
     // Stack
     MaximalStackDepth,
+    ExpandStack,
 
     // Watchers & Locals
     WatchExpression,
diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp
index ea973c0c69221db16942c8b0d6e5a65d7d6669e1..4b7ac701bf73b8077d60dc9e2717201de9f0d54f 100644
--- a/src/plugins/debugger/debuggermanager.cpp
+++ b/src/plugins/debugger/debuggermanager.cpp
@@ -148,8 +148,7 @@ extern IDebuggerEngine *createWinEngine(DebuggerManager *)
 #endif
 extern IDebuggerEngine *createScriptEngine(DebuggerManager *parent);
 
-DebuggerManager::DebuggerManager() :
-    m_attachCoreAction(0)
+DebuggerManager::DebuggerManager()
 {
     init();
 }
@@ -294,11 +293,9 @@ void DebuggerManager::init()
     m_attachExternalAction = new QAction(this);
     m_attachExternalAction->setText(tr("Attach to Running External Application..."));
 
-#ifndef Q_OS_WIN
     m_attachCoreAction = new QAction(this);
     m_attachCoreAction->setText(tr("Attach to Core..."));
     connect(m_attachCoreAction, SIGNAL(triggered()), this, SLOT(attachCore()));
-#endif
 
     m_continueAction = new QAction(this);
     m_continueAction->setText(tr("Continue"));
@@ -1172,7 +1169,7 @@ void DebuggerManager::setStatus(int status)
     if (status == m_status)
         return;
 
-    if (!isAllowedTransition(m_status, status)) {
+    if (0 && !isAllowedTransition(m_status, status)) {
         const QString msg = QString::fromLatin1("%1: UNEXPECTED TRANSITION: %2 -> %3").
                             arg(QLatin1String(Q_FUNC_INFO), QLatin1String(stateName(m_status)), QLatin1String(stateName(status)));
         qWarning("%s", qPrintable(msg));
@@ -1193,8 +1190,11 @@ void DebuggerManager::setStatus(int status)
 
     m_startExternalAction->setEnabled(!started && !starting);
     m_attachExternalAction->setEnabled(!started && !starting);
-    if (m_attachCoreAction)
-        m_attachCoreAction->setEnabled(!started && !starting);
+#ifdef Q_OS_WIN
+    m_attachCoreAction->setEnabled(false);
+#else
+    m_attachCoreAction->setEnabled(!started && !starting);
+#endif
     m_watchAction->setEnabled(ready);
     m_breakAction->setEnabled(true);
 
@@ -1372,7 +1372,7 @@ void DebuggerManager::disassemblerDockToggled(bool on)
 
 //////////////////////////////////////////////////////////////////////
 //
-// Sourec files specific stuff
+// Source files specific stuff
 //
 //////////////////////////////////////////////////////////////////////
 
@@ -1449,4 +1449,19 @@ void DebuggerManager::reloadRegisters()
 }
 
 
+//////////////////////////////////////////////////////////////////////
+//
+// Testing
+//
+//////////////////////////////////////////////////////////////////////
+
+void DebuggerManager::runTest(const QString &fileName)
+{
+    m_executable = fileName;
+    m_processArgs = QStringList() << "--run-debuggee";
+    m_workingDir = QString();
+    if (!startNewDebugger(StartInternal))
+        emit debuggingFinished();
+}
+
 #include "debuggermanager.moc"
diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h
index 77150b452b2822aaa1bc1bd9b6a24536b696c544..72c1467c52efe4243c46dc8f40bc0bbe018f23dc 100644
--- a/src/plugins/debugger/debuggermanager.h
+++ b/src/plugins/debugger/debuggermanager.h
@@ -341,6 +341,7 @@ public:
 private:
     void init();
     void setDebuggerType(DebuggerType type);
+    void runTest(const QString &fileName);
     QDockWidget *createDockForWidget(QWidget *widget);
     Q_SLOT void createNewDock(QWidget *widget);
 
diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp
index fbe80e4588216fd69cd53c8095a14e77b47d97a2..29a1b19ab8b0fd69a05b59a4979ae1fc4c22b6e6 100644
--- a/src/plugins/debugger/debuggerplugin.cpp
+++ b/src/plugins/debugger/debuggerplugin.cpp
@@ -796,6 +796,11 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess
 
 void DebuggerPlugin::extensionsInitialized()
 {
+    // time gdb -i mi -ex 'debuggerplugin.cpp:800' -ex r -ex q bin/qtcreator.bin
+    QByteArray env = qgetenv("QTC_DEBUGGER_TEST");
+    //qDebug() << "EXTENSIONS INITIALIZED:" << env;
+    if (!env.isEmpty())
+        m_manager->runTest(QString::fromLocal8Bit(env));
 }
 
 /*! Activates the previous mode when the current mode is the debug mode. */
diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp
index f1fea3104eb3075b79871d6b331e85ec8490a8c6..2a82bbda4cf315a0e2bd7b558a50138daf3a7055 100644
--- a/src/plugins/debugger/gdbengine.cpp
+++ b/src/plugins/debugger/gdbengine.cpp
@@ -230,6 +230,9 @@ void GdbEngine::initializeConnections()
         this, SLOT(reloadRegisters()));
     connect(theDebuggerAction(FormatNatural), SIGNAL(triggered()),
         this, SLOT(reloadRegisters()));
+
+    connect(theDebuggerAction(ExpandStack), SIGNAL(triggered()),
+        this, SLOT(reloadFullStack()));
 }
 
 void GdbEngine::initializeVariables()
@@ -373,16 +376,18 @@ void GdbEngine::handleResponse(const QByteArray &buff)
 
             GdbMi record;
             while (from != to) {
-                if (*from != ',') {
-                    qDebug() << "MALFORMED ASYNC OUTPUT" << from;
-                    return;
-                }
-                ++from; // skip ','
                 GdbMi data;
-                data.parseResultOrValue(from, to);
-                if (data.isValid()) {
-                    //qDebug() << "parsed response: " << data.toString();
-                    record.m_children += data;
+                if (*from == ',') {
+                    ++from; // skip ','
+                    data.parseResultOrValue(from, to);
+                    if (data.isValid()) {
+                        //qDebug() << "parsed response: " << data.toString();
+                        record.m_children += data;
+                        record.m_type = GdbMi::Tuple;
+                    }
+                } else {
+                    // happens on archer where we get 
+                    // 23^running <NL> *running,thread-id="all" <NL> (gdb) 
                     record.m_type = GdbMi::Tuple;
                 }
             }
@@ -395,6 +400,10 @@ void GdbEngine::handleResponse(const QByteArray &buff)
                 // target-name="/usr/lib/libdrm.so.2",
                 // host-name="/usr/lib/libdrm.so.2",
                 // symbols-loaded="0"
+            } else if (asyncClass == "library-unloaded") {
+                // Archer has 'id="/usr/lib/libdrm.so.2",
+                // target-name="/usr/lib/libdrm.so.2",
+                // host-name="/usr/lib/libdrm.so.2"
             } else if (asyncClass == "thread-group-created") {
                 // Archer has "{id="28902"}" 
             } else if (asyncClass == "thread-created") {
@@ -403,6 +412,8 @@ void GdbEngine::handleResponse(const QByteArray &buff)
                 // Archer has "{id="28902"}" 
             } else if (asyncClass == "thread-exited") {
                 //"{id="1",group-id="28902"}" 
+            } else if (asyncClass == "thread-selected") {
+                //"{id="2"}" 
             #ifdef Q_OS_MAC
             } else if (asyncClass == "shlibs-updated") {
                 // MAC announces updated libs
@@ -473,14 +484,16 @@ void GdbEngine::handleResponse(const QByteArray &buff)
 
             from = inner;
             if (from != to) {
-                if (*from != ',') {
-                    qDebug() << "MALFORMED RESULT OUTPUT" << from;
-                    return;
+                if (*from == ',') {
+                    ++from;
+                    record.data.parseTuple_helper(from, to);
+                    record.data.m_type = GdbMi::Tuple;
+                    record.data.m_name = "data";
+                } else {
+                    // Archer has this
+                    record.data.m_type = GdbMi::Tuple;
+                    record.data.m_name = "data";
                 }
-                ++from;
-                record.data.parseTuple_helper(from, to);
-                record.data.m_type = GdbMi::Tuple;
-                record.data.m_name = "data";
             }
 
             //qDebug() << "\nLOG STREAM:" + m_pendingLogStreamOutput;
@@ -803,7 +816,7 @@ void GdbEngine::handleResult(const GdbResultRecord & record, int type,
             break;
 
         case StackListFrames:
-            handleStackListFrames(record);
+            handleStackListFrames(record, cookie.toBool());
             break;
         case StackListThreads:
             handleStackListThreads(record, cookie.toInt());
@@ -1301,12 +1314,18 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
 #endif
 }
 
+void GdbEngine::reloadFullStack()
+{
+    QString cmd = "-stack-list-frames";
+    sendSynchronizedCommand(cmd, StackListFrames, true);
+}
+
 void GdbEngine::reloadStack()
 {
     QString cmd = "-stack-list-frames";
     if (int stackDepth = theDebuggerAction(MaximalStackDepth)->value().toInt())
         cmd += " 0 " + QString::number(stackDepth);
-    sendSynchronizedCommand(cmd, StackListFrames);
+    sendSynchronizedCommand(cmd, StackListFrames, false);
 }
 
 void GdbEngine::handleAsyncOutput2(const GdbMi &data)
@@ -2450,7 +2469,7 @@ void GdbEngine::handleStackSelectThread(const GdbResultRecord &record, int)
 }
 
 
-void GdbEngine::handleStackListFrames(const GdbResultRecord &record)
+void GdbEngine::handleStackListFrames(const GdbResultRecord &record, bool isFull)
 {
     QList<StackFrame> stackFrames;
 
@@ -2501,30 +2520,11 @@ void GdbEngine::handleStackListFrames(const GdbResultRecord &record)
             topFrame = i;
     }
 
-    if (n >= theDebuggerAction(MaximalStackDepth)->value().toInt()) {
-        StackFrame frame(n);
-        frame.file = "...";
-        frame.function = "...";
-        frame.from = "...";
-        frame.line = 0;
-        frame.address = "...";
-        stackFrames.append(frame);
-    }
-
-    qq->stackHandler()->setFrames(stackFrames);
+    bool canExpand = !isFull 
+        && (n >= theDebuggerAction(MaximalStackDepth)->value().toInt());
+    theDebuggerAction(ExpandStack)->setEnabled(canExpand);
+    qq->stackHandler()->setFrames(stackFrames, canExpand);
 
-#if 0
-    if (0 && topFrame != -1) {
-        // updates of locals already triggered early
-        const StackFrame &frame = qq->stackHandler()->currentFrame();
-        if (frame.isUsable())
-            q->gotoLocation(frame.file, frame.line, true);
-        else
-            qDebug() << "FULL NAME NOT USABLE 0: " << frame.file;
-    } else {
-        activateFrame(topFrame);
-    }
-#else
     if (topFrame != -1) {
         // updates of locals already triggered early
         const StackFrame &frame = qq->stackHandler()->currentFrame();
@@ -2533,7 +2533,6 @@ void GdbEngine::handleStackListFrames(const GdbResultRecord &record)
         else
             qDebug() << "FULL NAME NOT USABLE 0: " << frame.file << topFrame;
     }
-#endif
 }
 
 void GdbEngine::selectThread(int index)
@@ -2562,6 +2561,10 @@ void GdbEngine::activateFrame(int frameIndex)
     //qDebug() << "ACTIVATE FRAME: " << frameIndex << oldIndex
     //    << stackHandler->currentIndex();
 
+    if (frameIndex == stackHandler->stackSize()) {
+        reloadFullStack();
+        return;
+    }
     QTC_ASSERT(frameIndex < stackHandler->stackSize(), return);
 
     if (oldIndex != frameIndex) {
diff --git a/src/plugins/debugger/gdbengine.h b/src/plugins/debugger/gdbengine.h
index 0ea15012e982dfca77c71a00fbf939d594130bcc..79d95f34fcabf90c7fda1160d89a63409f56613f 100644
--- a/src/plugins/debugger/gdbengine.h
+++ b/src/plugins/debugger/gdbengine.h
@@ -277,10 +277,11 @@ private:
     //
     // Stack specific stuff
     // 
-    void handleStackListFrames(const GdbResultRecord &record);
+    void handleStackListFrames(const GdbResultRecord &record, bool isFull);
     void handleStackSelectThread(const GdbResultRecord &record, int cookie);
     void handleStackListThreads(const GdbResultRecord &record, int cookie);
-    void reloadStack();
+    Q_SLOT void reloadStack();
+    Q_SLOT void reloadFullStack();
 
 
     //
diff --git a/src/plugins/debugger/gdbmi.cpp b/src/plugins/debugger/gdbmi.cpp
index 2e778cb8e83c9b6965f56ccc7c81d6a0cf65def8..82fdaf4fd13487684dd92c9de56e55de12008a26 100644
--- a/src/plugins/debugger/gdbmi.cpp
+++ b/src/plugins/debugger/gdbmi.cpp
@@ -115,18 +115,18 @@ void GdbMi::parseValue(const char *&from, const char *to)
 {
     //qDebug() << "parseValue: " << QByteArray::fromUtf16(from, to - from);
     switch (*from) {
-    case '{':
-        parseTuple(from, to);
-        break;
-    case '[':
-        parseList(from, to);
-        break;
-    case '"':
-        m_type = Const;
-        m_data = parseCString(from, to);
-        break;
-    default:
-        break;
+        case '{':
+            parseTuple(from, to);
+            break;
+        case '[':
+            parseList(from, to);
+            break;
+        case '"':
+            m_type = Const;
+            m_data = parseCString(from, to);
+            break;
+        default:
+            break;
     }
 }
 
@@ -211,52 +211,53 @@ void GdbMi::dumpChildren(QByteArray * str, bool multiline, int indent) const
     }
 }
 
+static QByteArray escaped(QByteArray ba)
+{
+    ba.replace("\"", "\\\"");
+    return ba;
+}
+
 QByteArray GdbMi::toString(bool multiline, int indent) const
 {
     QByteArray result;
     switch (m_type) {
-    case Invalid:
-        if (multiline) {
-            result += ind(indent) + "Invalid\n";
-        } else {
-        result += "Invalid";
-        }
-        break;
-    case Const:
-        if (!m_name.isEmpty())
-            result += m_name + "=";
-        if (multiline) {
-        result += "\"" + m_data + "\"";
-        } else {
-            result += "\"" + m_data + "\"";
-        }
-        break;
-    case Tuple:
-        if (!m_name.isEmpty())
-            result += m_name + "=";
-        if (multiline) {
-            result += "{\n";
-            dumpChildren(&result, multiline, indent + 1);
-            result += '\n' + ind(indent) + "}";
-        } else {
-        result += "{";
-            dumpChildren(&result, multiline, indent + 1);
-        result += "}";
-        }
-        break;
-    case List:
-        if (!m_name.isEmpty())
-            result += m_name + "=";
-        if (multiline) {
-            result += "[\n";
-            dumpChildren(&result, multiline, indent + 1);
-            result += "]";
-        } else {
-            result += "[";
-            dumpChildren(&result, multiline, indent + 1);
-            result += '\n' + ind(indent) + "]";
-        }
-        break;
+        case Invalid:
+            if (multiline)
+                result += ind(indent) + "Invalid\n";
+            else
+                result += "Invalid";
+            break;
+        case Const: 
+            if (!m_name.isEmpty())
+                result += m_name + "=";
+            result += "\"" + escaped(m_data) + "\"";
+            break;
+        case Tuple:
+            if (!m_name.isEmpty())
+                result += m_name + "=";
+            if (multiline) {
+                result += "{\n";
+                dumpChildren(&result, multiline, indent + 1);
+                result += '\n' + ind(indent) + "}";
+            } else {
+                result += "{";
+                dumpChildren(&result, multiline, indent + 1);
+                result += "}";
+            }
+            break;
+        case List:
+            if (!m_name.isEmpty())
+                result += m_name + "=";
+            if (multiline) {
+                result += "[\n";
+                dumpChildren(&result, multiline, indent + 1);
+                result += '\n' + ind(indent) + "]";
+            } else {
+                result += "[";
+                dumpChildren(&result, multiline, indent + 1);
+                result += "]";
+            }
+            break;
     }
     return result;
 }
@@ -319,152 +320,5 @@ QByteArray GdbResultRecord::toString() const
     return result;
 }
 
-
-//////////////////////////////////////////////////////////////////////////////////
-//
-// GdbStreamOutput
-//
-//////////////////////////////////////////////////////////////////////////////////
-
-#if 0
-
-static const char test1[] =
-    "1^done,stack=[frame={level=\"0\",addr=\"0x00000000004061ca\","
-    "func=\"main\",file=\"test1.cpp\","
-    "fullname=\"/home/apoenitz/work/test1/test1.cpp\",line=\"209\"}]\n"
-    "(gdb)\n";
-
-static const char test2[] =
-    "2^done,stack=[frame={level=\"0\",addr=\"0x00002ac058675840\","
-    "func=\"QApplication\",file=\"/home/apoenitz/dev/qt/src/gui/kernel/qapplication.cpp\","
-    "fullname=\"/home/apoenitz/dev/qt/src/gui/kernel/qapplication.cpp\",line=\"592\"},"
-    "frame={level=\"1\",addr=\"0x00000000004061e0\",func=\"main\",file=\"test1.cpp\","
-    "fullname=\"/home/apoenitz/work/test1/test1.cpp\",line=\"209\"}]\n"
-    "(gdb)\n";
-
-static const char test3[] =
-    "3^done,stack=[frame={level=\"0\",addr=\"0x00000000004061ca\","
-    "func=\"main\",file=\"test1.cpp\","
-    "fullname=\"/home/apoenitz/work/test1/test1.cpp\",line=\"209\"}]\n"
-    "(gdb)\n";
-
-static const char test4[] =
-    "&\"source /home/apoenitz/dev/ide/main/bin/gdb/qt4macros\\n\"\n"
-    "4^done\n"
-    "(gdb)\n";
-
-
-static const char test5[] =
-    "1*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"1\","
-    "frame={addr=\"0x0000000000405738\",func=\"main\","
-    "args=[{name=\"argc\",value=\"1\"},{name=\"argv\",value=\"0x7fff1ac78f28\"}],"
-    "file=\"test1.cpp\",fullname=\"/home/apoenitz/work/test1/test1.cpp\","
-    "line=\"209\"}\n"
-    "(gdb)\n";
-
-static const char test6[] =
-    "{u = {u = 2048, v = 16788279, w = -689265400}, a = 1, b = -689265424, c = 11063, s = {static null = {<No data fields>}, static shared_null = {ref = {value = 2}, alloc = 0, size = 0, data = 0x6098da, clean = 0, simpletext = 0, righttoleft = 0, asciiCache = 0, capacity = 0, reserved = 0, array = {0}}, static shared_empty = {ref = {value = 1}, alloc = 0, size = 0, data = 0x2b37d84f8fba, clean = 0, simpletext = 0, righttoleft = 0, asciiCache = 0, capacity = 0, reserved = 0, array = {0}}, d = 0x6098c0, static codecForCStrings = 0x0}}";
-
-static const char test8[] =
-    "8^done,data={locals={{name=\"a\"},{name=\"w\"}}}\n"
-    "(gdb)\n";
-
-static const char test9[] =
-    "9^done,data={locals=[name=\"baz\",name=\"urgs\",name=\"purgs\"]}\n"
-    "(gdb)\n";
-
-
-static const char test10[] =
-    "16^done,name=\"urgs\",numchild=\"1\",type=\"Urgs\"\n"
-    "(gdb)\n"
-    "17^done,name=\"purgs\",numchild=\"1\",type=\"Urgs *\"\n"
-    "(gdb)\n"
-    "18^done,name=\"bar\",numchild=\"0\",type=\"int\"\n"
-    "(gdb)\n"
-    "19^done,name=\"z\",numchild=\"0\",type=\"int\"\n"
-    "(gdb)\n";
-
-static const char test11[] =
-    "[{name=\"size\",value=\"1\",type=\"size_t\",readonly=\"true\"},"
-     "{name=\"0\",value=\"one\",type=\"QByteArray\"}]";
-
-static const char test12[] =
-    "{iname=\"local.hallo\",value=\"\\\"\\\"\",type=\"QByteArray\",numchild=\"0\"}";
-
-static struct Tester {
-
-    Tester() {
-        //test(test10);
-        test2(test12);
-        //test(test4);
-        //apple();
-        exit(0);
-    }
-
-    void test(const char* input)
-    {
-        //qDebug("\n<<<<\n%s\n====\n%s\n>>>>\n", input,
-           //qPrintable(GdbResponse(input).toString()));
-    }
-
-    void test2(const char* input)
-    {
-        GdbMi mi(input);
-        qDebug("\n<<<<\n%s\n====\n%s\n>>>>\n", input,
-            qPrintable(mi.toString()));
-    }
-
-    void apple()
-    {
-        QByteArray input(test9);
-/*
-        qDebug() << "input: " << input;
-        input = input.replace("{{","[");
-        input = input.replace("},{",",");
-        input = input.replace("}}","]");
-        qDebug() << "input: " << input;
-        GdbResponse response(input);
-        qDebug() << "read: " << response.toString();
-        GdbMi list = response.results[0].data.findChild("data").findChild("locals");
-        QByteArrayList locals;
-        foreach (const GdbMi &item, list.children())
-            locals.append(item.string());
-        qDebug() << "Locals (new): " << locals;
-*/
-    }
-    void parse(const QByteArray &str)
-    {
-        QByteArray result;
-        result += "\n ";
-        int indent = 0;
-        int from = 0;
-        int to = str.size();
-        if (str.size() && str[0] == '{' /*'}'*/) {
-            ++from;
-            --to;
-        }
-        for (int i = from; i < to; ++i) {
-            if (str[i] == '{')
-                result += "{\n" + QByteArray(2*++indent + 1, ' ');
-            else if (str[i] == '}') {
-                if (!result.isEmpty() && result[result.size() - 1] != '\n')
-                    result += "\n";
-                result += QByteArray(2*--indent + 1, ' ') + "}\n";
-            }
-            else if (str[i] == ',') {
-                if (true || !result.isEmpty() && result[result.size() - 1] != '\n')
-                    result += "\n";
-                result += QByteArray(2*indent, ' ');
-            }
-            else
-                result += str[i];
-        }
-        qDebug() << "result:\n" << result;
-    }
-
-} dummy;
-
-#endif
-
 } // namespace Internal
 } // namespace Debugger
diff --git a/src/plugins/debugger/stackhandler.cpp b/src/plugins/debugger/stackhandler.cpp
index 17c8168c7c3c3f156053f69ffc42af2d4a969da2..d8beb63a3e66631f04f50e81e2dfe3d0ee7f0c3d 100644
--- a/src/plugins/debugger/stackhandler.cpp
+++ b/src/plugins/debugger/stackhandler.cpp
@@ -57,12 +57,13 @@ StackHandler::StackHandler(QObject *parent)
 {
     m_emptyIcon = QIcon(":/gdbdebugger/images/empty.svg");
     m_positionIcon = QIcon(":/gdbdebugger/images/location.svg");
+    m_canExpand = false;
 }
 
 int StackHandler::rowCount(const QModelIndex &parent) const
 {
     // Since the stack is not a tree, row count is 0 for any valid parent
-    return parent.isValid() ? 0 : m_stackFrames.size();
+    return parent.isValid() ? 0 : (m_stackFrames.size() + m_canExpand);
 }
 
 int StackHandler::columnCount(const QModelIndex &parent) const
@@ -72,9 +73,15 @@ int StackHandler::columnCount(const QModelIndex &parent) const
 
 QVariant StackHandler::data(const QModelIndex &index, int role) const
 {
-    if (!index.isValid() || index.row() >= m_stackFrames.size())
+    if (!index.isValid() || index.row() >= m_stackFrames.size() + m_canExpand)
         return QVariant();
 
+    if (index.row() == m_stackFrames.size()) {
+        if (role == Qt::DisplayRole && index.column() == 0) 
+            return "<...>";
+        return QVariant();
+    }
+
     const StackFrame &frame = m_stackFrames.at(index.row());
 
     if (role == Qt::DisplayRole) {
@@ -123,10 +130,12 @@ QVariant StackHandler::headerData(int section, Qt::Orientation orientation, int
 
 Qt::ItemFlags StackHandler::flags(const QModelIndex &index) const
 {
-    if (index.row() >= m_stackFrames.size())
+    if (index.row() >= m_stackFrames.size() + m_canExpand)
         return 0;
+    if (index.row() == m_stackFrames.size())
+        return QAbstractTableModel::flags(index);
     const StackFrame &frame = m_stackFrames.at(index.row());
-    const bool isValid = !frame.file.isEmpty() && !frame.function.isEmpty();
+    const bool isValid = (!frame.file.isEmpty() && !frame.function.isEmpty());
     return isValid ? QAbstractTableModel::flags(index) : Qt::ItemFlags(0);
 }
 
@@ -160,8 +169,9 @@ void StackHandler::removeAll()
     reset();
 }
 
-void StackHandler::setFrames(const QList<StackFrame> &frames)
+void StackHandler::setFrames(const QList<StackFrame> &frames, bool canExpand)
 {
+    m_canExpand = canExpand;
     m_stackFrames = frames;
     if (m_currentIndex >= m_stackFrames.size())
         m_currentIndex = m_stackFrames.size() - 1;
diff --git a/src/plugins/debugger/stackhandler.h b/src/plugins/debugger/stackhandler.h
index ae073e3d1369f74a42ba6eeb9b5df0580c545205..c928a6fed92913351031f1e9072ecf65a8a6639d 100644
--- a/src/plugins/debugger/stackhandler.h
+++ b/src/plugins/debugger/stackhandler.h
@@ -64,7 +64,7 @@ class StackHandler : public QAbstractTableModel
 public:
     StackHandler(QObject *parent = 0);
 
-    void setFrames(const QList<StackFrame> &frames);
+    void setFrames(const QList<StackFrame> &frames, bool canExpand = false);
     QList<StackFrame> frames() const;
     void setCurrentIndex(int index);
     int currentIndex() const { return m_currentIndex; }
@@ -88,6 +88,7 @@ private:
     int m_currentIndex;
     QIcon m_positionIcon;
     QIcon m_emptyIcon;
+    bool m_canExpand;
 };
 
 
diff --git a/src/plugins/debugger/stackwindow.cpp b/src/plugins/debugger/stackwindow.cpp
index e0340ce0ae8e3908276a0a37c22b1228056c8e24..cac2a40bed9ce194a5728519008779b7459425a3 100644
--- a/src/plugins/debugger/stackwindow.cpp
+++ b/src/plugins/debugger/stackwindow.cpp
@@ -98,6 +98,7 @@ void StackWindow::contextMenuEvent(QContextMenuEvent *ev)
     act2->setCheckable(true);
     act2->setChecked(m_alwaysResizeColumnsToContents);
 
+    menu.addAction(theDebuggerAction(ExpandStack));
     menu.addAction(act0);
     menu.addSeparator();
     menu.addAction(act1);
diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp
index b2af8278d94ba1a6818ea2d3d1d007695d500fd7..76d27768e19acad7f750ae8f60095593e2f0fcc8 100644
--- a/src/plugins/debugger/watchhandler.cpp
+++ b/src/plugins/debugger/watchhandler.cpp
@@ -871,10 +871,11 @@ void WatchHandler::watchExpression(const QString &exp)
 {
     // FIXME: 'exp' can contain illegal characters
     //MODEL_DEBUG("WATCH: " << exp);
+    static int counter = 0;
     WatchData data;
     data.exp = exp;
     data.name = exp;
-    data.iname = QLatin1String("watch.") + exp;
+    data.iname = QLatin1String("watch.") + QString::number(counter++);
     insertData(data);
     m_watchers.append(exp);
     saveWatchers();
@@ -993,7 +994,6 @@ void WatchHandler::reinitializeWatchersHelper()
         data.variable.clear();
         data.setAllNeeded();
         data.valuedisabled = false;
-        data.iname = QLatin1String("watch.") + QString::number(i);
         data.name = exp;
         data.exp = exp;
         insertData(data);
diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp
index 96d02733017ec660867d87617c137ca4863d4b82..9a4339fd1922382eaf1c8a97e8b0fbb2e96a39a9 100644
--- a/src/plugins/fakevim/fakevimhandler.cpp
+++ b/src/plugins/fakevim/fakevimhandler.cpp
@@ -213,6 +213,7 @@ public:
 
     EventResult handleEvent(QKeyEvent *ev);
     bool wantsOverride(QKeyEvent *ev);
+    void handleCommand(const QString &cmd); // sets m_tc + handleExCommand
     void handleExCommand(const QString &cmd);
 
     void installEventFilter();
@@ -350,6 +351,7 @@ public:
     bool m_needMoreUndo;
 
     // extra data for '.'
+    void replay(const QString &text);
     QString m_dotCommand;
     bool m_inReplay; // true if we are executing a '.'
 
@@ -1007,11 +1009,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
         qDebug() << "REPEATING" << m_dotCommand;
         QString savedCommand = m_dotCommand;
         m_dotCommand.clear();
-        m_inReplay = true;
-        for (int i = count(); --i >= 0; )
-            foreach (QChar c, savedCommand)
-                handleKey(c.unicode(), c.unicode(), QString(c));
-        m_inReplay = false;
+        replay(savedCommand);
         enterCommandMode();
         m_dotCommand = savedCommand;
     } else if (key == '<' && m_visualMode == NoVisualMode) {
@@ -1643,6 +1641,13 @@ void FakeVimHandler::Private::selectRange(int beginLine, int endLine)
        setPosition(firstPositionInLine(endLine + 1));
 }
 
+void FakeVimHandler::Private::handleCommand(const QString &cmd)
+{
+    m_tc = EDITOR(textCursor());
+    handleExCommand(cmd);
+    EDITOR(setTextCursor(m_tc));
+}
+
 void FakeVimHandler::Private::handleExCommand(const QString &cmd0)
 {
     QString cmd = cmd0;
@@ -1665,10 +1670,11 @@ void FakeVimHandler::Private::handleExCommand(const QString &cmd0)
 
     //qDebug() << "RANGE: " << beginLine << endLine << cmd << cmd0 << m_marks;
 
-    static QRegExp reWrite("^w!?( (.*))?$");
     static QRegExp reDelete("^d( (.*))?$");
-    static QRegExp reSet("^set?( (.*))?$");
     static QRegExp reHistory("^his(tory)?( (.*))?$");
+    static QRegExp reNormal("^norm(al)?( (.*))?$");
+    static QRegExp reSet("^set?( (.*))?$");
+    static QRegExp reWrite("^w!?( (.*))?$");
 
     if (cmd.isEmpty()) {
         setPosition(firstPositionInLine(beginLine));
@@ -1769,6 +1775,9 @@ void FakeVimHandler::Private::handleExCommand(const QString &cmd0)
         redo();
         enterCommandMode();
         updateMiniBuffer();
+    } else if (reNormal.indexIn(cmd) != -1) { // :normal
+        enterCommandMode();
+        replay(reNormal.cap(3));
     } else if (reSet.indexIn(cmd) != -1) { // :set
         showBlackMessage(QString());
         QString arg = reSet.cap(2);
@@ -2341,6 +2350,15 @@ void FakeVimHandler::Private::handleStartOfLine()
         moveToFirstNonBlankOnLine();
 }
 
+void FakeVimHandler::Private::replay(const QString &command)
+{
+    //qDebug() << "REPLAY: " << command;
+    m_inReplay = true;
+    for (int i = count(); --i >= 0; )
+        foreach (QChar c, command)
+            handleKey(c.unicode(), c.unicode(), QString(c));
+    m_inReplay = false;
+}
 
 ///////////////////////////////////////////////////////////////////////
 //
@@ -2403,7 +2421,7 @@ void FakeVimHandler::restoreWidget()
 
 void FakeVimHandler::handleCommand(const QString &cmd)
 {
-    d->handleExCommand(cmd);
+    d->handleCommand(cmd);
 }
 
 void FakeVimHandler::setCurrentFileName(const QString &fileName)
diff --git a/src/plugins/qtscripteditor/qtscripteditor.cpp b/src/plugins/qtscripteditor/qtscripteditor.cpp
index 701f6005291e544900d8c3d4e84b032418d93d9c..16244140235b81ce336357f01bb943d1c5370f28 100644
--- a/src/plugins/qtscripteditor/qtscripteditor.cpp
+++ b/src/plugins/qtscripteditor/qtscripteditor.cpp
@@ -240,7 +240,7 @@ void ScriptEditor::updateDocumentNow()
     errorFormat.setUnderlineStyle(QTextCharFormat::WaveUnderline);
 
     QTextCharFormat warningFormat;
-    warningFormat.setUnderlineColor(Qt::yellow);
+    warningFormat.setUnderlineColor(Qt::darkYellow);
     warningFormat.setUnderlineStyle(QTextCharFormat::WaveUnderline);
 
     QTextEdit::ExtraSelection sel;
diff --git a/src/shared/proparser/profileevaluator.cpp b/src/shared/proparser/profileevaluator.cpp
index bbfeba7dd7e6039abfeb89ce8c2577ba5ba8fca9..19041d7bb77cb884663dfa89704630e98abb2d5e 100644
--- a/src/shared/proparser/profileevaluator.cpp
+++ b/src/shared/proparser/profileevaluator.cpp
@@ -224,15 +224,15 @@ public:
 ProFileEvaluator::Private::Private(ProFileEvaluator *q_)
   : q(q_)
 {
+    // Global parser state
     m_prevLineNo = 0;
     m_prevProFile = 0;
+
+    // Configuration, more or less
     m_verbose = true;
-    m_block = 0;
-    m_commentItem = 0;
-    m_syntaxError = 0;
-    m_lineNo = 0;
-    m_contNextLine = false;
     m_cumulative = true;
+
+    // Evaluator state
     m_updateCondition = false;
     m_condition = ConditionFalse;
     m_invertNext = false;
@@ -248,8 +248,13 @@ bool ProFileEvaluator::Private::read(ProFile *pro)
         return false;
     }
 
+    // Parser state
+    m_block = 0;
+    m_commentItem = 0;
+    m_contNextLine = false;
     m_syntaxError = false;
     m_lineNo = 1;
+    m_blockstack.clear();
     m_blockstack.push(pro);
 
     QTextStream ts(&file);
diff --git a/tests/auto/debugger/debugger.pro b/tests/auto/debugger/debugger.pro
new file mode 100644
index 0000000000000000000000000000000000000000..6f6e9357741412cf1f0c9dfd463a7097f3c6a72c
--- /dev/null
+++ b/tests/auto/debugger/debugger.pro
@@ -0,0 +1,12 @@
+
+QT = core testlib
+
+DEBUGGERDIR = ../../../src/plugins/debugger
+UTILSDIR = ../../../src/libs
+
+SOURCES += \
+    $$DEBUGGERDIR/gdbmi.cpp \
+    main.cpp \
+
+INCLUDEPATH += $$DEBUGGERDIR $$UTILSDIR
+
diff --git a/tests/auto/debugger/main.cpp b/tests/auto/debugger/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f59a54a6790c92e5b99ac94de0d93404559c0b92
--- /dev/null
+++ b/tests/auto/debugger/main.cpp
@@ -0,0 +1,153 @@
+
+#include "gdbmi.h"
+
+#include <QtCore/QObject>
+#include <QtCore/QProcess>
+#include <QtCore/QFileInfo>
+#include <QtTest/QtTest>
+//#include <QtTest/qtest_gui.h>
+
+using namespace Debugger;
+using namespace Debugger::Internal;
+
+static const char test1[] =
+    "[frame={level=\"0\",addr=\"0x00000000004061ca\","
+    "func=\"main\",file=\"test1.cpp\","
+    "fullname=\"/home/apoenitz/work/test1/test1.cpp\",line=\"209\"}]";
+
+static const char test2[] =
+    "[frame={level=\"0\",addr=\"0x00002ac058675840\","
+    "func=\"QApplication\",file=\"/home/apoenitz/dev/qt/src/gui/kernel/qapplication.cpp\","
+    "fullname=\"/home/apoenitz/dev/qt/src/gui/kernel/qapplication.cpp\",line=\"592\"},"
+    "frame={level=\"1\",addr=\"0x00000000004061e0\",func=\"main\",file=\"test1.cpp\","
+    "fullname=\"/home/apoenitz/work/test1/test1.cpp\",line=\"209\"}]";
+
+static const char test3[] =
+    "[stack={frame={level=\"0\",addr=\"0x00000000004061ca\","
+    "func=\"main\",file=\"test1.cpp\","
+    "fullname=\"/home/apoenitz/work/test1/test1.cpp\",line=\"209\"}}]";
+
+static const char test4[] =
+    "&\"source /home/apoenitz/dev/ide/main/bin/gdb/qt4macros\\n\""
+    "4^done\n";
+
+static const char test5[] =
+    "[reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"1\","
+    "frame={addr=\"0x0000000000405738\",func=\"main\","
+    "args=[{name=\"argc\",value=\"1\"},{name=\"argv\",value=\"0x7fff1ac78f28\"}],"
+    "file=\"test1.cpp\",fullname=\"/home/apoenitz/work/test1/test1.cpp\","
+    "line=\"209\"}]";
+
+static const char test8[] =
+    "[data={locals={{name=\"a\"},{name=\"w\"}}}]";
+
+static const char test9[] =
+    "[data={locals=[name=\"baz\",name=\"urgs\",name=\"purgs\"]}]";
+
+static const char test10[] =
+    "[name=\"urgs\",numchild=\"1\",type=\"Urgs\"]";
+
+static const char test11[] =
+    "[{name=\"size\",value=\"1\",type=\"size_t\",readonly=\"true\"},"
+     "{name=\"0\",value=\"one\",type=\"QByteArray\"}]";
+
+static const char test12[] =
+    "[{iname=\"local.hallo\",value=\"\\\"\\\"\",type=\"QByteArray\","
+     "numchild=\"0\"}]";
+
+class tst_Debugger : public QObject
+{
+    Q_OBJECT
+
+public:
+    tst_Debugger() {}
+
+    void testMi(const char* input)
+    {
+        QCOMPARE('\n' + QString::fromLatin1(GdbMi(input).toString(false)),
+            '\n' + QString(input));
+    }
+
+private slots:
+    void mi1()  { testMi(test1);  }
+    void mi2()  { testMi(test2);  }
+    void mi3()  { testMi(test3);  }
+    //void mi4()  { testMi(test4);  }
+    void mi5()  { testMi(test5);  }
+    void mi8()  { testMi(test8);  }
+    void mi9()  { testMi(test9);  }
+    void mi10() { testMi(test10); }
+    void mi11() { testMi(test11); }
+    void mi12() { testMi(test12); }
+    void runQtc();
+
+public slots:
+    void readStandardOutput();
+    void readStandardError();
+
+private:
+    QProcess m_proc; // the Qt Creator process
+};
+
+static QByteArray stripped(QByteArray ba)
+{
+    for (int i = ba.size(); --i >= 0; ) {
+        if (ba.at(i) == '\n' || ba.at(i) == ' ')
+            ba.chop(1);
+        else
+            break;
+    }
+    return ba;
+}
+
+void tst_Debugger::readStandardOutput()
+{
+    qDebug() << "qtcreator-out: " << stripped(m_proc.readAllStandardOutput());
+}
+
+void tst_Debugger::readStandardError()
+{
+    qDebug() << "qtcreator-err: " << stripped(m_proc.readAllStandardError());
+}
+
+void tst_Debugger::runQtc()
+{
+    QString test = QFileInfo(qApp->arguments().at(0)).absoluteFilePath();
+    QString qtc = QFileInfo(test).absolutePath() + "/../../../bin/qtcreator.bin";
+    qtc = QFileInfo(qtc).absoluteFilePath();
+    QStringList env = QProcess::systemEnvironment();
+    env.append("QTC_DEBUGGER_TEST=" + test);
+    m_proc.setEnvironment(env);
+    connect(&m_proc, SIGNAL(readyReadStandardOutput()),
+        this, SLOT(readStandardOutput()));
+    connect(&m_proc, SIGNAL(readyReadStandardError()),
+        this, SLOT(readStandardError()));
+    m_proc.start(qtc);
+    m_proc.waitForStarted();
+    QCOMPARE(m_proc.state(), QProcess::Running);
+    m_proc.waitForFinished();
+    QCOMPARE(m_proc.state(), QProcess::NotRunning);
+}
+
+void runDebuggee()
+{
+    qDebug() << "RUNNING DEBUGGEE";
+}
+
+int main(int argc, char *argv[])
+{
+    QCoreApplication app(argc, argv);
+    QStringList args = app.arguments();
+
+
+    if (args.size() == 2 && args.at(1) == "--run-debuggee") {
+        runDebuggee();
+        return 0;
+    }
+
+    tst_Debugger test;
+    return QTest::qExec(&test, argc, argv);
+}
+
+#include "main.moc"
+
diff --git a/tests/auto/fakevim/fakevim.pro b/tests/auto/fakevim/fakevim.pro
index 539a40f335c9e64b377e9fba993e7e8906094088..04fefc12d30548202540f2b9cf6dea67a3d89d80 100644
--- a/tests/auto/fakevim/fakevim.pro
+++ b/tests/auto/fakevim/fakevim.pro
@@ -1,14 +1,23 @@
 
 QT += testlib
 
-FAKEVIMSOURCE = ../../../src/plugins/fakevim
-
-INCLUDEPATH += $$FAKEVIMSOURCE
+FAKEVIMDIR = ../../../src/plugins/fakevim
+UTILSDIR = ../../../src/libs
 
 SOURCES += \
 	main.cpp \
-	$$FAKEVIMSOURCE/handler.cpp
+	$$FAKEVIMDIR/fakevimhandler.cpp \
+	$$FAKEVIMDIR/fakevimactions.cpp \
+	$$UTILSDIR/utils/savedaction.cpp \
+	$$UTILSDIR/utils/pathchooser.cpp \
+	$$UTILSDIR/utils/basevalidatinglineedit.cpp \
 
 HEADERS += \
-	$$FAKEVIMSOURCE/handler.h
+	$$FAKEVIMDIR/fakevimhandler.h \
+	$$FAKEVIMDIR/fakevimactions.h \
+	$$UTILSDIR/utils/savedaction.h \
+	$$UTILSDIR/utils/pathchooser.h \
+	$$UTILSDIR/utils/basevalidatinglineedit.h \
+
+INCLUDEPATH += $$FAKEVIMDIR $$UTILSDIR
 
diff --git a/tests/auto/fakevim/main.cpp b/tests/auto/fakevim/main.cpp
index 5445ba3f048621839f5dd9aaf1fb8acc144667ec..700b25d63db3ca76dc35a322466a5c8163a8e2ce 100644
--- a/tests/auto/fakevim/main.cpp
+++ b/tests/auto/fakevim/main.cpp
@@ -27,18 +27,167 @@
 **
 **************************************************************************/
 
-#include "handler.h"
+#include "fakevimhandler.h"
 
-#include <QtTest/QtTest>
 #include <QtCore/QSet>
+#include <QtGui/QPlainTextEdit>
+
+#include <QtTest/QtTest>
+
+using namespace FakeVim;
+using namespace FakeVim::Internal;
+
 
 class tst_FakeVim : public QObject
 {
     Q_OBJECT
 
+public:
+    tst_FakeVim();
+
+    void setup();    
+    void send(const QString &command); // send a normal command
+    void sendEx(const QString &command); // send an ex command
+
+    QString cleaned(QString wanted) { wanted.remove('$'); return wanted; }
+
+public slots:
+    void changeStatusData(const QString &info) { m_statusData = info; }
+    void changeStatusMessage(const QString &info) { m_statusMessage = info; }
+    void changeExtraInformation(const QString &info) { m_infoMessage = info; }
+    
+public:
+    QString m_statusMessage;
+    QString m_statusData;
+    QString m_infoMessage;
+
 private slots:
+    void commandI();
+    void commandDollar();
+
+private:
+    QPlainTextEdit m_editor;
+    FakeVimHandler m_handler;
+    QList<QTextEdit::ExtraSelection> m_selection;
+
+    static const QString lines;
+    static const QString escape;
 };
 
+const QString tst_FakeVim::lines = 
+    "\n"
+    "#include <QtCore>\n"
+    "#include <QtGui>\n"
+    "\n"
+    "int main(int argc, char *argv[])\n"
+    "{\n"
+    "    QApplication app(argc, argv);\n"
+    "\n"
+    "    return app.exec();\n"
+    "}\n";
+
+const QString tst_FakeVim::escape = QChar(27);
+
+tst_FakeVim::tst_FakeVim()
+    : m_handler(&m_editor, this)
+{
+
+    QObject::connect(&m_handler, SIGNAL(commandBufferChanged(QString)),
+        this, SLOT(changeStatusMessage(QString)));
+    QObject::connect(&m_handler, SIGNAL(extraInformationChanged(QString)),
+        this, SLOT(changeExtraInformation(QString)));
+    QObject::connect(&m_handler, SIGNAL(statusDataChanged(QString)),
+        this, SLOT(changeStatusData(QString)));
+}
+
+void tst_FakeVim::setup()
+{
+    m_statusMessage.clear();
+    m_statusData.clear();
+    m_infoMessage.clear();
+    m_editor.setPlainText(lines);
+    QCOMPARE(m_editor.toPlainText(), lines);
+}
+
+void tst_FakeVim::send(const QString &command)
+{
+    m_handler.handleCommand("normal " + command);
+}
+
+void tst_FakeVim::sendEx(const QString &command)
+{
+    m_handler.handleCommand(command);
+}
+
+#define checkContents(wanted) \
+    do { QString want = cleaned(wanted); \
+        QString got = m_editor.toPlainText(); \
+        QStringList wantlist = want.split('\n'); \
+        QStringList gotlist = got.split('\n'); \
+        QCOMPARE(gotlist.size(), wantlist.size()); \
+        for (int i = 0; i < wantlist.size() && i < gotlist.size(); ++i) { \
+           QString g = QString("line %1: %2").arg(i + 1).arg(gotlist.at(i)); \
+           QString w = QString("line %1: %2").arg(i + 1).arg(wantlist.at(i)); \
+           QCOMPARE(g, w); \
+        } \
+    } while (0)
+
+#define checkText(cmd, wanted) \
+    do { \
+        send(cmd); \
+        checkContents(wanted); \
+        int p = (wanted).indexOf('$'); \
+        QCOMPARE(m_editor.textCursor().position(), p); \
+    } while (0)
+
+#define checkTextEx(cmd, wanted) \
+    do { \
+        sendEx(cmd); \
+        checkContents(wanted); \
+        int p = (wanted).indexOf('$'); \
+        QCOMPARE(m_editor.textCursor().position(), p); \
+    } while (0)
+
+#define checkPosition(cmd, pos) \
+    do { \
+        send(cmd); \
+        QCOMPARE(m_editor.textCursor().position(), pos); \
+    } while (0)
+
+void tst_FakeVim::commandI()
+{
+    setup();
+
+    // empty insertion at start of document
+    checkText("i" + escape, "$" + lines);
+    checkText("u", "$" + lines);
+
+    // small insertion at start of document
+    checkText("ix" + escape, "$x" + lines);
+    checkText("u", "$" + lines);
+
+    // small insertion at start of document
+    checkText("ixxx" + escape, "xx$x" + lines);
+    checkText("u", "$" + lines);
+
+    // combine insertions
+    checkText("ia" + escape, "$a" + lines);
+    checkText("ibx" + escape, "b$xa" + lines);
+    checkText("icyy" + escape, "bcy$yxa" + lines);
+    checkText("u", "b$xa" + lines);
+    checkText("u", "$a" + lines);   // undo broken
+    checkTextEx("redo", "b$xa" + lines);
+    checkText("u", "$a" + lines);
+    checkText("u", "$" + lines);
+}
+
+void tst_FakeVim::commandDollar()
+{
+    setup();
+    checkPosition("$", 0);
+    checkPosition("j", 2);
+}
+
 
 QTEST_MAIN(tst_FakeVim)
 
diff --git a/tests/manual/gdbdebugger/simple/app.cpp b/tests/manual/gdbdebugger/simple/app.cpp
index 8b51d7f8b767f506cd1470f587749433b3bd3ba9..d50180c4ad2fc60fee3e15b04e8a7b58f69c7878 100644
--- a/tests/manual/gdbdebugger/simple/app.cpp
+++ b/tests/manual/gdbdebugger/simple/app.cpp
@@ -1078,7 +1078,8 @@ struct QMetaTypeId<QHostAddress>
     {
         static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0);
         if (!metatype_id)
-             metatype_id = qRegisterMetaType<QHostAddress>("myns::QHostAddress");
+             metatype_id = qRegisterMetaType<QHostAddress>
+                ("myns::QHostAddress");
         return metatype_id;                                    \
     }                                                           \
 };
@@ -1091,7 +1092,8 @@ struct QMetaTypeId< QMap<uint, QStringList> >
     {
         static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0);
         if (!metatype_id)
-             metatype_id = qRegisterMetaType< QMap<uint, QStringList> >("myns::QMap<uint, myns::QStringList>");
+             metatype_id = qRegisterMetaType< QMap<uint, QStringList> >
+                ("myns::QMap<uint, myns::QStringList>");
         return metatype_id;                                    \
     }                                                           \
 };