diff --git a/src/plugins/debugger/qml/qmldebuggerclient.h b/src/plugins/debugger/qml/qmldebuggerclient.h
index 8b92d17d396d0ce4c59618316b7b8796647098f2..11eafe213cb48566674b10301a2976b69795f925 100644
--- a/src/plugins/debugger/qml/qmldebuggerclient.h
+++ b/src/plugins/debugger/qml/qmldebuggerclient.h
@@ -83,6 +83,8 @@ public:
 
     virtual void setEngine(QmlEngine *engine) = 0;
 
+    virtual void getSourceFiles() {}
+
     void flushSendBuffer();
 
 signals:
diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp
index d9054312a25487c1ca129fa5889c96f1cf02ed04..66620897b267310d4b338e3d71acaee63bdb8779 100644
--- a/src/plugins/debugger/qml/qmlengine.cpp
+++ b/src/plugins/debugger/qml/qmlengine.cpp
@@ -38,6 +38,7 @@
 #include "debuggerconstants.h"
 #include "debuggercore.h"
 #include "debuggerdialogs.h"
+#include "debuggerinternalconstants.h"
 #include "debuggermainwindow.h"
 #include "debuggerrunner.h"
 #include "debuggerstringutils.h"
@@ -48,18 +49,24 @@
 #include "registerhandler.h"
 #include "stackhandler.h"
 #include "watchhandler.h"
+#include "sourcefileshandler.h"
 #include "watchutils.h"
 
 #include <extensionsystem/pluginmanager.h>
 #include <projectexplorer/applicationlauncher.h>
 #include <qmljsdebugclient/qdeclarativeoutputparser.h>
+#include <qmljseditor/qmljseditorconstants.h>
 
 #include <utils/environment.h>
 #include <utils/qtcassert.h>
 #include <utils/fileinprojectfinder.h>
 
-#include <coreplugin/icore.h>
+#include <coreplugin/coreconstants.h>
+#include <coreplugin/editormanager/editormanager.h>
 #include <coreplugin/helpmanager.h>
+#include <coreplugin/icore.h>
+
+#include <texteditor/itexteditor.h>
 
 #include <QtCore/QDateTime>
 #include <QtCore/QDebug>
@@ -71,6 +78,7 @@
 #include <QtGui/QApplication>
 #include <QtGui/QMainWindow>
 #include <QtGui/QMessageBox>
+#include <QtGui/QPlainTextEdit>
 #include <QtGui/QToolTip>
 #include <QtGui/QTextDocument>
 
@@ -102,6 +110,8 @@ private:
     Utils::FileInProjectFinder fileFinder;
     QTimer m_noDebugOutputTimer;
     QmlJsDebugClient::QDeclarativeOutputParser m_outputParser;
+    QHash<QString, QTextDocument*> m_sourceDocuments;
+    QHash<QString, QWeakPointer<TextEditor::ITextEditor> > m_sourceEditors;
 };
 
 QmlEnginePrivate::QmlEnginePrivate(QmlEngine *q)
@@ -170,6 +180,16 @@ QmlEngine::~QmlEngine()
         pluginManager->removeObject(this);
     }
 
+    QList<Core::IEditor *> editorsToClose;
+
+    QHash<QString, QWeakPointer<TextEditor::ITextEditor> >::iterator iter;
+    for (iter = d->m_sourceEditors.begin(); iter != d->m_sourceEditors.end(); ++iter) {
+        QWeakPointer<TextEditor::ITextEditor> textEditPtr = iter.value();
+        if (textEditPtr)
+            editorsToClose << textEditPtr.data();
+    }
+    Core::EditorManager::instance()->closeEditors(editorsToClose);
+
     delete d;
 }
 
@@ -322,6 +342,46 @@ void QmlEngine::showMessage(const QString &msg, int channel, int timeout) const
     DebuggerEngine::showMessage(msg, channel, timeout);
 }
 
+void QmlEngine::gotoLocation(const Location &location)
+{
+    const QString fileName = location.fileName();
+    if (QUrl(fileName).isLocalFile()) {
+        // internal file from source files -> show generated .js
+        QString fileName = location.fileName();
+        QTC_ASSERT(d->m_sourceDocuments.contains(fileName), return);
+        const QString jsSource = d->m_sourceDocuments.value(fileName)->toPlainText();
+
+        Core::IEditor *editor = 0;
+
+        Core::EditorManager *editorManager = Core::EditorManager::instance();
+        QList<Core::IEditor *> editors = editorManager->editorsForFileName(location.fileName());
+        if (editors.isEmpty()) {
+            QString titlePattern = tr("JS Source for %1").arg(fileName);
+            editor = editorManager->openEditorWithContents(QmlJSEditor::Constants::C_QMLJSEDITOR_ID,
+                                                           &titlePattern);
+            if (editor) {
+                editor->setProperty(Constants::OPENED_BY_DEBUGGER, true);
+            }
+        } else {
+            editor = editors.back();
+        }
+
+        TextEditor::ITextEditor *textEditor = qobject_cast<TextEditor::ITextEditor*>(editor);
+        if (!textEditor)
+            return;
+
+        QPlainTextEdit *plainTextEdit =
+                qobject_cast<QPlainTextEdit *>(editor->widget());
+        if (!plainTextEdit)
+            return;
+        plainTextEdit->setPlainText(jsSource);
+        plainTextEdit->setReadOnly(true);
+        editorManager->activateEditor(editor);
+    } else {
+        DebuggerEngine::gotoLocation(location);
+    }
+}
+
 void QmlEngine::closeConnection()
 {
     disconnect(watchersModel(),SIGNAL(layoutChanged()),this,SLOT(synchronizeWatchers()));
@@ -643,6 +703,13 @@ void QmlEngine::reloadModules()
 {
 }
 
+void QmlEngine::reloadSourceFiles()
+{
+    if (d->m_adapter.activeDebuggerClient()) {
+        d->m_adapter.activeDebuggerClient()->getSourceFiles();
+    }
+}
+
 void QmlEngine::requestModuleSymbols(const QString &moduleName)
 {
     Q_UNUSED(moduleName)
@@ -783,6 +850,61 @@ void QmlEngine::logMessage(const QString &service, LogDirection direction, const
     showMessage(msg, LogDebug);
 }
 
+void QmlEngine::setSourceFiles(const QStringList &fileNames)
+{
+    QMap<QString,QString> files;
+    foreach (const QString &file, fileNames) {
+        QString shortName = file;
+        QString fullName = d->fileFinder.findFile(file);
+        files.insert(shortName, fullName);
+    }
+
+    sourceFilesHandler()->setSourceFiles(files);
+}
+
+void QmlEngine::updateScriptSource(const QString &fileName, int lineOffset, int columnOffset,
+                                   const QString &source)
+{
+    QTextDocument *document = 0;
+    if (d->m_sourceDocuments.contains(fileName)) {
+        document = d->m_sourceDocuments.value(fileName);
+    } else {
+        document = new QTextDocument(this);
+        d->m_sourceDocuments.insert(fileName, document);
+    }
+
+    // We're getting an unordered set of snippets that can even interleave
+    // Therefore we've to carefully update the existing document
+
+    QTextCursor cursor(document);
+    for (int i = 0; i < lineOffset; ++i) {
+        if (!cursor.movePosition(QTextCursor::NextBlock))
+            cursor.insertBlock();
+    }
+    QTC_CHECK(cursor.blockNumber() == lineOffset);
+
+    for (int i = 0; i < columnOffset; ++i) {
+        if (!cursor.movePosition(QTextCursor::NextCharacter))
+            cursor.insertText(QLatin1String(" "));
+    }
+    QTC_CHECK(cursor.positionInBlock() == columnOffset);
+
+    QStringList lines = source.split(QLatin1Char('\n'));
+    foreach (QString line, lines) {
+        if (line.endsWith(QLatin1Char('\r')))
+            line.remove(line.size() -1, 1);
+
+        // line already there?
+        QTextCursor existingCursor(cursor);
+        existingCursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
+        if (existingCursor.selectedText() != line)
+            cursor.insertText(line);
+
+        if (!cursor.movePosition(QTextCursor::NextBlock))
+            cursor.insertBlock();
+    }
+}
+
 QmlAdapter *QmlEngine::adapter() const
 {
     return &d->m_adapter;
diff --git a/src/plugins/debugger/qml/qmlengine.h b/src/plugins/debugger/qml/qmlengine.h
index cc165bf1a1cb1755f1e3cf32529966623f48212a..2500d55df56a17ecc67172aa3c1f963e12ab0723 100644
--- a/src/plugins/debugger/qml/qmlengine.h
+++ b/src/plugins/debugger/qml/qmlengine.h
@@ -68,12 +68,17 @@ public:
 
     void showMessage(const QString &msg, int channel = LogDebug,
                      int timeout = -1) const;
+    void gotoLocation(const Internal::Location &location);
+
     void filterApplicationMessage(const QString &msg, int channel);
     QString toFileInProject(const QUrl &fileUrl);
     void inferiorSpontaneousStop();
 
     void logMessage(const QString &service, LogDirection direction, const QString &str);
 
+    void setSourceFiles(const QStringList &fileNames);
+    void updateScriptSource(const QString &fileName, int lineOffset, int columnOffset, const QString &source);
+
     QmlAdapter *adapter() const;
 
 public slots:
@@ -120,12 +125,14 @@ private:
 
     void assignValueInDebugger(const WatchData *data,
         const QString &expr, const QVariant &value);
+
+
     void loadSymbols(const QString &moduleName);
     void loadAllSymbols();
     void requestModuleSymbols(const QString &moduleName);
     void reloadModules();
     void reloadRegisters() {}
-    void reloadSourceFiles() {}
+    void reloadSourceFiles();
     void reloadFullStack() {}
 
     bool supportsThreads() const { return false; }
diff --git a/src/plugins/debugger/qml/qmlv8debuggerclient.cpp b/src/plugins/debugger/qml/qmlv8debuggerclient.cpp
index c22bb5736c6192b2596786f535b38d690116c886..a76f8fef5f120003489f0e6731c2a820d16b063e 100644
--- a/src/plugins/debugger/qml/qmlv8debuggerclient.cpp
+++ b/src/plugins/debugger/qml/qmlv8debuggerclient.cpp
@@ -141,6 +141,7 @@ public:
 
     QScriptValue parser;
     QScriptValue stringifier;
+    QStringList scriptSourceRequests;
 
     QHash<int, QString> evaluatingExpression;
     QHash<int, QByteArray> localsAndWatchers;
@@ -447,7 +448,7 @@ void QmlV8DebuggerClientPrivate::scopes(int frameNumber)
 }
 
 void QmlV8DebuggerClientPrivate::scripts(int types, const QList<int> ids, bool includeSource,
-                                         const QVariant /*filter*/)
+                                         const QVariant filter)
 {
     //    { "seq"       : <number>,
     //      "type"      : "request",
@@ -482,6 +483,16 @@ void QmlV8DebuggerClientPrivate::scripts(int types, const QList<int> ids, bool i
     if (includeSource)
         args.setProperty(_(INCLUDESOURCE), QScriptValue(includeSource));
 
+    QScriptValue filterValue;
+    if (filter.type() == QVariant::String)
+        filterValue = QScriptValue(filter.toString());
+    else if (filter.type() == QVariant::Int)
+        filterValue = QScriptValue(filter.toInt());
+    else
+        QTC_CHECK(!filter.isValid());
+
+    args.setProperty(_(FILTER), filterValue);
+
     jsonVal.setProperty(_(ARGUMENTS), args);
 
     const QScriptValue jsonMessage = stringifier.call(QScriptValue(), QScriptValueList() << jsonVal);
@@ -1173,6 +1184,11 @@ void QmlV8DebuggerClient::setEngine(QmlEngine *engine)
     d->engine = engine;
 }
 
+void QmlV8DebuggerClient::getSourceFiles()
+{
+    d->scripts(4, QList<int>(), true, QVariant());
+}
+
 void QmlV8DebuggerClient::messageReceived(const QByteArray &data)
 {
     QDataStream ds(data);
@@ -1305,6 +1321,53 @@ void QmlV8DebuggerClient::messageReceived(const QByteArray &data)
                 } else if (debugCommand == _(SCOPES)) {
                 } else if (debugCommand == _(SOURCE)) {
                 } else if (debugCommand == _(SCRIPTS)) {
+                    //                { "seq"         : <number>,
+                    //                  "type"        : "response",
+                    //                  "request_seq" : <number>,
+                    //                  "command"     : "scripts",
+                    //                  "body"        : [ { "name"             : <name of the script>,
+                    //                                      "id"               : <id of the script>
+                    //                                      "lineOffset"       : <line offset within the containing resource>
+                    //                                      "columnOffset"     : <column offset within the containing resource>
+                    //                                      "lineCount"        : <number of lines in the script>
+                    //                                      "data"             : <optional data object added through the API>
+                    //                                      "source"           : <source of the script if includeSource was specified in the request>
+                    //                                      "sourceStart"      : <first 80 characters of the script if includeSource was not specified in the request>
+                    //                                      "sourceLength"     : <total length of the script in characters>
+                    //                                      "scriptType"       : <script type (see request for values)>
+                    //                                      "compilationType"  : < How was this script compiled:
+                    //                                                               0 if script was compiled through the API
+                    //                                                               1 if script was compiled through eval
+                    //                                                            >
+                    //                                      "evalFromScript"   : <if "compilationType" is 1 this is the script from where eval was called>
+                    //                                      "evalFromLocation" : { line   : < if "compilationType" is 1 this is the line in the script from where eval was called>
+                    //                                                             column : < if "compilationType" is 1 this is the column in the script from where eval was called>
+                    //                                  ]
+                    //                  "running"     : <is the VM running after sending this response>
+                    //                  "success"     : true
+                    //                }
+
+                    if (success) {
+                        const QVariantList body = resp.value(_(BODY)).toList();
+
+                        QStringList sourceFiles;
+                        for (int i = 0; i < body.size(); ++i) {
+                            const QVariantMap entryMap = body.at(i).toMap();
+                            const int lineOffset = entryMap.value("lineOffset").toInt();
+                            const int columnOffset = entryMap.value("columnOffset").toInt();
+                            const QString name = entryMap.value("name").toString();
+                            const QString source = entryMap.value("source").toString();
+
+                            if (name.isEmpty())
+                                continue;
+
+                            if (!sourceFiles.contains(name))
+                                sourceFiles << name;
+
+                            d->engine->updateScriptSource(name, lineOffset, columnOffset, source);
+                        }
+                        d->engine->setSourceFiles(sourceFiles);
+                    }
                 } else if (debugCommand == _(VERSION)) {
                     d->logReceiveMessage(QString(_("Using V8 Version: %1")).arg(
                                              resp.value(_(BODY)).toMap().
diff --git a/src/plugins/debugger/qml/qmlv8debuggerclient.h b/src/plugins/debugger/qml/qmlv8debuggerclient.h
index 1f8cec0271d34a46003e65ebfa3ebd224b066b8d..944f1cda986ad902f8f92f80e52d46a56e44d3a3 100644
--- a/src/plugins/debugger/qml/qmlv8debuggerclient.h
+++ b/src/plugins/debugger/qml/qmlv8debuggerclient.h
@@ -96,6 +96,8 @@ public:
 
     void setEngine(QmlEngine *engine);
 
+    void getSourceFiles();
+
 protected:
     void messageReceived(const QByteArray &data);