diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp
index 550d0360a7c7e668fcfd54b5c8413f9a001b0f6c..903a991caf3afd65446e9bd3ee64c621ada6bb00 100644
--- a/src/plugins/debugger/cdb/cdbengine.cpp
+++ b/src/plugins/debugger/cdb/cdbengine.cpp
@@ -55,6 +55,7 @@
 #include "shared/cdbsymbolpathlisteditor.h"
 #include "shared/hostutils.h"
 #include "procinterrupt.h"
+#include "sourceutils.h"
 
 #include <TranslationUnit.h>
 
diff --git a/src/plugins/debugger/debugger.pro b/src/plugins/debugger/debugger.pro
index eb9e101e716cfa9eadc1127dd9cfc8d829f7d29e..0ca196b27fe00f305894698487ddac3511648118 100644
--- a/src/plugins/debugger/debugger.pro
+++ b/src/plugins/debugger/debugger.pro
@@ -57,6 +57,7 @@ HEADERS += \
     sourceagent.h \
     sourcefileshandler.h \
     sourcefileswindow.h \
+    sourceutils.h \
     stackframe.h \
     stackhandler.h \
     stackwindow.h \
@@ -107,6 +108,7 @@ SOURCES += \
     sourceagent.cpp \
     sourcefileshandler.cpp \
     sourcefileswindow.cpp \
+    sourceutils.cpp \
     stackhandler.cpp \
     stackwindow.cpp \
     threadshandler.cpp \
diff --git a/src/plugins/debugger/debugger.qbs b/src/plugins/debugger/debugger.qbs
index 1cbbd2c4824064369125c7c882c20f7373f38687..d87a42171f2eb6a2b28acf47f0aed768dcae3cf6 100644
--- a/src/plugins/debugger/debugger.qbs
+++ b/src/plugins/debugger/debugger.qbs
@@ -117,6 +117,8 @@ QtcPlugin {
         "sourcefileshandler.h",
         "sourcefileswindow.cpp",
         "sourcefileswindow.h",
+        "sourceutils.cpp",
+        "sourceutils.h",
         "stackframe.cpp",
         "stackframe.h",
         "stackhandler.cpp",
diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp
index a1e155a376b3225641a33712a3f9555321ea317e..a2d76a2bba679a69899541e9bd5437b452b7442c 100644
--- a/src/plugins/debugger/debuggerplugin.cpp
+++ b/src/plugins/debugger/debuggerplugin.cpp
@@ -62,6 +62,7 @@
 #include "localsandexpressionswindow.h"
 #include "loadcoredialog.h"
 #include "hostutils.h"
+#include "sourceutils.h"
 
 #include "snapshothandler.h"
 #include "threadshandler.h"
diff --git a/src/plugins/debugger/gdb/classicgdbengine.cpp b/src/plugins/debugger/gdb/classicgdbengine.cpp
index a6634d8226e2c5df58643331db9e21c58068d193..957a5b6bb322b0ace2bf6dff3ffcecfaeebf5a2f 100644
--- a/src/plugins/debugger/gdb/classicgdbengine.cpp
+++ b/src/plugins/debugger/gdb/classicgdbengine.cpp
@@ -34,6 +34,7 @@
 #include "debuggerprotocol.h"
 #include "debuggerstartparameters.h"
 #include "debuggerstringutils.h"
+#include "sourceutils.h"
 #include "stackhandler.h"
 #include "watchhandler.h"
 
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index 2d97fbcda298b2a609438018b6cf18a2825a4e5d..fef90b55a1441d4fceedcc850962b8066e1f3956 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -51,6 +51,7 @@
 #include "disassembleragent.h"
 #include "gdboptionspage.h"
 #include "memoryagent.h"
+#include "sourceutils.h"
 #include "watchutils.h"
 
 #include "breakhandler.h"
@@ -5448,6 +5449,14 @@ void GdbEngine::interruptLocalInferior(qint64 pid)
     }
 }
 
+QByteArray GdbEngine::dotEscape(QByteArray str)
+{
+    str.replace(' ', '.');
+    str.replace('\\', '.');
+    str.replace('/', '.');
+    return str;
+}
+
 //
 // Factory
 //
diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h
index 6cd6597438e12487516aedca389d03aa55a17c8a..c9f932f89caaaf3de6468e6d064c9c279c4fa6bf 100644
--- a/src/plugins/debugger/gdb/gdbengine.h
+++ b/src/plugins/debugger/gdb/gdbengine.h
@@ -720,6 +720,7 @@ protected:
     static QString msgInferiorSetupOk();
     static QString msgInferiorRunOk();
     static QString msgConnectRemoteServerFailed(const QString &why);
+    static QByteArray dotEscape(QByteArray str);
 
 protected:
     enum DumperHandling
diff --git a/src/plugins/debugger/pdb/pdbengine.cpp b/src/plugins/debugger/pdb/pdbengine.cpp
index ca78dcff62c10ca63edd03a72f9cf36918c3a14e..b87b27ce2d1ef42b99a2a476c1fd11622509a67a 100644
--- a/src/plugins/debugger/pdb/pdbengine.cpp
+++ b/src/plugins/debugger/pdb/pdbengine.cpp
@@ -42,6 +42,7 @@
 #include "moduleshandler.h"
 #include "registerhandler.h"
 #include "stackhandler.h"
+#include "sourceutils.h"
 #include "watchhandler.h"
 #include "watchutils.h"
 
diff --git a/src/plugins/debugger/script/scriptengine.cpp b/src/plugins/debugger/script/scriptengine.cpp
index b8a8a8ff82306d716ae839a2fbfece482a9d8527..f88bd8f35e29f103ee6da398babfdf82a89f29c2 100644
--- a/src/plugins/debugger/script/scriptengine.cpp
+++ b/src/plugins/debugger/script/scriptengine.cpp
@@ -37,6 +37,7 @@
 #include "debuggerstringutils.h"
 #include "moduleshandler.h"
 #include "registerhandler.h"
+#include "sourceutils.h"
 #include "stackhandler.h"
 #include "watchhandler.h"
 #include "watchutils.h"
diff --git a/src/plugins/debugger/sourceutils.cpp b/src/plugins/debugger/sourceutils.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..22dc8e34d3e30fcfebfadc380ada7d39642fde4f
--- /dev/null
+++ b/src/plugins/debugger/sourceutils.cpp
@@ -0,0 +1,431 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "sourceutils.h"
+
+#include "debuggerprotocol.h"
+#include "debuggerstringutils.h"
+#include "watchdata.h"
+#include "watchutils.h"
+
+#include <utils/qtcassert.h>
+
+#include <coreplugin/idocument.h>
+
+#include <texteditor/basetexteditor.h>
+#include <texteditor/basetextmark.h>
+#include <texteditor/itexteditor.h>
+#include <texteditor/texteditorconstants.h>
+#include <coreplugin/editormanager/editormanager.h>
+
+#include <cpptools/cpptoolsconstants.h>
+#include <cpptools/abstracteditorsupport.h>
+
+#include <cpptools/ModelManagerInterface.h>
+#include <cplusplus/ExpressionUnderCursor.h>
+#include <cplusplus/Overview.h>
+#include <Symbols.h>
+#include <Scope.h>
+
+#include <extensionsystem/pluginmanager.h>
+
+#include <QCoreApplication>
+#include <QDateTime>
+#include <QDebug>
+#include <QHash>
+#include <QStringList>
+#include <QTextStream>
+#include <QTime>
+
+#include <QTextCursor>
+#include <QPlainTextEdit>
+
+#include <string.h>
+#include <ctype.h>
+
+enum { debug = 0 };
+
+// Debug helpers for code model. @todo: Move to some CppTools library?
+namespace CPlusPlus {
+
+static void debugCppSymbolRecursion(QTextStream &str, const Overview &o,
+                                    const Symbol &s, bool doRecurse = true,
+                                    int recursion = 0)
+{
+    for (int i = 0; i < recursion; i++)
+        str << "  ";
+    str << "Symbol: " << o.prettyName(s.name()) << " at line " << s.line();
+    if (s.isFunction())
+        str << " function";
+    if (s.isClass())
+        str << " class";
+    if (s.isDeclaration())
+        str << " declaration";
+    if (s.isBlock())
+        str << " block";
+    if (doRecurse && s.isScope()) {
+        const Scope *scoped = s.asScope();
+        const int size =  scoped->memberCount();
+        str << " scoped symbol of " << size << '\n';
+        for (int m = 0; m < size; m++)
+            debugCppSymbolRecursion(str, o, *scoped->memberAt(m), true, recursion + 1);
+    } else {
+        str << '\n';
+    }
+}
+
+QDebug operator<<(QDebug d, const Symbol &s)
+{
+    QString output;
+    CPlusPlus::Overview o;
+    QTextStream str(&output);
+    debugCppSymbolRecursion(str, o, s, true, 0);
+    d.nospace() << output;
+    return d;
+}
+
+QDebug operator<<(QDebug d, const Scope &scope)
+{
+    QString output;
+    Overview o;
+    QTextStream str(&output);
+    const int size =  scope.memberCount();
+    str << "Scope of " << size;
+    if (scope.isNamespace())
+        str << " namespace";
+    if (scope.isClass())
+        str << " class";
+    if (scope.isEnum())
+        str << " enum";
+    if (scope.isBlock())
+        str << " block";
+    if (scope.isFunction())
+        str << " function";
+    if (scope.isFunction())
+        str << " prototype";
+#if 0 // ### port me
+    if (const Symbol *owner = &scope) {
+        str << " owner: ";
+        debugCppSymbolRecursion(str, o, *owner, false, 0);
+    } else {
+        str << " 0-owner\n";
+    }
+#endif
+    for (int s = 0; s < size; s++)
+        debugCppSymbolRecursion(str, o, *scope.memberAt(s), true, 2);
+    d.nospace() << output;
+    return d;
+}
+} // namespace CPlusPlus
+
+namespace Debugger {
+namespace Internal {
+
+/* getUninitializedVariables(): Get variables that are not initialized
+ * at a certain line of a function from the code model to be able to
+ * indicate them as not in scope in the locals view.
+ * Find document + function in the code model, do a double check and
+ * collect declarative symbols that are in the function past or on
+ * the current line. blockRecursion() recurses up the scopes
+ * and collect symbols declared past or on the current line.
+ * Recursion goes up from the innermost scope, keeping a map
+ * of occurrences seen, to be able to derive the names of
+ * shadowed variables as the debugger sees them:
+\code
+int x;             // Occurrence (1), should be reported as "x <shadowed 1>"
+if (true) {
+   int x = 5; (2)  // Occurrence (2), should be reported as "x"
+}
+\endcode
+ */
+
+typedef QHash<QString, int> SeenHash;
+
+static void blockRecursion(const CPlusPlus::Overview &overview,
+                           const CPlusPlus::Scope *scope,
+                           unsigned line,
+                           QStringList *uninitializedVariables,
+                           SeenHash *seenHash,
+                           int level = 0)
+{
+    // Go backwards in case someone has identical variables in the same scope.
+    // Fixme: loop variables or similar are currently seen in the outer scope
+    for (int s = scope->memberCount() - 1; s >= 0; --s){
+        const CPlusPlus::Symbol *symbol = scope->memberAt(s);
+        if (symbol->isDeclaration()) {
+            // Find out about shadowed symbols by bookkeeping
+            // the already seen occurrences in a hash.
+            const QString name = overview.prettyName(symbol->name());
+            SeenHash::iterator it = seenHash->find(name);
+            if (it == seenHash->end())
+                it = seenHash->insert(name, 0);
+            else
+                ++(it.value());
+            // Is the declaration on or past the current line, that is,
+            // the variable not initialized.
+            if (symbol->line() >= line)
+                uninitializedVariables->push_back(WatchData::shadowedName(name, it.value()));
+        }
+    }
+    // Next block scope.
+    if (const CPlusPlus::Scope *enclosingScope = scope->enclosingBlock())
+        blockRecursion(overview, enclosingScope, line, uninitializedVariables, seenHash, level + 1);
+}
+
+// Inline helper with integer error return codes.
+static inline
+int getUninitializedVariablesI(const CPlusPlus::Snapshot &snapshot,
+                               const QString &functionName,
+                               const QString &file,
+                               int line,
+                               QStringList *uninitializedVariables)
+{
+    uninitializedVariables->clear();
+    // Find document
+    if (snapshot.isEmpty() || functionName.isEmpty() || file.isEmpty() || line < 1)
+        return 1;
+    const CPlusPlus::Snapshot::const_iterator docIt = snapshot.find(file);
+    if (docIt == snapshot.end())
+        return 2;
+    const CPlusPlus::Document::Ptr doc = docIt.value();
+    // Look at symbol at line and find its function. Either it is the
+    // function itself or some expression/variable.
+    const CPlusPlus::Symbol *symbolAtLine = doc->lastVisibleSymbolAt(line, 0);
+    if (!symbolAtLine)
+        return 4;
+    // First figure out the function to do a safety name check
+    // and the innermost scope at cursor position
+    const CPlusPlus::Function *function = 0;
+    const CPlusPlus::Scope *innerMostScope = 0;
+    if (symbolAtLine->isFunction()) {
+        function = symbolAtLine->asFunction();
+        if (function->memberCount() == 1) // Skip over function block
+            if (CPlusPlus::Block *block = function->memberAt(0)->asBlock())
+                innerMostScope = block;
+    } else {
+        if (const CPlusPlus::Scope *functionScope = symbolAtLine->enclosingFunction()) {
+            function = functionScope->asFunction();
+            innerMostScope = symbolAtLine->isBlock() ?
+                             symbolAtLine->asBlock() :
+                             symbolAtLine->enclosingBlock();
+        }
+    }
+    if (!function || !innerMostScope)
+        return 7;
+    // Compare function names with a bit off fuzz,
+    // skipping modules from a CDB symbol "lib!foo" or namespaces
+    // that the code model does not show at this point
+    CPlusPlus::Overview overview;
+    const QString name = overview.prettyName(function->name());
+    if (!functionName.endsWith(name))
+        return 11;
+    if (functionName.size() > name.size()) {
+        const char previousChar = functionName.at(functionName.size() - name.size() - 1).toLatin1();
+        if (previousChar != ':' && previousChar != '!' )
+            return 11;
+    }
+    // Starting from the innermost block scope, collect declarations.
+    SeenHash seenHash;
+    blockRecursion(overview, innerMostScope, line, uninitializedVariables, &seenHash);
+    return 0;
+}
+
+bool getUninitializedVariables(const CPlusPlus::Snapshot &snapshot,
+                               const QString &function,
+                               const QString &file,
+                               int line,
+                               QStringList *uninitializedVariables)
+{
+    const int rc = getUninitializedVariablesI(snapshot, function, file, line, uninitializedVariables);
+    if (debug) {
+        QString msg;
+        QTextStream str(&msg);
+        str << "getUninitializedVariables() " << function << ' ' << file << ':' << line
+                << " returns (int) " << rc << " '"
+                << uninitializedVariables->join(QString(QLatin1Char(','))) << '\'';
+        if (rc)
+            str << " of " << snapshot.size() << " documents";
+        qDebug() << msg;
+    }
+    return rc == 0;
+}
+
+//QByteArray gdbQuoteTypes(const QByteArray &type)
+//{
+//    // gdb does not understand sizeof(Core::IDocument*).
+//    // "sizeof('Core::IDocument*')" is also not acceptable,
+//    // it needs to be "sizeof('Core::IDocument'*)"
+//    //
+//    // We never will have a perfect solution here (even if we had a full blown
+//    // C++ parser as we do not have information on what is a type and what is
+//    // a variable name. So "a<b>::c" could either be two comparisons of values
+//    // 'a', 'b' and '::c', or a nested type 'c' in a template 'a<b>'. We
+//    // assume here it is the latter.
+//    //return type;
+
+//    // (*('myns::QPointer<myns::QObject>*'*)0x684060)" is not acceptable
+//    // (*('myns::QPointer<myns::QObject>'**)0x684060)" is acceptable
+//    if (isPointerType(type))
+//        return gdbQuoteTypes(stripPointerType(type)) + '*';
+
+//    QByteArray accu;
+//    QByteArray result;
+//    int templateLevel = 0;
+
+//    const char colon = ':';
+//    const char singleQuote = '\'';
+//    const char lessThan = '<';
+//    const char greaterThan = '>';
+//    for (int i = 0; i != type.size(); ++i) {
+//        const char c = type.at(i);
+//        if (isLetterOrNumber(c) || c == '_' || c == colon || c == ' ') {
+//            accu += c;
+//        } else if (c == lessThan) {
+//            ++templateLevel;
+//            accu += c;
+//        } else if (c == greaterThan) {
+//            --templateLevel;
+//            accu += c;
+//        } else if (templateLevel > 0) {
+//            accu += c;
+//        } else {
+//            if (accu.contains(colon) || accu.contains(lessThan))
+//                result += singleQuote + accu + singleQuote;
+//            else
+//                result += accu;
+//            accu.clear();
+//            result += c;
+//        }
+//    }
+//    if (accu.contains(colon) || accu.contains(lessThan))
+//        result += singleQuote + accu + singleQuote;
+//    else
+//        result += accu;
+//    //qDebug() << "GDB_QUOTING" << type << " TO " << result;
+
+//    return result;
+//}
+
+// Utilities to decode string data returned by the dumper helpers.
+
+
+// Editor tooltip support
+bool isCppEditor(Core::IEditor *editor)
+{
+    using namespace CppTools::Constants;
+    const Core::IDocument *document= editor->document();
+    if (!document)
+        return false;
+    const QByteArray mimeType = document->mimeType().toLatin1();
+    return mimeType == C_SOURCE_MIMETYPE
+        || mimeType == CPP_SOURCE_MIMETYPE
+        || mimeType == CPP_HEADER_MIMETYPE
+        || mimeType == OBJECTIVE_CPP_SOURCE_MIMETYPE;
+}
+
+// Return the Cpp expression, and, if desired, the function
+QString cppExpressionAt(TextEditor::ITextEditor *editor, int pos,
+                        int *line, int *column, QString *function /* = 0 */)
+{
+    using namespace CppTools;
+    using namespace CPlusPlus;
+    *line = *column = 0;
+    if (function)
+        function->clear();
+
+    const QPlainTextEdit *plaintext = qobject_cast<QPlainTextEdit*>(editor->widget());
+    if (!plaintext)
+        return QString();
+
+    QString expr = plaintext->textCursor().selectedText();
+    CppModelManagerInterface *modelManager = CppModelManagerInterface::instance();
+    if (expr.isEmpty() && modelManager) {
+        QTextCursor tc(plaintext->document());
+        tc.setPosition(pos);
+
+        const QChar ch = editor->characterAt(pos);
+        if (ch.isLetterOrNumber() || ch == QLatin1Char('_'))
+            tc.movePosition(QTextCursor::EndOfWord);
+
+        // Fetch the expression's code.
+        CPlusPlus::ExpressionUnderCursor expressionUnderCursor;
+        expr = expressionUnderCursor(tc);
+        *column = tc.positionInBlock();
+        *line = tc.blockNumber();
+    } else {
+        const QTextCursor tc = plaintext->textCursor();
+        *column = tc.positionInBlock();
+        *line = tc.blockNumber();
+    }
+
+    if (function && !expr.isEmpty())
+        if (const Core::IDocument *document= editor->document())
+            if (modelManager)
+                *function = AbstractEditorSupport::functionAt(modelManager,
+                    document->fileName(), *line, *column);
+
+    return expr;
+}
+
+// Ensure an expression can be added as side-effect
+// free debugger expression.
+QString fixCppExpression(const QString &expIn)
+{
+    QString exp = expIn.trimmed();;
+    // Extract the first identifier, everything else is considered
+    // too dangerous.
+    int pos1 = 0, pos2 = exp.size();
+    bool inId = false;
+    for (int i = 0; i != exp.size(); ++i) {
+        const QChar c = exp.at(i);
+        const bool isIdChar = c.isLetterOrNumber() || c.unicode() == '_';
+        if (inId && !isIdChar) {
+            pos2 = i;
+            break;
+        }
+        if (!inId && isIdChar) {
+            inId = true;
+            pos1 = i;
+        }
+    }
+    exp = exp.mid(pos1, pos2 - pos1);
+    return removeObviousSideEffects(exp);
+}
+
+QString cppFunctionAt(const QString &fileName, int line)
+{
+    using namespace CppTools;
+    using namespace CPlusPlus;
+    CppModelManagerInterface *modelManager = CppModelManagerInterface::instance();
+    return AbstractEditorSupport::functionAt(modelManager,
+                                             fileName, line, 1);
+}
+
+} // namespace Internal
+} // namespace Debugger
diff --git a/src/plugins/debugger/sourceutils.h b/src/plugins/debugger/sourceutils.h
new file mode 100644
index 0000000000000000000000000000000000000000..12bea32f198a13e49414fea233ecd916b88389fb
--- /dev/null
+++ b/src/plugins/debugger/sourceutils.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef SOURCE_UTILS_H
+#define SOURCE_UTILS_H
+
+#include <QSet>
+#include <QString>
+
+namespace TextEditor { class ITextEditor; }
+namespace Core { class IEditor; }
+namespace CPlusPlus { class Snapshot; }
+
+namespace Debugger {
+namespace Internal {
+
+// Editor tooltip support
+bool isCppEditor(Core::IEditor *editor);
+QString cppExpressionAt(TextEditor::ITextEditor *editor, int pos,
+                        int *line, int *column, QString *function = 0);
+QString fixCppExpression(const QString &exp);
+QString cppFunctionAt(const QString &fileName, int line);
+
+// Get variables that are not initialized at a certain line
+// of a function from the code model. Shadowed variables will
+// be reported using the debugger naming conventions '<shadowed n>'
+bool getUninitializedVariables(const CPlusPlus::Snapshot &snapshot,
+   const QString &function, const QString &file, int line,
+   QStringList *uninitializedVariables);
+
+} // namespace Internal
+} // namespace Debugger
+
+#endif // SOURCE_UTILS_H
diff --git a/src/plugins/debugger/watchdata.cpp b/src/plugins/debugger/watchdata.cpp
index 866b31209cdc5b692769f45f5e3eeb2c3a30198b..90234453922a93d44d89f74b77f43f44c2c08e9e 100644
--- a/src/plugins/debugger/watchdata.cpp
+++ b/src/plugins/debugger/watchdata.cpp
@@ -27,11 +27,14 @@
 **
 ****************************************************************************/
 
+// NOTE: Don't add dependencies to other files.
+// This is used in the debugger auto-tests.
+
 #include "watchdata.h"
 #include "watchutils.h"
 
-#include <QTextStream>
 #include <QTextDocument>
+#include <QTextStream>
 #include <QDebug>
 
 ////////////////////////////////////////////////////////////////////
diff --git a/src/plugins/debugger/watchutils.cpp b/src/plugins/debugger/watchutils.cpp
index ad079eb27a5e5e0b7ac15a9f7fdf86c28c5745bc..162c91b22d6edf7373642f2e947678bd753c1369 100644
--- a/src/plugins/debugger/watchutils.cpp
+++ b/src/plugins/debugger/watchutils.cpp
@@ -27,135 +27,44 @@
 **
 ****************************************************************************/
 
+// NOTE: Don't add dependencies to other files.
+// This is used in the debugger auto-tests.
+
 #include "watchutils.h"
 #include "watchdata.h"
 #include "debuggerprotocol.h"
-#include "debuggerstringutils.h"
-
-#include <utils/qtcassert.h>
-
-#include <coreplugin/idocument.h>
-
-#include <texteditor/basetexteditor.h>
-#include <texteditor/basetextmark.h>
-#include <texteditor/itexteditor.h>
-#include <texteditor/texteditorconstants.h>
-#include <coreplugin/editormanager/editormanager.h>
-
-#include <cpptools/cpptoolsconstants.h>
-#include <cpptools/abstracteditorsupport.h>
-
-#include <cpptools/ModelManagerInterface.h>
-#include <cplusplus/ExpressionUnderCursor.h>
-#include <cplusplus/Overview.h>
-#include <Symbols.h>
-#include <Scope.h>
-
-#include <extensionsystem/pluginmanager.h>
 
-#include <QCoreApplication>
-#include <QDateTime>
 #include <QDebug>
-#include <QHash>
-#include <QStringList>
-#include <QTextStream>
-#include <QTime>
-
-#include <QTextCursor>
-#include <QPlainTextEdit>
 
 #include <string.h>
 #include <ctype.h>
 
 enum { debug = 0 };
 
-// Debug helpers for code model. @todo: Move to some CppTools library?
-namespace CPlusPlus {
+namespace Debugger {
+namespace Internal {
 
-static void debugCppSymbolRecursion(QTextStream &str, const Overview &o,
-                                    const Symbol &s, bool doRecurse = true,
-                                    int recursion = 0)
+QString removeObviousSideEffects(const QString &expIn)
 {
-    for (int i = 0; i < recursion; i++)
-        str << "  ";
-    str << "Symbol: " << o.prettyName(s.name()) << " at line " << s.line();
-    if (s.isFunction())
-        str << " function";
-    if (s.isClass())
-        str << " class";
-    if (s.isDeclaration())
-        str << " declaration";
-    if (s.isBlock())
-        str << " block";
-    if (doRecurse && s.isScope()) {
-        const Scope *scoped = s.asScope();
-        const int size =  scoped->memberCount();
-        str << " scoped symbol of " << size << '\n';
-        for (int m = 0; m < size; m++)
-            debugCppSymbolRecursion(str, o, *scoped->memberAt(m), true, recursion + 1);
-    } else {
-        str << '\n';
-    }
-}
+    QString exp = expIn.trimmed();
+    if (exp.isEmpty() || exp.startsWith(QLatin1Char('#')) || !hasLetterOrNumber(exp) || isKeyWord(exp))
+        return QString();
 
-QDebug operator<<(QDebug d, const Symbol &s)
-{
-    QString output;
-    CPlusPlus::Overview o;
-    QTextStream str(&output);
-    debugCppSymbolRecursion(str, o, s, true, 0);
-    d.nospace() << output;
-    return d;
-}
+    if (exp.startsWith(QLatin1Char('"')) && exp.endsWith(QLatin1Char('"')))
+        return QString();
 
-QDebug operator<<(QDebug d, const Scope &scope)
-{
-    QString output;
-    Overview o;
-    QTextStream str(&output);
-    const int size =  scope.memberCount();
-    str << "Scope of " << size;
-    if (scope.isNamespace())
-        str << " namespace";
-    if (scope.isClass())
-        str << " class";
-    if (scope.isEnum())
-        str << " enum";
-    if (scope.isBlock())
-        str << " block";
-    if (scope.isFunction())
-        str << " function";
-    if (scope.isFunction())
-        str << " prototype";
-#if 0 // ### port me
-    if (const Symbol *owner = &scope) {
-        str << " owner: ";
-        debugCppSymbolRecursion(str, o, *owner, false, 0);
-    } else {
-        str << " 0-owner\n";
-    }
-#endif
-    for (int s = 0; s < size; s++)
-        debugCppSymbolRecursion(str, o, *scope.memberAt(s), true, 2);
-    d.nospace() << output;
-    return d;
-}
-} // namespace CPlusPlus
+    if (exp.startsWith(QLatin1String("++")) || exp.startsWith(QLatin1String("--")))
+        exp.remove(0, 2);
 
-namespace Debugger {
-namespace Internal {
+    if (exp.endsWith(QLatin1String("++")) || exp.endsWith(QLatin1String("--")))
+        exp.truncate(exp.size() - 2);
 
-QByteArray dotEscape(QByteArray str)
-{
-    str.replace(' ', '.');
-    str.replace('\\', '.');
-    str.replace('/', '.');
-    return str;
-}
+    if (exp.startsWith(QLatin1Char('<')) || exp.startsWith(QLatin1Char('[')))
+        return QString();
 
-QString currentTime()
-{
-    return QTime::currentTime().toString(QLatin1String("hh:mm:ss.zzz"));
+    if (hasSideEffects(exp) || exp.isEmpty())
+        return QString();
+    return exp;
 }
 
 bool isSkippableFunction(const QString &funcName, const QString &fileName)
@@ -269,8 +178,9 @@ bool hasSideEffects(const QString &exp)
 
 bool isKeyWord(const QString &exp)
 {
-    // FIXME: incomplete
-    QTC_ASSERT(!exp.isEmpty(), return false);
+    // FIXME: incomplete.
+    if (!exp.isEmpty())
+        return false;
     switch (exp.at(0).toLatin1()) {
     case 'a':
         return exp == QLatin1String("auto");
@@ -361,135 +271,6 @@ QString formatToolTipAddress(quint64 a)
     return QLatin1String("0x") + rc;
 }
 
-/* getUninitializedVariables(): Get variables that are not initialized
- * at a certain line of a function from the code model to be able to
- * indicate them as not in scope in the locals view.
- * Find document + function in the code model, do a double check and
- * collect declarative symbols that are in the function past or on
- * the current line. blockRecursion() recurses up the scopes
- * and collect symbols declared past or on the current line.
- * Recursion goes up from the innermost scope, keeping a map
- * of occurrences seen, to be able to derive the names of
- * shadowed variables as the debugger sees them:
-\code
-int x;             // Occurrence (1), should be reported as "x <shadowed 1>"
-if (true) {
-   int x = 5; (2)  // Occurrence (2), should be reported as "x"
-}
-\endcode
- */
-
-typedef QHash<QString, int> SeenHash;
-
-static void blockRecursion(const CPlusPlus::Overview &overview,
-                           const CPlusPlus::Scope *scope,
-                           unsigned line,
-                           QStringList *uninitializedVariables,
-                           SeenHash *seenHash,
-                           int level = 0)
-{
-    // Go backwards in case someone has identical variables in the same scope.
-    // Fixme: loop variables or similar are currently seen in the outer scope
-    for (int s = scope->memberCount() - 1; s >= 0; --s){
-        const CPlusPlus::Symbol *symbol = scope->memberAt(s);
-        if (symbol->isDeclaration()) {
-            // Find out about shadowed symbols by bookkeeping
-            // the already seen occurrences in a hash.
-            const QString name = overview.prettyName(symbol->name());
-            SeenHash::iterator it = seenHash->find(name);
-            if (it == seenHash->end())
-                it = seenHash->insert(name, 0);
-            else
-                ++(it.value());
-            // Is the declaration on or past the current line, that is,
-            // the variable not initialized.
-            if (symbol->line() >= line)
-                uninitializedVariables->push_back(WatchData::shadowedName(name, it.value()));
-        }
-    }
-    // Next block scope.
-    if (const CPlusPlus::Scope *enclosingScope = scope->enclosingBlock())
-        blockRecursion(overview, enclosingScope, line, uninitializedVariables, seenHash, level + 1);
-}
-
-// Inline helper with integer error return codes.
-static inline
-int getUninitializedVariablesI(const CPlusPlus::Snapshot &snapshot,
-                               const QString &functionName,
-                               const QString &file,
-                               int line,
-                               QStringList *uninitializedVariables)
-{
-    uninitializedVariables->clear();
-    // Find document
-    if (snapshot.isEmpty() || functionName.isEmpty() || file.isEmpty() || line < 1)
-        return 1;
-    const CPlusPlus::Snapshot::const_iterator docIt = snapshot.find(file);
-    if (docIt == snapshot.end())
-        return 2;
-    const CPlusPlus::Document::Ptr doc = docIt.value();
-    // Look at symbol at line and find its function. Either it is the
-    // function itself or some expression/variable.
-    const CPlusPlus::Symbol *symbolAtLine = doc->lastVisibleSymbolAt(line, 0);
-    if (!symbolAtLine)
-        return 4;
-    // First figure out the function to do a safety name check
-    // and the innermost scope at cursor position
-    const CPlusPlus::Function *function = 0;
-    const CPlusPlus::Scope *innerMostScope = 0;
-    if (symbolAtLine->isFunction()) {
-        function = symbolAtLine->asFunction();
-        if (function->memberCount() == 1) // Skip over function block
-            if (CPlusPlus::Block *block = function->memberAt(0)->asBlock())
-                innerMostScope = block;
-    } else {
-        if (const CPlusPlus::Scope *functionScope = symbolAtLine->enclosingFunction()) {
-            function = functionScope->asFunction();
-            innerMostScope = symbolAtLine->isBlock() ?
-                             symbolAtLine->asBlock() :
-                             symbolAtLine->enclosingBlock();
-        }
-    }
-    if (!function || !innerMostScope)
-        return 7;
-    // Compare function names with a bit off fuzz,
-    // skipping modules from a CDB symbol "lib!foo" or namespaces
-    // that the code model does not show at this point
-    CPlusPlus::Overview overview;
-    const QString name = overview.prettyName(function->name());
-    if (!functionName.endsWith(name))
-        return 11;
-    if (functionName.size() > name.size()) {
-        const char previousChar = functionName.at(functionName.size() - name.size() - 1).toLatin1();
-        if (previousChar != ':' && previousChar != '!' )
-            return 11;
-    }
-    // Starting from the innermost block scope, collect declarations.
-    SeenHash seenHash;
-    blockRecursion(overview, innerMostScope, line, uninitializedVariables, &seenHash);
-    return 0;
-}
-
-bool getUninitializedVariables(const CPlusPlus::Snapshot &snapshot,
-                               const QString &function,
-                               const QString &file,
-                               int line,
-                               QStringList *uninitializedVariables)
-{
-    const int rc = getUninitializedVariablesI(snapshot, function, file, line, uninitializedVariables);
-    if (debug) {
-        QString msg;
-        QTextStream str(&msg);
-        str << "getUninitializedVariables() " << function << ' ' << file << ':' << line
-                << " returns (int) " << rc << " '"
-                << uninitializedVariables->join(QString(QLatin1Char(','))) << '\'';
-        if (rc)
-            str << " of " << snapshot.size() << " documents";
-        qDebug() << msg;
-    }
-    return rc == 0;
-}
-
 QByteArray gdbQuoteTypes(const QByteArray &type)
 {
     // gdb does not understand sizeof(Core::IDocument*).
@@ -609,121 +390,6 @@ void decodeArray(QList<WatchData> *list, const WatchData &tmplate,
     }
 }
 
-// Editor tooltip support
-bool isCppEditor(Core::IEditor *editor)
-{
-    using namespace CppTools::Constants;
-    const Core::IDocument *document= editor->document();
-    if (!document)
-        return false;
-    const QByteArray mimeType = document->mimeType().toLatin1();
-    return mimeType == C_SOURCE_MIMETYPE
-        || mimeType == CPP_SOURCE_MIMETYPE
-        || mimeType == CPP_HEADER_MIMETYPE
-        || mimeType == OBJECTIVE_CPP_SOURCE_MIMETYPE;
-}
-
-// Return the Cpp expression, and, if desired, the function
-QString cppExpressionAt(TextEditor::ITextEditor *editor, int pos,
-                        int *line, int *column, QString *function /* = 0 */)
-{
-    using namespace CppTools;
-    using namespace CPlusPlus;
-    *line = *column = 0;
-    if (function)
-        function->clear();
-
-    const QPlainTextEdit *plaintext = qobject_cast<QPlainTextEdit*>(editor->widget());
-    if (!plaintext)
-        return QString();
-
-    QString expr = plaintext->textCursor().selectedText();
-    CppModelManagerInterface *modelManager = CppModelManagerInterface::instance();
-    if (expr.isEmpty() && modelManager) {
-        QTextCursor tc(plaintext->document());
-        tc.setPosition(pos);
-
-        const QChar ch = editor->characterAt(pos);
-        if (ch.isLetterOrNumber() || ch == QLatin1Char('_'))
-            tc.movePosition(QTextCursor::EndOfWord);
-
-        // Fetch the expression's code.
-        CPlusPlus::ExpressionUnderCursor expressionUnderCursor;
-        expr = expressionUnderCursor(tc);
-        *column = tc.positionInBlock();
-        *line = tc.blockNumber();
-    } else {
-        const QTextCursor tc = plaintext->textCursor();
-        *column = tc.positionInBlock();
-        *line = tc.blockNumber();
-    }
-
-    if (function && !expr.isEmpty())
-        if (const Core::IDocument *document= editor->document())
-            if (modelManager)
-                *function = AbstractEditorSupport::functionAt(modelManager,
-                    document->fileName(), *line, *column);
-
-    return expr;
-}
-
-// Ensure an expression can be added as side-effect
-// free debugger expression.
-QString fixCppExpression(const QString &expIn)
-{
-    QString exp = expIn.trimmed();;
-    // Extract the first identifier, everything else is considered
-    // too dangerous.
-    int pos1 = 0, pos2 = exp.size();
-    bool inId = false;
-    for (int i = 0; i != exp.size(); ++i) {
-        const QChar c = exp.at(i);
-        const bool isIdChar = c.isLetterOrNumber() || c.unicode() == '_';
-        if (inId && !isIdChar) {
-            pos2 = i;
-            break;
-        }
-        if (!inId && isIdChar) {
-            inId = true;
-            pos1 = i;
-        }
-    }
-    exp = exp.mid(pos1, pos2 - pos1);
-    return removeObviousSideEffects(exp);
-}
-
-QString removeObviousSideEffects(const QString &expIn)
-{
-    QString exp = expIn.trimmed();
-    if (exp.isEmpty() || exp.startsWith(QLatin1Char('#')) || !hasLetterOrNumber(exp) || isKeyWord(exp))
-        return QString();
-
-    if (exp.startsWith(QLatin1Char('"')) && exp.endsWith(QLatin1Char('"')))
-        return QString();
-
-    if (exp.startsWith(QLatin1String("++")) || exp.startsWith(QLatin1String("--")))
-        exp.remove(0, 2);
-
-    if (exp.endsWith(QLatin1String("++")) || exp.endsWith(QLatin1String("--")))
-        exp.truncate(exp.size() - 2);
-
-    if (exp.startsWith(QLatin1Char('<')) || exp.startsWith(QLatin1Char('[')))
-        return QString();
-
-    if (hasSideEffects(exp) || exp.isEmpty())
-        return QString();
-    return exp;
-}
-
-QString cppFunctionAt(const QString &fileName, int line)
-{
-    using namespace CppTools;
-    using namespace CPlusPlus;
-    CppModelManagerInterface *modelManager = CppModelManagerInterface::instance();
-    return AbstractEditorSupport::functionAt(modelManager,
-                                             fileName, line, 1);
-}
-
 //////////////////////////////////////////////////////////////////////
 //
 // GdbMi interaction
@@ -830,7 +496,7 @@ void setWatchDataType(WatchData &data, const GdbMi &item)
 void setWatchDataDisplayedType(WatchData &data, const GdbMi &item)
 {
     if (item.isValid())
-        data.displayedType = _(item.data());
+        data.displayedType = QString::fromLatin1(item.data());
 }
 
 void parseWatchData(const QSet<QByteArray> &expandedINames,
@@ -897,7 +563,7 @@ void parseWatchData(const QSet<QByteArray> &expandedINames,
             data1.sortId = i;
             GdbMi name = child.findChild("name");
             if (name.isValid())
-                data1.name = _(name.data());
+                data1.name = QString::fromLatin1(name.data());
             else
                 data1.name = QString::number(i);
             GdbMi iname = child.findChild("iname");
@@ -920,7 +586,7 @@ void parseWatchData(const QSet<QByteArray> &expandedINames,
                 QString skey = decodeData(key, encoding);
                 if (skey.size() > 13) {
                     skey = skey.left(12);
-                    skey += _("...");
+                    skey += QLatin1String("...");
                 }
                 //data1.name += " (" + skey + ")";
                 data1.name = skey;
@@ -930,6 +596,5 @@ void parseWatchData(const QSet<QByteArray> &expandedINames,
     }
 }
 
-
 } // namespace Internal
 } // namespace Debugger
diff --git a/src/plugins/debugger/watchutils.h b/src/plugins/debugger/watchutils.h
index aef4ad1b42fc8a1504364119926c40c8ecdebc86..8ab67f3b77eeb0fcf4dbe4fcfcda89fa92c95d9d 100644
--- a/src/plugins/debugger/watchutils.h
+++ b/src/plugins/debugger/watchutils.h
@@ -30,29 +30,18 @@
 #ifndef WATCHUTILS_H
 #define WATCHUTILS_H
 
+// NOTE: Don't add dependencies to other files.
+// This is used in the debugger auto-tests.
+
 #include <QSet>
 #include <QString>
 
-namespace TextEditor {
-    class ITextEditor;
-}
-
-namespace Core {
-    class IEditor;
-}
-
-namespace CPlusPlus {
-    class Snapshot;
-}
-
 namespace Debugger {
 namespace Internal {
 
 class WatchData;
 class GdbMi;
 
-QByteArray dotEscape(QByteArray str);
-QString currentTime();
 bool isSkippableFunction(const QString &funcName, const QString &fileName);
 bool isLeavableFunction(const QString &funcName, const QString &fileName);
 
@@ -69,25 +58,12 @@ bool isIntOrFloatType(const QByteArray &type);
 bool isIntType(const QByteArray &type);
 
 QString formatToolTipAddress(quint64 a);
-
-// Editor tooltip support
-bool isCppEditor(Core::IEditor *editor);
-QString cppExpressionAt(TextEditor::ITextEditor *editor, int pos,
-                        int *line, int *column, QString *function = 0);
 QString removeObviousSideEffects(const QString &exp);
-QString fixCppExpression(const QString &exp);
-QString cppFunctionAt(const QString &fileName, int line);
+
 // Decode string data as returned by the dumper helpers.
 void decodeArray(WatchData *list, const WatchData &tmplate,
     const QByteArray &rawData, int encoding);
 
-// Get variables that are not initialized at a certain line
-// of a function from the code model. Shadowed variables will
-// be reported using the debugger naming conventions '<shadowed n>'
-bool getUninitializedVariables(const CPlusPlus::Snapshot &snapshot,
-   const QString &function, const QString &file, int line,
-   QStringList *uninitializedVariables);
-
 
 //
 // GdbMi interaction