From f3c047a33c84ac5ba24cbaf594f04ba95977cb97 Mon Sep 17 00:00:00 2001
From: Aurindam Jana <aurindam.jana@nokia.com>
Date: Wed, 26 Oct 2011 10:02:37 +0200
Subject: [PATCH] QmlV8DebuggerClient: Refactored code

Change List:
a) Refactored code: Shifted JSON message creation to
QmlV8DebuggerClientPrivate.
b) QScriptEngine is used for JSON instead of JsonValue and
JsonInputStream.
c) Locals Window displays all variables accessible in the current
context.

Change-Id: I82e73f6c57482408f5fc501c908aa96297d3d754
Reviewed-by: Kai Koehne <kai.koehne@nokia.com>
---
 src/libs/symbianutils/symbianutils.pri        |    2 +-
 src/libs/symbianutils/symbianutils.pro        |    2 +-
 src/plugins/debugger/qml/qml.pri              |    5 +-
 src/plugins/debugger/qml/qmldebuggerclient.h  |    4 +-
 src/plugins/debugger/qml/qmlengine.cpp        |    6 +-
 .../debugger/qml/qmlv8debuggerclient.cpp      | 1698 ++++++++++++-----
 .../debugger/qml/qmlv8debuggerclient.h        |   39 +-
 .../qml/qmlv8debuggerclientconstants.h        |  121 ++
 .../debugger/qml/qscriptdebuggerclient.cpp    |    6 +-
 .../debugger/qml/qscriptdebuggerclient.h      |    7 +-
 10 files changed, 1392 insertions(+), 498 deletions(-)
 create mode 100644 src/plugins/debugger/qml/qmlv8debuggerclientconstants.h

diff --git a/src/libs/symbianutils/symbianutils.pri b/src/libs/symbianutils/symbianutils.pri
index 978aabebdb4..e6b59799fde 100644
--- a/src/libs/symbianutils/symbianutils.pri
+++ b/src/libs/symbianutils/symbianutils.pri
@@ -1,2 +1,2 @@
-INCLUDEPATH *= $$PWD/../../shared/symbianutils
+INCLUDEPATH *= $$PWD/../../shared/symbianutils $$PWD/../../shared/json
 LIBS *= -l$$qtLibraryName(symbianutils)
diff --git a/src/libs/symbianutils/symbianutils.pro b/src/libs/symbianutils/symbianutils.pro
index 3ae094e9d7a..ed2ff004eb8 100644
--- a/src/libs/symbianutils/symbianutils.pro
+++ b/src/libs/symbianutils/symbianutils.pro
@@ -1,6 +1,6 @@
 TEMPLATE = lib
 CONFIG+=dll
 TARGET = symbianutils
-DEFINES += SYMBIANUTILS_BUILD_LIB
+DEFINES += SYMBIANUTILS_BUILD_LIB JSON_BUILD_LIB
 include(../../qtcreatorlibrary.pri)
 include(../../shared/symbianutils/symbianutils.pri)
diff --git a/src/plugins/debugger/qml/qml.pri b/src/plugins/debugger/qml/qml.pri
index c70ce3ea11e..a34c120add6 100644
--- a/src/plugins/debugger/qml/qml.pri
+++ b/src/plugins/debugger/qml/qml.pri
@@ -1,6 +1,4 @@
 include($$PWD/../../../libs/qmljsdebugclient/qmljsdebugclient.pri)
-include($$PWD/../../../shared/json/json.pri)
-DEFINES += JSON_INCLUDE_PRI
 
 HEADERS += \
     $$PWD/qmlengine.h \
@@ -11,7 +9,8 @@ HEADERS += \
     $$PWD/qmljsscriptconsole.h \
     $$PWD/qscriptdebuggerclient.h \
     $$PWD/qmlv8debuggerclient.h \
-    $$PWD/interactiveinterpreter.h
+    $$PWD/interactiveinterpreter.h \
+    $$PWD/qmlv8debuggerclientconstants.h
 
 SOURCES += \
     $$PWD/qmlengine.cpp \
diff --git a/src/plugins/debugger/qml/qmldebuggerclient.h b/src/plugins/debugger/qml/qmldebuggerclient.h
index 26fd33c53aa..2333e9ac87c 100644
--- a/src/plugins/debugger/qml/qmldebuggerclient.h
+++ b/src/plugins/debugger/qml/qmldebuggerclient.h
@@ -69,12 +69,12 @@ public:
     virtual void insertBreakpoint(const BreakpointModelId &id) = 0;
     virtual void removeBreakpoint(const BreakpointModelId &id) = 0;
     virtual void changeBreakpoint(const BreakpointModelId &id) = 0;
-    virtual void updateBreakpoints() = 0;
+    virtual void synchronizeBreakpoints() = 0;
 
     virtual void assignValueInDebugger(const QByteArray expr, const quint64 &id,
                                        const QString &property, const QString &value) = 0;
 
-    virtual void updateWatchData(const WatchData *data) = 0;
+    virtual void updateWatchData(const WatchData &data) = 0;
     virtual void executeDebuggerCommand(const QString &command) = 0;
 
     virtual void synchronizeWatchers(const QStringList &watchers) = 0;
diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp
index 9023f002341..6bfb054c9c3 100644
--- a/src/plugins/debugger/qml/qmlengine.cpp
+++ b/src/plugins/debugger/qml/qmlengine.cpp
@@ -629,10 +629,10 @@ void QmlEngine::attemptBreakpointSynchronization()
     DebuggerEngine::attemptBreakpointSynchronization();
 
     if (d->m_adapter.activeDebuggerClient()) {
-        d->m_adapter.activeDebuggerClient()->updateBreakpoints();
+        d->m_adapter.activeDebuggerClient()->synchronizeBreakpoints();
     } else {
         foreach (QmlDebuggerClient *client, d->m_adapter.debuggerClients()) {
-            client->updateBreakpoints();
+            client->synchronizeBreakpoints();
         }
     }
 }
@@ -715,7 +715,7 @@ void QmlEngine::updateWatchData(const WatchData &data,
         if (data.isValueNeeded()) {
             logMessage(LogSend, QString("%1 %2 %3").arg(QString("EXEC"), QString(data.iname),
                                                         QString(data.name)));
-            d->m_adapter.activeDebuggerClient()->updateWatchData(&data);
+            d->m_adapter.activeDebuggerClient()->updateWatchData(data);
         }
         if (data.isChildrenNeeded()
                 && watchHandler()->isExpandedIName(data.iname)) {
diff --git a/src/plugins/debugger/qml/qmlv8debuggerclient.cpp b/src/plugins/debugger/qml/qmlv8debuggerclient.cpp
index 33d4353d414..8dc6182714b 100644
--- a/src/plugins/debugger/qml/qmlv8debuggerclient.cpp
+++ b/src/plugins/debugger/qml/qmlv8debuggerclient.cpp
@@ -31,19 +31,16 @@
 **************************************************************************/
 
 #include "qmlv8debuggerclient.h"
+#include "qmlv8debuggerclientconstants.h"
+#include "debuggerstringutils.h"
 
-#include "watchdata.h"
 #include "watchhandler.h"
 #include "breakpoint.h"
 #include "breakhandler.h"
-#include "debuggerconstants.h"
 #include "qmlengine.h"
 #include "stackhandler.h"
-#include "debuggercore.h"
 
-#include <extensionsystem/pluginmanager.h>
 #include <utils/qtcassert.h>
-
 #include <coreplugin/editormanager/editormanager.h>
 #include <texteditor/basetexteditor.h>
 
@@ -51,261 +48,859 @@
 #include <QtCore/QVariant>
 #include <QtCore/QFileInfo>
 #include <QtGui/QTextDocument>
-#include <QtGui/QMessageBox>
+#include <QtScript/QScriptEngine>
+#include <QtScript/QScriptValue>
 
-#define INITIALPARAMS "seq" << ':' << ++d->sequence << ',' << "type" << ':' << "request"
+#define DEBUG_QML 0
+#if DEBUG_QML
+#   define SDEBUG(s) qDebug() << s
+#else
+#   define SDEBUG(s)
+#endif
 
 using namespace Core;
-using namespace Json;
 
 namespace Debugger {
 namespace Internal {
 
-struct ExceptionInfo
-{
-    int sourceLine;
-    QString filePath;
-    QString errorMessage;
+typedef QPair<QByteArray, QByteArray> WatchDataPair;
+
+struct QmlV8ObjectData {
+    QByteArray type;
+    QVariant value;
+    QVariant properties;
 };
 
 class QmlV8DebuggerClientPrivate
 {
 public:
-    explicit QmlV8DebuggerClientPrivate(QmlV8DebuggerClient *) :
-        handleException(false),
-        sequence(0),
-        ping(0),
+    explicit QmlV8DebuggerClientPrivate(QmlV8DebuggerClient *q) :
+        q(q),
+        sequence(-1),
         engine(0)
     {
+        q->reset();
+        parser = m_scriptEngine.evaluate(_("JSON.parse"));
+        stringifier = m_scriptEngine.evaluate(_("JSON.stringify"));
     }
 
-    bool handleException;
+    void connect();
+    void disconnect();
+
+    void interrupt();
+    void continueDebugging(QmlV8DebuggerClient::StepAction stepAction, int stepCount = 1);
+
+    void evaluate(const QString expr, bool global = false, bool disableBreak = false,
+                  int frame = -1, bool addContext = false);
+    void lookup(const QList<int> handles, bool includeSource = false);
+    void backtrace(int fromFrame = -1, int toFrame = -1, bool bottom = false);
+    void frame(int number = -1);
+    void scope(int number = -1, int frameNumber = -1);
+    void scopes(int frameNumber = -1);
+    void scripts(int types = 4, const QList<int> ids = QList<int>(),
+                 bool includeSource = false, const QVariant filter = QVariant());
+    void source(int frame = -1, int fromLine = -1, int toLine = -1);
+
+    void setBreakpoint(const QString type, const QString target, int line = -1,
+                       int column = -1, bool enabled = true,
+                       const QString condition = QString(), int ignoreCount = -1);
+    void changeBreakpoint(int breakpoint, bool enabled = true,
+                          const QString condition = QString(), int ignoreCount = -1);
+    void clearBreakpoint(int breakpoint);
+    void setExceptionBreak(QmlV8DebuggerClient::Exceptions type, bool enabled = false);
+    void listBreakpoints();
+
+    void v8flags(const QString flags);
+    void version();
+    //void profile(ProfileCommand command); //NOT SUPPORTED
+    void gc();
+
+    QmlV8ObjectData extractData(const QVariant &data);
+
+private:
+    QByteArray packMessage(const QByteArray &message);
+    QScriptValue initObject();
+
+public:
+    QmlV8DebuggerClient *q;
+
     int sequence;
-    int ping;
     QmlEngine *engine;
-    QHash<BreakpointModelId,int> breakpoints;
-    QHash<int,BreakpointModelId> breakpointsSync;
-    QHash<int,QByteArray> locals;
-    QHash<int,QByteArray> watches;
-    QByteArray frames;
-    QScopedPointer<ExceptionInfo> exceptionInfo;
+    QHash<BreakpointModelId, int> breakpoints;
+    QHash<int, BreakpointModelId> breakpointsSync;
+    QHash<int, QByteArray> locals;
+    QHash<int, WatchDataPair> watches;
+
+    QScriptValue parser;
+    QScriptValue stringifier;
+
+    int currentFrameIndex;
+    bool updateCurrentStackFrameIndex;
+private:
+    QScriptEngine m_scriptEngine;
 };
 
-QmlV8DebuggerClient::QmlV8DebuggerClient(QmlJsDebugClient::QDeclarativeDebugConnection* client)
-    : QmlDebuggerClient(client, QLatin1String("V8Debugger")),
-      d(new QmlV8DebuggerClientPrivate(this))
+///////////////////////////////////////////////////////////////////////
+//
+// QmlV8DebuggerClientPrivate
+//
+///////////////////////////////////////////////////////////////////////
+
+void QmlV8DebuggerClientPrivate::connect()
 {
+    //    { "seq"     : <number>,
+    //      "type"    : "request",
+    //      "command" : "connect",
+    //    }
+    QScriptValue jsonVal = initObject();
+    jsonVal.setProperty(_(COMMAND), QScriptValue(_(CONNECT)));
+
+    const QScriptValue jsonMessage = stringifier.call(QScriptValue(), QScriptValueList() << jsonVal);
+    q->sendMessage(packMessage(jsonMessage.toString().toUtf8()));
 }
 
-QmlV8DebuggerClient::~QmlV8DebuggerClient()
+void QmlV8DebuggerClientPrivate::disconnect()
 {
-    delete d;
+    //    { "seq"     : <number>,
+    //      "type"    : "request",
+    //      "command" : "disconnect",
+    //    }
+    QScriptValue jsonVal = initObject();
+    jsonVal.setProperty(_(COMMAND), QScriptValue(_(DISCONNECT)));
+
+    const QScriptValue jsonMessage = stringifier.call(QScriptValue(), QScriptValueList() << jsonVal);
+    q->sendMessage(packMessage(jsonMessage.toString().toUtf8()));
 }
 
-QByteArray QmlV8DebuggerClient::packMessage(const QByteArray &message)
+void QmlV8DebuggerClientPrivate::interrupt()
 {
-    QByteArray reply;
-    QDataStream rs(&reply, QIODevice::WriteOnly);
-    QByteArray cmd = "V8DEBUG";
-    rs << cmd << message;
-    return reply;
+    //    { "seq"     : <number>,
+    //      "type"    : "request",
+    //      "command" : "interrupt",
+    //    }
+    QScriptValue jsonVal = initObject();
+    jsonVal.setProperty(_(COMMAND), QScriptValue(_(INTERRUPT)));
+
+    const QScriptValue jsonMessage = stringifier.call(QScriptValue(), QScriptValueList() << jsonVal);
+    q->sendMessage(packMessage(jsonMessage.toString().toUtf8()));
 }
 
-void QmlV8DebuggerClient::breakOnException(Exceptions exceptionsType, bool enabled)
+void QmlV8DebuggerClientPrivate::continueDebugging(QmlV8DebuggerClient::StepAction action,
+                                                   int count)
 {
-    //TODO: Have to deal with NoExceptions
-    QByteArray request;
-
-    JsonInputStream(request) << '{' << INITIALPARAMS ;
-    JsonInputStream(request) << ',' << "command" << ':' << "setexceptionbreak";
+    //First reset
+    q->reset();
+
+    //    { "seq"       : <number>,
+    //      "type"      : "request",
+    //      "command"   : "continue",
+    //      "arguments" : { "stepaction" : <"in", "next" or "out">,
+    //                      "stepcount"  : <number of steps (default 1)>
+    //                    }
+    //    }
+    QScriptValue jsonVal = initObject();
+    jsonVal.setProperty(_(COMMAND),
+                        QScriptValue(_(CONTINEDEBUGGING)));
+
+    if (action != QmlV8DebuggerClient::Continue) {
+        QScriptValue args = parser.call(QScriptValue(), QScriptValueList() << QScriptValue(_(OBJECT)));
+        switch (action) {
+        case QmlV8DebuggerClient::In:
+            args.setProperty(_(STEPACTION), QScriptValue(_(IN)));
+            break;
+        case QmlV8DebuggerClient::Out:
+            args.setProperty(_(STEPACTION), QScriptValue(_(OUT)));
+            break;
+        case QmlV8DebuggerClient::Next:
+            args.setProperty(_(STEPACTION), QScriptValue(_(NEXT)));
+            break;
+        default:break;
+        }
+        if (count != 1)
+            args.setProperty(_(STEPCOUNT), QScriptValue(count));
+        jsonVal.setProperty(_(ARGUMENTS), args);
 
-    JsonInputStream(request) << ',' << "arguments" << ':';
-    if (exceptionsType == AllExceptions)
-        JsonInputStream(request) << '{' << "type" << ':' << "all";
-    else if (exceptionsType == UncaughtExceptions)
-        JsonInputStream(request) << '{' << "type" << ':' << "uncaught";
+    }
+    const QScriptValue jsonMessage = stringifier.call(QScriptValue(), QScriptValueList() << jsonVal);
+    q->sendMessage(packMessage(jsonMessage.toString().toUtf8()));
+}
 
-    JsonInputStream(request) << ',' << "enabled" << ':' << enabled;
-    JsonInputStream(request) << '}';
+void QmlV8DebuggerClientPrivate::evaluate(const QString expr, bool global,
+                                          bool disableBreak, int frame,
+                                          bool addContext)
+{
+    updateCurrentStackFrameIndex = false;
+
+    //    { "seq"       : <number>,
+    //      "type"      : "request",
+    //      "command"   : "evaluate",
+    //      "arguments" : { "expression"    : <expression to evaluate>,
+    //                      "frame"         : <number>,
+    //                      "global"        : <boolean>,
+    //                      "disable_break" : <boolean>,
+    //                      "additional_context" : [
+    //                           { "name" : <name1>, "handle" : <handle1> },
+    //                           { "name" : <name2>, "handle" : <handle2> },
+    //                           ...
+    //                      ]
+    //                    }
+    //    }
+    QScriptValue jsonVal = initObject();
+    jsonVal.setProperty(_(COMMAND), QScriptValue(_(EVALUATE)));
+
+    QScriptValue args = parser.call(QScriptValue(), QScriptValueList() << QScriptValue(_(OBJECT)));
+    args.setProperty(_(EXPRESSION), QScriptValue(expr));
+
+    if (frame != -1)
+        args.setProperty(_(FRAME), QScriptValue(frame));
+
+    if (global)
+        args.setProperty(_(GLOBAL), QScriptValue(global));
+
+    if (disableBreak)
+        args.setProperty(_(DISABLE_BREAK), QScriptValue(disableBreak));
+
+    if (addContext) {
+        QAbstractItemModel *localsModel = engine->localsModel();
+        int rowCount = localsModel->rowCount();
+
+        QScriptValue ctxtList = parser.call(QScriptValue(), QScriptValueList() << _(ARRAY  ));
+        while (rowCount) {
+            QModelIndex index = localsModel->index(--rowCount, 0);
+            const WatchData *data = engine->watchHandler()->watchData(LocalsWatch, index);
+            QScriptValue ctxt = parser.call(QScriptValue(), QScriptValueList() << QScriptValue(_(OBJECT)));
+            ctxt.setProperty(_(NAME), QScriptValue(data->name));
+            ctxt.setProperty(_(HANDLE), QScriptValue(int(data->id)));
+
+            ctxtList.setProperty(rowCount, ctxt);
+        }
 
-    JsonInputStream(request) << '}';
+        args.setProperty(_(ADDITIONAL_CONTEXT), QScriptValue(ctxtList));
+    }
 
+    jsonVal.setProperty(_(ARGUMENTS), args);
 
-    sendMessage(packMessage(request));
+    const QScriptValue jsonMessage = stringifier.call(QScriptValue(), QScriptValueList() << jsonVal);
+    q->sendMessage(packMessage(jsonMessage.toString().toUtf8()));
 }
 
-void QmlV8DebuggerClient::storeExceptionInformation(const QByteArray &message)
+void QmlV8DebuggerClientPrivate::lookup(QList<int> handles, bool includeSource)
 {
-    JsonValue response(message);
+    //    { "seq"       : <number>,
+    //      "type"      : "request",
+    //      "command"   : "lookup",
+    //      "arguments" : { "handles"       : <array of handles>,
+    //                      "includeSource" : <boolean indicating whether
+    //                                          the source will be included when
+    //                                          script objects are returned>,
+    //                    }
+    //    }
+    QScriptValue jsonVal = initObject();
+    jsonVal.setProperty(_(COMMAND), QScriptValue(_(LOOKUP)));
+
+    QScriptValue args = parser.call(QScriptValue(), QScriptValueList() << QScriptValue(_(OBJECT)));
+
+    QScriptValue array = parser.call(QScriptValue(), QScriptValueList() << _(ARRAY));
+    int index = 0;
+    foreach (int handle, handles) {
+        array.setProperty(index++, QScriptValue(handle));
+    }
+    args.setProperty(_(HANDLES), array);
+
+    if (includeSource)
+        args.setProperty(_(INCLUDESOURCE), QScriptValue(includeSource));
 
-    JsonValue body = response.findChild("body");
+    jsonVal.setProperty(_(ARGUMENTS), args);
 
-    d->exceptionInfo.reset(new ExceptionInfo);
-    d->exceptionInfo->sourceLine = body.findChild("sourceLine").toVariant().toInt();
-    QUrl fileUrl(body.findChild("script").findChild("name").toVariant().toString());
-    d->exceptionInfo->filePath = d->engine->toFileInProject(fileUrl);
-    d->exceptionInfo->errorMessage = body.findChild("exception").findChild("text").toVariant().toString();
+    const QScriptValue jsonMessage = stringifier.call(QScriptValue(), QScriptValueList() << jsonVal);
+    q->sendMessage(packMessage(jsonMessage.toString().toUtf8()));
 }
 
-void QmlV8DebuggerClient::handleException()
+void QmlV8DebuggerClientPrivate::backtrace(int fromFrame, int toFrame, bool bottom)
 {
-    EditorManager *editorManager = EditorManager::instance();
-    QList<IEditor *> openedEditors = editorManager->openedEditors();
+    //    { "seq"       : <number>,
+    //      "type"      : "request",
+    //      "command"   : "backtrace",
+    //      "arguments" : { "fromFrame" : <number>
+    //                      "toFrame" : <number>
+    //                      "bottom" : <boolean, set to true if the bottom of the
+    //                          stack is requested>
+    //                    }
+    //    }
+    QScriptValue jsonVal = initObject();
+    jsonVal.setProperty(_(COMMAND), QScriptValue(_(BACKTRACE)));
 
-    // set up the format for the errors
-    QTextCharFormat errorFormat;
-    errorFormat.setUnderlineStyle(QTextCharFormat::WaveUnderline);
-    errorFormat.setUnderlineColor(Qt::red);
+    QScriptValue args = parser.call(QScriptValue(), QScriptValueList() << QScriptValue(_(OBJECT)));
 
-    foreach (IEditor *editor, openedEditors) {
-        if (editor->file()->fileName() == d->exceptionInfo->filePath) {
-            TextEditor::BaseTextEditorWidget *ed = qobject_cast<TextEditor::BaseTextEditorWidget *>(editor->widget());
-            if (!ed)
-                continue;
+    if (fromFrame != -1)
+        args.setProperty(_(FROMFRAME), QScriptValue(fromFrame));
 
-            QList<QTextEdit::ExtraSelection> selections;
-            QTextEdit::ExtraSelection sel;
-            sel.format = errorFormat;
-            QTextCursor c(ed->document()->findBlockByNumber(d->exceptionInfo->sourceLine));
-            const QString text = c.block().text();
-            for (int i = 0; i < text.size(); ++i) {
-                if (! text.at(i).isSpace()) {
-                    c.setPosition(c.position() + i);
-                    break;
-                }
-            }
-            c.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
-            sel.cursor = c;
+    if (toFrame != -1)
+        args.setProperty(_(TOFRAME), QScriptValue(toFrame));
 
-            sel.format.setToolTip(d->exceptionInfo->errorMessage);
+    if (bottom)
+        args.setProperty(_(BOTTOM), QScriptValue(bottom));
 
-            selections.append(sel);
-            ed->setExtraSelections(TextEditor::BaseTextEditorWidget::DebuggerExceptionSelection, selections);
+    jsonVal.setProperty(_(ARGUMENTS), args);
 
-            d->engine->showMessage(d->exceptionInfo->errorMessage, ScriptConsoleOutput);
-        }
+    const QScriptValue jsonMessage = stringifier.call(QScriptValue(), QScriptValueList() << jsonVal);
+    q->sendMessage(packMessage(jsonMessage.toString().toUtf8()));
+}
+
+void QmlV8DebuggerClientPrivate::frame(int number)
+{
+    //    { "seq"       : <number>,
+    //      "type"      : "request",
+    //      "command"   : "frame",
+    //      "arguments" : { "number" : <frame number>
+    //                    }
+    //    }
+    QScriptValue jsonVal = initObject();
+    jsonVal.setProperty(_(COMMAND), QScriptValue(_(FRAME)));
+
+    if (number != -1) {
+        QScriptValue args = parser.call(QScriptValue(), QScriptValueList() << QScriptValue(_(OBJECT)));
+        args.setProperty(_(NUMBER), QScriptValue(number));
+
+        jsonVal.setProperty(_(ARGUMENTS), args);
     }
 
-    //Delete the info even if the code hasnt been highlighted
-    d->exceptionInfo.reset();
+    const QScriptValue jsonMessage = stringifier.call(QScriptValue(), QScriptValueList() << jsonVal);
+    q->sendMessage(packMessage(jsonMessage.toString().toUtf8()));
 }
 
-void QmlV8DebuggerClient::clearExceptionSelection()
+void QmlV8DebuggerClientPrivate::scope(int number, int frameNumber)
 {
-    //Check if break was due to exception
-    if (d->handleException) {
-        EditorManager *editorManager = EditorManager::instance();
-        QList<IEditor *> openedEditors = editorManager->openedEditors();
-        QList<QTextEdit::ExtraSelection> selections;
+    //    { "seq"       : <number>,
+    //      "type"      : "request",
+    //      "command"   : "scope",
+    //      "arguments" : { "number" : <scope number>
+    //                      "frameNumber" : <frame number, optional uses selected
+    //                                      frame if missing>
+    //                    }
+    //    }
+    QScriptValue jsonVal = initObject();
+    jsonVal.setProperty(_(COMMAND), QScriptValue(_(SCOPE)));
+
+    if (number != -1) {
+        QScriptValue args = parser.call(QScriptValue(), QScriptValueList() << QScriptValue(_(OBJECT)));
+        args.setProperty(_(NUMBER), QScriptValue(number));
+
+        if (frameNumber != -1)
+            args.setProperty(_(FRAMENUMBER), QScriptValue(frameNumber));
+
+        jsonVal.setProperty(_(ARGUMENTS), args);
+    }
 
-        foreach (IEditor *editor, openedEditors) {
-            TextEditor::BaseTextEditorWidget *ed = qobject_cast<TextEditor::BaseTextEditorWidget *>(editor->widget());
-            if (!ed)
-                continue;
+    const QScriptValue jsonMessage = stringifier.call(QScriptValue(), QScriptValueList() << jsonVal);
+    q->sendMessage(packMessage(jsonMessage.toString().toUtf8()));
+}
 
-            ed->setExtraSelections(TextEditor::BaseTextEditorWidget::DebuggerExceptionSelection, selections);
+void QmlV8DebuggerClientPrivate::scopes(int frameNumber)
+{
+    //    { "seq"       : <number>,
+    //      "type"      : "request",
+    //      "command"   : "scopes",
+    //      "arguments" : { "frameNumber" : <frame number, optional uses selected
+    //                                      frame if missing>
+    //                    }
+    //    }
+    QScriptValue jsonVal = initObject();
+    jsonVal.setProperty(_(COMMAND), QScriptValue(_(SCOPES)));
+
+    if (frameNumber != -1) {
+        QScriptValue args = parser.call(QScriptValue(), QScriptValueList() << QScriptValue(_(OBJECT)));
+        args.setProperty(_(FRAMENUMBER), QScriptValue(frameNumber));
+
+        jsonVal.setProperty(_(ARGUMENTS), args);
+    }
+
+    const QScriptValue jsonMessage = stringifier.call(QScriptValue(), QScriptValueList() << jsonVal);
+    q->sendMessage(packMessage(jsonMessage.toString().toUtf8()));
+}
+
+void QmlV8DebuggerClientPrivate::scripts(int types, const QList<int> ids, bool includeSource,
+                                         const QVariant /*filter*/)
+{
+    //    { "seq"       : <number>,
+    //      "type"      : "request",
+    //      "command"   : "scripts",
+    //      "arguments" : { "types"         : <types of scripts to retrieve
+    //                                           set bit 0 for native scripts
+    //                                           set bit 1 for extension scripts
+    //                                           set bit 2 for normal scripts
+    //                                         (default is 4 for normal scripts)>
+    //                      "ids"           : <array of id's of scripts to return. If this is not specified all scripts are requrned>
+    //                      "includeSource" : <boolean indicating whether the source code should be included for the scripts returned>
+    //                      "filter"        : <string or number: filter string or script id.
+    //                                         If a number is specified, then only the script with the same number as its script id will be retrieved.
+    //                                         If a string is specified, then only scripts whose names contain the filter string will be retrieved.>
+    //                    }
+    //    }
+    QScriptValue jsonVal = initObject();
+    jsonVal.setProperty(_(COMMAND), QScriptValue(_(SCRIPTS)));
+
+    QScriptValue args = parser.call(QScriptValue(), QScriptValueList() << QScriptValue(_(OBJECT)));
+    args.setProperty(_(TYPES), QScriptValue(types));
+
+    if (ids.count()) {
+        QScriptValue array = parser.call(QScriptValue(), QScriptValueList() << _(ARRAY));
+        int index = 0;
+        foreach (int id, ids) {
+            array.setProperty(index++, QScriptValue(id));
         }
-        d->handleException = false;
+        args.setProperty(_(IDS), array);
     }
+
+    if (includeSource)
+        args.setProperty(_(INCLUDESOURCE), QScriptValue(includeSource));
+
+    jsonVal.setProperty(_(ARGUMENTS), args);
+
+    const QScriptValue jsonMessage = stringifier.call(QScriptValue(), QScriptValueList() << jsonVal);
+    q->sendMessage(packMessage(jsonMessage.toString().toUtf8()));
 }
 
-void QmlV8DebuggerClient::continueDebugging(StepAction type)
+void QmlV8DebuggerClientPrivate::source(int frame, int fromLine, int toLine)
 {
-    clearExceptionSelection();
+    //    { "seq"       : <number>,
+    //      "type"      : "request",
+    //      "command"   : "source",
+    //      "arguments" : { "frame"    : <frame number (default selected frame)>
+    //                      "fromLine" : <from line within the source default is line 0>
+    //                      "toLine"   : <to line within the source this line is not included in
+    //                                    the result default is the number of lines in the script>
+    //                    }
+    //    }
+    QScriptValue jsonVal = initObject();
+    jsonVal.setProperty(_(COMMAND), QScriptValue(_(SOURCE)));
 
-    QByteArray request;
+    QScriptValue args = parser.call(QScriptValue(), QScriptValueList() << QScriptValue(_(OBJECT)));
 
-    JsonInputStream(request) << '{' << INITIALPARAMS ;
-    JsonInputStream(request) << ',' << "command" << ':' << "continue";
+    if (frame != -1)
+        args.setProperty(_(FRAME), QScriptValue(frame));
 
-    if (type != Continue) {
-        JsonInputStream(request) << ',' << "arguments" << ':';
+    if (fromLine != -1)
+        args.setProperty(_(FROMLINE), QScriptValue(fromLine));
 
-        switch (type) {
-        case In: JsonInputStream(request) << '{' << "stepaction" << ':' << "in";
-            break;
-        case Out: JsonInputStream(request) << '{' << "stepaction" << ':' << "out";
-            break;
-        case Next: JsonInputStream(request) << '{' << "stepaction" << ':' << "next";
-            break;
-        default:break;
-        }
+    if (toLine != -1)
+        args.setProperty(_(TOLINE), QScriptValue(toLine));
 
-        JsonInputStream(request) << '}';
-    }
+    jsonVal.setProperty(_(ARGUMENTS), args);
 
-    JsonInputStream(request) << '}';
+    const QScriptValue jsonMessage = stringifier.call(QScriptValue(), QScriptValueList() << jsonVal);
+    q->sendMessage(packMessage(jsonMessage.toString().toUtf8()));
+}
 
-    sendMessage(packMessage(request));
+void QmlV8DebuggerClientPrivate::setBreakpoint(const QString type, const QString target,
+                                               int line, int column, bool enabled,
+                                               const QString condition, int ignoreCount)
+{
+    //    { "seq"       : <number>,
+    //      "type"      : "request",
+    //      "command"   : "setbreakpoint",
+    //      "arguments" : { "type"        : <"function" or "script" or "scriptId" or "scriptRegExp">
+    //                      "target"      : <function expression or script identification>
+    //                      "line"        : <line in script or function>
+    //                      "column"      : <character position within the line>
+    //                      "enabled"     : <initial enabled state. True or false, default is true>
+    //                      "condition"   : <string with break point condition>
+    //                      "ignoreCount" : <number specifying the number of break point hits to ignore, default value is 0>
+    //                    }
+    //    }
+    QScriptValue jsonVal = initObject();
+    jsonVal.setProperty(_(COMMAND), QScriptValue(_(SETBREAKPOINT)));
+
+    QScriptValue args = parser.call(QScriptValue(), QScriptValueList() << QScriptValue(_(OBJECT)));
+
+    args.setProperty(_(TYPE), QScriptValue(type));
+    args.setProperty(_(TARGET), QScriptValue(target));
+
+    if (line != -1)
+        args.setProperty(_(LINE), QScriptValue(line));
+
+    if (column != -1)
+        args.setProperty(_(COLUMN), QScriptValue(column));
+
+    args.setProperty(_(ENABLED), QScriptValue(enabled));
+
+    if (!condition.isEmpty())
+        args.setProperty(_(CONDITION), QScriptValue(condition));
+
+    if (ignoreCount != -1)
+        args.setProperty(_(IGNORECOUNT), QScriptValue(ignoreCount));
+
+    jsonVal.setProperty(_(ARGUMENTS), args);
+
+    const QScriptValue jsonMessage = stringifier.call(QScriptValue(), QScriptValueList() << jsonVal);
+    q->sendMessage(packMessage(jsonMessage.toString().toUtf8()));
 }
 
-void QmlV8DebuggerClient::executeStep()
+void QmlV8DebuggerClientPrivate::changeBreakpoint(int breakpoint, bool enabled,
+                                                  const QString condition, int ignoreCount)
 {
-    continueDebugging(In);
+    //    { "seq"       : <number>,
+    //      "type"      : "request",
+    //      "command"   : "changebreakpoint",
+    //      "arguments" : { "breakpoint"  : <number of the break point to clear>
+    //                      "enabled"     : <initial enabled state. True or false,
+    //                                      default is true>
+    //                      "condition"   : <string with break point condition>
+    //                      "ignoreCount" : <number specifying the number of break point hits            }
+    //    }
+    QScriptValue jsonVal = initObject();
+    jsonVal.setProperty(_(COMMAND),
+                        QScriptValue(_(CHANGEBREAKPOINT)));
+
+    QScriptValue args = parser.call(QScriptValue(), QScriptValueList() << QScriptValue(_(OBJECT)));
+
+    args.setProperty(_(BREAKPOINT), QScriptValue(breakpoint));
+
+    args.setProperty(_(ENABLED), QScriptValue(enabled));
+
+    if (!condition.isEmpty())
+        args.setProperty(_(CONDITION), QScriptValue(condition));
+
+    if (ignoreCount != -1)
+        args.setProperty(_(IGNORECOUNT), QScriptValue(ignoreCount));
+
+    jsonVal.setProperty(_(ARGUMENTS), args);
+
+    const QScriptValue jsonMessage = stringifier.call(QScriptValue(), QScriptValueList() << jsonVal);
+    q->sendMessage(packMessage(jsonMessage.toString().toUtf8()));
 }
 
-void QmlV8DebuggerClient::executeStepOut()
+void QmlV8DebuggerClientPrivate::clearBreakpoint(int breakpoint)
+{
+    //    { "seq"       : <number>,
+    //      "type"      : "request",
+    //      "command"   : "clearbreakpoint",
+    //      "arguments" : { "breakpoint" : <number of the break point to clear>
+    //                    }
+    //    }
+    QScriptValue jsonVal = initObject();
+    jsonVal.setProperty(_(COMMAND),
+                        QScriptValue(_(CLEARBREAKPOINT)));
+
+    QScriptValue args = parser.call(QScriptValue(), QScriptValueList() << QScriptValue(_(OBJECT)));
+
+    args.setProperty(_(BREAKPOINT), QScriptValue(breakpoint));
+
+    jsonVal.setProperty(_(ARGUMENTS), args);
+
+    const QScriptValue jsonMessage = stringifier.call(QScriptValue(), QScriptValueList() << jsonVal);
+    q->sendMessage(packMessage(jsonMessage.toString().toUtf8()));
+}
+
+void QmlV8DebuggerClientPrivate::setExceptionBreak(QmlV8DebuggerClient::Exceptions type,
+                                                   bool enabled)
 {
-    continueDebugging(Out);
+    //    { "seq"       : <number>,
+    //      "type"      : "request",
+    //      "command"   : "setexceptionbreak",
+    //      "arguments" : { "type"    : <string: "all", or "uncaught">,
+    //                      "enabled" : <optional bool: enables the break type if true>
+    //                    }
+    //    }
+    QScriptValue jsonVal = initObject();
+    jsonVal.setProperty(_(COMMAND),
+                        QScriptValue(_(SETEXCEPTIONBREAK)));
+
+    QScriptValue args = parser.call(QScriptValue(), QScriptValueList() << QScriptValue(_(OBJECT)));
+
+    if (type == QmlV8DebuggerClient::AllExceptions)
+        args.setProperty(_(TYPE), QScriptValue(_(ALL)));
+    //Not Supported
+    //    else if (type == QmlV8DebuggerClient::UncaughtExceptions)
+    //        args.setProperty(_(TYPE),QScriptValue(_(UNCAUGHT)));
+
+    if (enabled)
+        args.setProperty(_(ENABLED), QScriptValue(enabled));
+
+    jsonVal.setProperty(_(ARGUMENTS), args);
+
+
+    const QScriptValue jsonMessage = stringifier.call(QScriptValue(), QScriptValueList() << jsonVal);
+    q->sendMessage(packMessage(jsonMessage.toString().toUtf8()));
 }
 
-void QmlV8DebuggerClient::executeNext()
+void QmlV8DebuggerClientPrivate::listBreakpoints()
 {
-    continueDebugging(Next);
+    //    { "seq"       : <number>,
+    //      "type"      : "request",
+    //      "command"   : "listbreakpoints",
+    //    }
+    QScriptValue jsonVal = initObject();
+    jsonVal.setProperty(_(COMMAND),
+                        QScriptValue(_(LISTBREAKPOINTS)));
+
+    const QScriptValue jsonMessage = stringifier.call(QScriptValue(), QScriptValueList() << jsonVal);
+    q->sendMessage(packMessage(jsonMessage.toString().toUtf8()));
 }
 
-void QmlV8DebuggerClient::executeStepI()
+void QmlV8DebuggerClientPrivate::v8flags(const QString flags)
 {
-    continueDebugging(In);
+    //    { "seq"       : <number>,
+    //      "type"      : "request",
+    //      "command"   : "v8flags",
+    //      "arguments" : { "flags" : <string: a sequence of v8 flags just like
+    //                                  those used on the command line>
+    //                    }
+    //    }
+    QScriptValue jsonVal = initObject();
+    jsonVal.setProperty(_(COMMAND), QScriptValue(_(V8FLAGS)));
+
+    QScriptValue args = parser.call(QScriptValue(), QScriptValueList() << QScriptValue(_(OBJECT)));
+
+    args.setProperty(_(FLAGS), QScriptValue(flags));
+
+    jsonVal.setProperty(_(ARGUMENTS), args);
+
+    const QScriptValue jsonMessage = stringifier.call(QScriptValue(), QScriptValueList() << jsonVal);
+    q->sendMessage(packMessage(jsonMessage.toString().toUtf8()));
 }
 
-void QmlV8DebuggerClient::continueInferior()
+void QmlV8DebuggerClientPrivate::version()
 {
-    continueDebugging(Continue);
+    //    { "seq"       : <number>,
+    //      "type"      : "request",
+    //      "command"   : "version",
+    //    }
+    QScriptValue jsonVal = initObject();
+    jsonVal.setProperty(_(COMMAND), QScriptValue(_(VERSION)));
+
+    const QScriptValue jsonMessage = stringifier.call(QScriptValue(), QScriptValueList() << jsonVal);
+    q->sendMessage(packMessage(jsonMessage.toString().toUtf8()));
 }
 
-void QmlV8DebuggerClient::interruptInferior()
+//void QmlV8DebuggerClientPrivate::profile(ProfileCommand command)
+//{
+////    { "seq"       : <number>,
+////      "type"      : "request",
+////      "command"   : "profile",
+////      "arguments" : { "command"  : "resume" or "pause" }
+////    }
+//    QScriptValue jsonVal = initObject();
+//    jsonVal.setProperty(_(COMMAND), QScriptValue(_(PROFILE)));
+
+//    QScriptValue args = m_parser.call(QScriptValue(), QScriptValueList() << QScriptValue(_(OBJECT)));
+
+//    if (command == Resume)
+//        args.setProperty(_(COMMAND), QScriptValue(_(RESUME)));
+//    else
+//        args.setProperty(_(COMMAND), QScriptValue(_(PAUSE)));
+
+//    args.setProperty(_("modules"), QScriptValue(1));
+//    jsonVal.setProperty(_(ARGUMENTS), args);
+
+//    const QScriptValue jsonMessage = m_stringifier.call(QScriptValue(), QScriptValueList() << jsonVal);
+//    q->sendMessage(packMessage(jsonMessage.toString().toUtf8()));
+//}
+
+void QmlV8DebuggerClientPrivate::gc()
 {
-    QByteArray request;
+    //    { "seq"       : <number>,
+    //      "type"      : "request",
+    //      "command"   : "gc",
+    //      "arguments" : { "type" : <string: "all">,
+    //                    }
+    //    }
+    QScriptValue jsonVal = initObject();
+    jsonVal.setProperty(_(COMMAND),
+                        QScriptValue(_(GARBAGECOLLECTOR)));
 
-    JsonInputStream(request) << '{' << INITIALPARAMS ;
-    JsonInputStream(request) << ',' << "command" << ':' << "interrupt";
+    QScriptValue args = parser.call(QScriptValue(), QScriptValueList() << QScriptValue(_(OBJECT)));
 
-    JsonInputStream(request) << '}';
+    args.setProperty(_(TYPE), QScriptValue(_(ALL)));
 
-    sendMessage(packMessage(request));
+    jsonVal.setProperty(_(ARGUMENTS), args);
 
+    const QScriptValue jsonMessage = stringifier.call(QScriptValue(), QScriptValueList() << jsonVal);
+    q->sendMessage(packMessage(jsonMessage.toString().toUtf8()));
 }
 
-void QmlV8DebuggerClient::startSession()
+QmlV8ObjectData QmlV8DebuggerClientPrivate::extractData(const QVariant &data)
+{
+    //    { "handle" : <handle>,
+    //      "type"   : <"undefined", "null", "boolean", "number", "string", "object", "function" or "frame">
+    //    }
+
+    //    {"handle":<handle>,"type":"undefined"}
+
+    //    {"handle":<handle>,"type":"null"}
+
+    //    { "handle":<handle>,
+    //      "type"  : <"boolean", "number" or "string">
+    //      "value" : <JSON encoded value>
+    //    }
+
+    //    {"handle":7,"type":"boolean","value":true}
+
+    //    {"handle":8,"type":"number","value":42}
+
+    //    { "handle"              : <handle>,
+    //      "type"                : "object",
+    //      "className"           : <Class name, ECMA-262 property [[Class]]>,
+    //      "constructorFunction" : {"ref":<handle>},
+    //      "protoObject"         : {"ref":<handle>},
+    //      "prototypeObject"     : {"ref":<handle>},
+    //      "properties" : [ {"name" : <name>,
+    //                        "ref"  : <handle>
+    //                       },
+    //                       ...
+    //                     ]
+    //    }
+
+    //        { "handle" : <handle>,
+    //          "type"                : "function",
+    //          "className"           : "Function",
+    //          "constructorFunction" : {"ref":<handle>},
+    //          "protoObject"         : {"ref":<handle>},
+    //          "prototypeObject"     : {"ref":<handle>},
+    //          "name"                : <function name>,
+    //          "inferredName"        : <inferred function name for anonymous functions>
+    //          "source"              : <function source>,
+    //          "script"              : <reference to function script>,
+    //          "scriptId"            : <id of function script>,
+    //          "position"            : <function begin position in script>,
+    //          "line"                : <function begin source line in script>,
+    //          "column"              : <function begin source column in script>,
+    //          "properties" : [ {"name" : <name>,
+    //                            "ref"  : <handle>
+    //                           },
+    //                           ...
+    //                         ]
+    //        }
+
+    QmlV8ObjectData objectData;
+    const QVariantMap dataMap = data.toMap();
+    QString type = dataMap.value(_(TYPE)).toString();
+
+    if (type == _("undefined")) {
+        objectData.type = QByteArray("undefined");
+        objectData.value = QVariant(_("undefined"));
+
+    } else if (type == _("null")) {
+        objectData.type = QByteArray("null");
+        objectData.value= QVariant(_("null"));
+
+    } else if (type == _("boolean")) {
+        objectData.type = QByteArray("boolean");
+        objectData.value = dataMap.value(_(VALUE));
+
+    } else if (type == _("number")) {
+        objectData.type = QByteArray("number");
+        objectData.value = dataMap.value(_(VALUE));
+
+    } else if (type == _("string")) {
+        objectData.type = QByteArray("string");
+        objectData.value = dataMap.value(_(VALUE));
+
+    } else if (type == _("object")) {
+        objectData.type = QByteArray("object");
+        objectData.value = dataMap.value(_("className"));
+        objectData.properties = dataMap.value(_("properties"));
+
+    } else if (type == _("function")) {
+        objectData.type = QByteArray("function");
+        objectData.value = dataMap.value(_(NAME));
+        objectData.properties = dataMap.value(_("properties"));
+
+    } else if (type == _("script")) {
+        objectData.type = QByteArray("script");
+        objectData.value = dataMap.value(_(NAME));
+    }
+
+    return objectData;
+}
+
+QByteArray QmlV8DebuggerClientPrivate::packMessage(const QByteArray &message)
 {
-    QByteArray request;
+    QByteArray reply;
+    QDataStream rs(&reply, QIODevice::WriteOnly);
+    QByteArray cmd = V8DEBUG;
+    rs << cmd << message;
+    SDEBUG(QString(message));
+    return reply;
+}
 
-    JsonInputStream(request) << '{' << INITIALPARAMS ;
-    JsonInputStream(request) << ',' << "command" << ':' << "connect";
+QScriptValue QmlV8DebuggerClientPrivate::initObject()
+{
+    QScriptValue jsonVal = parser.call(QScriptValue(),
+                                       QScriptValueList() << QScriptValue(_(OBJECT)));
+    jsonVal.setProperty(_(SEQ), QScriptValue(++sequence));
+    jsonVal.setProperty(_(TYPE), _(REQUEST));
+    return jsonVal;
+}
+
+///////////////////////////////////////////////////////////////////////
+//
+// QmlV8DebuggerClient
+//
+///////////////////////////////////////////////////////////////////////
+
+QmlV8DebuggerClient::QmlV8DebuggerClient(QmlJsDebugClient::QDeclarativeDebugConnection *client)
+    : QmlDebuggerClient(client, QLatin1String("V8Debugger")),
+      d(new QmlV8DebuggerClientPrivate(this))
+{
+}
 
-    JsonInputStream(request) << '}';
+QmlV8DebuggerClient::~QmlV8DebuggerClient()
+{
+    delete d;
+}
 
-    sendMessage(packMessage(request));
+void QmlV8DebuggerClient::startSession()
+{
+    d->connect();
 }
 
 void QmlV8DebuggerClient::endSession()
 {
-    clearExceptionSelection();
+    d->disconnect();
+}
+
+void QmlV8DebuggerClient::executeStep()
+{
+
+    d->continueDebugging(In);
+}
+
+void QmlV8DebuggerClient::executeStepOut()
+{
+
+    d->continueDebugging(Out);
+}
 
-    QByteArray request;
+void QmlV8DebuggerClient::executeNext()
+{
 
-    JsonInputStream(request) << '{' << INITIALPARAMS ;
-    JsonInputStream(request) << ',' << "command" << ':' << "disconnect";
+    d->continueDebugging(Next);
+}
 
-    JsonInputStream(request) << '}';
+void QmlV8DebuggerClient::executeStepI()
+{
+
+    d->continueDebugging(In);
+}
+
+void QmlV8DebuggerClient::continueInferior()
+{
 
-    sendMessage(packMessage(request));
+    d->continueDebugging(Continue);
+}
+
+void QmlV8DebuggerClient::interruptInferior()
+{
+
+
+    d->interrupt();
 }
 
 void QmlV8DebuggerClient::activateFrame(int index)
 {
-    setLocals(index);
+
+    d->backtrace(index);
 }
 
 bool QmlV8DebuggerClient::acceptsBreakpoint(const BreakpointModelId &id)
@@ -318,76 +913,64 @@ bool QmlV8DebuggerClient::acceptsBreakpoint(const BreakpointModelId &id)
 
 void QmlV8DebuggerClient::insertBreakpoint(const BreakpointModelId &id)
 {
+
+
     BreakHandler *handler = d->engine->breakHandler();
     const BreakpointParameters &params = handler->breakpointData(id);
 
     if (params.type == BreakpointAtJavaScriptThrow) {
         handler->notifyBreakpointInsertOk(id);
-        return breakOnException(AllExceptions, params.enabled);
-    }
+        d->setExceptionBreak(AllExceptions, params.enabled);
 
-    QByteArray request;
+    } else if (params.type == BreakpointByFileAndLine) {
+        d->setBreakpoint(QString(_(SCRIPT)), QFileInfo(params.fileName).fileName(),
+                         params.lineNumber - 1, -1, params.enabled,
+                         QString(params.condition), params.ignoreCount);
 
-    JsonInputStream(request) << '{' << INITIALPARAMS ;
-    JsonInputStream(request) << ',' << "command" << ':' << "setbreakpoint";
-    JsonInputStream(request) << ',' << "arguments" << ':' << '{';
-    if (params.type == BreakpointByFileAndLine) {
-        JsonInputStream(request) << "type" << ':' << "script";
-        JsonInputStream(request) << ',' << "target" << ':' << QFileInfo(params.fileName).fileName().toUtf8();
-        JsonInputStream(request) << ',' << "line" << ':' << params.lineNumber - 1;
     } else if (params.type == BreakpointByFunction) {
-        JsonInputStream(request) << "type" << ':' << "function";
-        JsonInputStream(request) << ',' << "target" << ':' << params.functionName.toUtf8();
+        d->setBreakpoint(QString(_(FUNCTION)), params.functionName,
+                         -1, -1, params.enabled, QString(params.condition),
+                         params.ignoreCount);
+
     } else if (params.type == BreakpointOnQmlSignalHandler) {
-        JsonInputStream(request) << "type" << ':' << "event";
-        JsonInputStream(request) << ',' << "target" << ':' << params.functionName.toUtf8();
+        d->setBreakpoint(QString(_(EVENT)), params.functionName,
+                         -1, -1, params.enabled);
     }
-    JsonInputStream(request) << ',' << "enabled" << ':' << params.enabled;
-
-    JsonInputStream(request) << '}';
-    JsonInputStream(request) << '}';
 
-    d->breakpointsSync.insert(d->sequence,id);
-    sendMessage(packMessage(request));
+    d->breakpointsSync.insert(d->sequence, id);
 }
 
 void QmlV8DebuggerClient::removeBreakpoint(const BreakpointModelId &id)
 {
-    BreakHandler *handler = d->engine->breakHandler();
 
-    if (handler->breakpointData(id).type == BreakpointAtJavaScriptThrow) {
-        return breakOnException(AllExceptions, false);
-    }
+
+    BreakHandler *handler = d->engine->breakHandler();
 
     int breakpoint = d->breakpoints.value(id);
     d->breakpoints.remove(id);
 
-    QByteArray request;
-
-    JsonInputStream(request) << '{' << INITIALPARAMS ;
-    JsonInputStream(request) << ',' << "command" << ':' << "clearbreakpoint";
-
-    JsonInputStream(request) << ',' << "arguments" << ':';
-    JsonInputStream(request) << '{' << "breakpoint" << ':' << breakpoint;
-    JsonInputStream(request) << '}';
-
-    JsonInputStream(request) << '}';
-
-    sendMessage(packMessage(request));
+    if (handler->breakpointData(id).type == BreakpointAtJavaScriptThrow) {
+        d->setExceptionBreak(AllExceptions);
+    } else {
+        d->clearBreakpoint(breakpoint);
+    }
 }
 
 void QmlV8DebuggerClient::changeBreakpoint(const BreakpointModelId &id)
 {
+
+
     BreakHandler *handler = d->engine->breakHandler();
     const BreakpointParameters &params = handler->breakpointData(id);
 
     if (params.type == BreakpointAtJavaScriptThrow) {
-        return breakOnException(AllExceptions, params.enabled);
+        d->setExceptionBreak(AllExceptions, params.enabled);
     }
 }
 
-void QmlV8DebuggerClient::updateBreakpoints()
+void QmlV8DebuggerClient::synchronizeBreakpoints()
 {
+    //NOT USED
 }
 
 void QmlV8DebuggerClient::assignValueInDebugger(const QByteArray /*expr*/, const quint64 &/*id*/,
@@ -396,93 +979,56 @@ void QmlV8DebuggerClient::assignValueInDebugger(const QByteArray /*expr*/, const
     //TODO::
 }
 
-void QmlV8DebuggerClient::updateWatchData(const WatchData *data)
+void QmlV8DebuggerClient::updateWatchData(const WatchData &data)
 {
-    if (!data->iname.startsWith("watch."))
-        return;
-
-    QByteArray request;
-
-    JsonInputStream(request) << '{' << INITIALPARAMS ;
-    JsonInputStream(request) << ',' << "command" << ':' << "evaluate";
-
-    JsonInputStream(request) << ',' << "arguments" << ':';
-    JsonInputStream(request) << '{' << "expression" << ':' << data->exp;
-    JsonInputStream(request) << ',' << "frame" << ':' << d->engine->stackHandler()->currentFrame().level;
-    JsonInputStream(request) << '}';
-
-    JsonInputStream(request) << '}';
-
-    d->watches.insert(d->sequence,data->iname);
-
-    sendMessage(packMessage(request));
-
+    if (data.isWatcher()) {
+        WatchDataPair pair(data.iname, data.exp);
+        if (d->watches.key(pair)) {
+            WatchData data1 = data;
+            data1.setAllUnneeded();
+            //            data1.setValue(_("<unavailable>"));
+            //            data1.setHasChildren(false);
+            d->engine->watchHandler()->insertData(data1);
+        } else {
+            StackHandler *stackHandler = d->engine->stackHandler();
+            if (stackHandler->isContentsValid())
+                d->evaluate(data.exp, false, false, stackHandler->currentIndex());
+            else
+                d->evaluate(data.exp);
+            d->watches.insert(d->sequence, pair);
+        }
+    }
 }
 
 void QmlV8DebuggerClient::executeDebuggerCommand(const QString &command)
 {
-    QByteArray request;
 
-    JsonInputStream(request) << '{' << INITIALPARAMS ;
-    JsonInputStream(request) << ',' << "command" << ':' << "evaluate";
-
-    JsonInputStream(request) << ',' << "arguments" << ':';
-    JsonInputStream(request) << '{' << "expression" << ':' << command;
-    JsonInputStream(request) << ',' << "global" << ':' << true;
-    JsonInputStream(request) << '}';
-
-    JsonInputStream(request) << '}';
-
-    sendMessage(packMessage(request));
 
+    StackHandler *stackHandler = d->engine->stackHandler();
+    if (stackHandler->isContentsValid()) {
+        d->evaluate(command, false, false, stackHandler->currentIndex());
+    } else {
+        //Currently cannot evaluate if not in a javascript break
+        d->engine->showMessage(_("Request Was Unsuccessful"), ScriptConsoleOutput);
+        //        d->evaluate(command);
+    }
 }
 
 void QmlV8DebuggerClient::synchronizeWatchers(const QStringList &/*watchers*/)
 {
-    //TODO:: send watchers list
+    //TODO::
 }
 
 void QmlV8DebuggerClient::expandObject(const QByteArray &iname, quint64 objectId)
 {
-    d->locals.insert(objectId,iname);
-    QList<int> ids;
-    ids.append(objectId);
-
-    QByteArray request;
-
-    JsonInputStream(request) << '{' << INITIALPARAMS ;
-    JsonInputStream(request) << ',' << "command" << ':' << "lookup";
-
-    JsonInputStream(request) << ',' << "arguments" << ':';
-    JsonInputStream(request) << '{' << "handles" << ':' << ids;
-    JsonInputStream(request) << '}';
-
-    JsonInputStream(request) << '}';
-
-    sendMessage(packMessage(request));
-
-}
-
-void QmlV8DebuggerClient::listBreakpoints()
-{
-    QByteArray request;
 
-    JsonInputStream(request) << '{' << INITIALPARAMS ;
-    JsonInputStream(request) << ',' << "command" << ':' << "listbreakpoints";
-    JsonInputStream(request) << '}';
-
-    sendMessage(packMessage(request));
+    d->locals.insertMulti(objectId, iname);
+    d->lookup(QList<int>() << objectId);
 }
 
-void QmlV8DebuggerClient::backtrace()
+void QmlV8DebuggerClient::setEngine(QmlEngine *engine)
 {
-    QByteArray request;
-
-    JsonInputStream(request) << '{' << INITIALPARAMS ;
-    JsonInputStream(request) << ',' << "command" << ':' << "backtrace";
-    JsonInputStream(request) << '}';
-
-    sendMessage(packMessage(request));
+    d->engine = engine;
 }
 
 void QmlV8DebuggerClient::messageReceived(const QByteArray &data)
@@ -491,292 +1037,528 @@ void QmlV8DebuggerClient::messageReceived(const QByteArray &data)
     QByteArray command;
     ds >> command;
 
-    if (command == "V8DEBUG") {
+    if (command == V8DEBUG) {
         QByteArray response;
         ds >> response;
+        QString responseString(response);
 
-        JsonValue value(response);
-        const QString type = value.findChild("type").toVariant().toString();
+        SDEBUG(responseString);
 
-        if (type == "response") {
+        const QVariantMap resp = d->parser.call(QScriptValue(),
+                                                QScriptValueList() <<
+                                                QScriptValue(responseString)).toVariant().toMap();
+        const QString type(resp.value(_(TYPE)).toString());
 
-            if (!value.findChild("success").toVariant().toBool()) {
-                //TODO:: have to handle this case for each command
-                d->engine->logMessage(QmlEngine::LogReceive, QString("V8 Response Error: %1").arg(QString(value.toString(true,2))));
-                return;
+        if (type == _("response")) {
+
+            bool success = resp.value(_("success")).toBool();
+            if (!success) {
+                SDEBUG("Request was unsuccessful");
+                d->engine->logMessage(QmlEngine::LogReceive,
+                                      QString(_("V8 Response Error: %1")).arg(
+                                          resp.value(_("message")).toString()));
             }
 
-            const QString debugCommand(value.findChild("command").toVariant().toString());
-            if (debugCommand == "backtrace") {
-                setStackFrames(response);
+            const QString debugCommand(resp.value(_(COMMAND)).toString());
 
-            } else if (debugCommand == "lookup") {
-                expandLocal(response);
+            if (debugCommand == _(CONNECT)) {
+                //debugging session started
 
-            } else if (debugCommand == "setbreakpoint") {
-                int sequence = value.findChild("request_seq").toVariant().toInt();
-                int breakpoint = value.findChild("body").findChild("breakpoint").toVariant().toInt();
-                BreakpointModelId id = d->breakpointsSync.take(sequence);
-                d->breakpoints.insert(id,breakpoint);
+            } else if (debugCommand == _(DISCONNECT)) {
+                //debugging session ended
 
-                //If this is an event breakpoint then set state = BreakpointInsertOk
-                const QString breakpointType = value.findChild("body").findChild("type").toVariant().toString();
-                if (breakpointType == "event") {
-                    d->engine->breakHandler()->notifyBreakpointInsertOk(id);
+            } else if (debugCommand == _(BACKTRACE)) {
+                if (success) {
+                    updateStack(resp.value(_(BODY)), resp.value(_(REFS)));
                 }
 
-            } else if (debugCommand == "evaluate") {
-                setExpression(response);
+            } else if (debugCommand == _(LOOKUP)) {
+                expandLocal(resp.value(_(BODY)), resp.value(_(REFS)));
 
-            } else if (debugCommand == "listbreakpoints") {
-                updateBreakpoints(response);
-                backtrace();
+            } else if (debugCommand == _(EVALUATE)) {
+                if (success) {
+                    int seq = resp.value(_("request_seq")).toInt();
+                    updateEvaluationResult(seq, resp.value(_(BODY)), resp.value(_(REFS)));
+                } else {
+                    d->engine->showMessage(resp.value(_("message")).toString(), ScriptConsoleOutput);
+                }
 
+            } else if (debugCommand == _(LISTBREAKPOINTS)) {
+                updateBreakpoints(resp.value(_(BODY)));
+
+            } else if (debugCommand == _(SETBREAKPOINT)) {
+                //                { "seq"         : <number>,
+                //                  "type"        : "response",
+                //                  "request_seq" : <number>,
+                //                  "command"     : "setbreakpoint",
+                //                  "body"        : { "type"       : <"function" or "script">
+                //                                    "breakpoint" : <break point number of the new break point>
+                //                                  }
+                //                  "running"     : <is the VM running after sending this response>
+                //                  "success"     : true
+                //                }
+
+                int seq = resp.value(_("request_seq")).toInt();
+                const QVariantMap breakpointData = resp.value(_(BODY)).toMap();
+                int index = breakpointData.value(_("breakpoint")).toInt();
+
+                BreakpointModelId id = d->breakpointsSync.take(seq);
+                d->breakpoints.insert(id, index);
+
+                d->engine->breakHandler()->notifyBreakpointInsertOk(id);
+
+
+            } else if (debugCommand == _(CHANGEBREAKPOINT)) {
+                // DO NOTHING
+
+            } else if (debugCommand == _(CLEARBREAKPOINT)) {
+                // DO NOTHING
+
+            } else if (debugCommand == _(SETEXCEPTIONBREAK)) {
+                //                { "seq"               : <number>,
+                //                  "type"              : "response",
+                //                  "request_seq" : <number>,
+                //                  "command"     : "setexceptionbreak",
+                //                  “body”        : { "type"    : <string: "all" or "uncaught" corresponding to the request.>,
+                //                                    "enabled" : <bool: true if the break type is currently enabled as a result of the request>
+                //                                  }
+                //                  "running"     : true
+                //                  "success"     : true
+                //                }
+                //TODO::
+
+            } else if (debugCommand == _(FRAME)) {
+                if (success) {
+                    const QVariant body = resp.value(_(BODY));
+                    const QVariant refs = resp.value(_(REFS));
+                    const QVariant locals = body.toMap().value(_("locals"));
+                    StackFrame frame = createStackFrame(body, refs);
+                    updateLocals(locals, refs);
+                    d->engine->stackHandler()->setCurrentIndex(frame.level);
+                }
+
+            } else if (debugCommand == _(SCOPE)) {
+            } else if (debugCommand == _(SCOPES)) {
+            } else if (debugCommand == _(SOURCE)) {
+            } else if (debugCommand == _(SCRIPTS)) {
+            } else if (debugCommand == _(VERSION)) {
+            } else if (debugCommand == _(V8FLAGS)) {
+            } else if (debugCommand == _(GARBAGECOLLECTOR)) {
             } else {
-                d->engine->logMessage(QmlEngine::LogReceive, value.toString(true,2));
+                // DO NOTHING
             }
+        } else if (type == _(EVENT)) {
+            const QString eventType(resp.value(_(EVENT)).toString());
+
+            if (eventType == _("break")) {
+                //DO NOTHING
+            } else if (eventType == _("exception")) {
+                const QVariantMap body = resp.value(_(BODY)).toMap();
+                int lineNumber = body.value(_("sourceLine")).toInt() + 1;
 
-        } else if (type == "event") {
-            const QString event(value.findChild("event").toVariant().toString());
-
-            if (event == "break") {
-                d->engine->inferiorSpontaneousStop();
-                listBreakpoints();
-            } else if (event == "exception") {
-                d->handleException = true;
-                d->engine->inferiorSpontaneousStop();
-                storeExceptionInformation(response);
-                backtrace();
+                const QVariantMap script = body.value(_("script")).toMap();
+                QUrl fileUrl(script.value(_(NAME)).toString());
+                QString filePath = d->engine->toFileInProject(fileUrl);
+
+                const QVariantMap exception = body.value(_("exception")).toMap();
+                QString errorMessage = exception.value(_("text")).toString();
+
+                highlightExceptionCode(lineNumber, filePath, errorMessage);
             }
         }
+
+        if (resp.value(_("running")).toBool()) {
+            //DO NOTHING
+        } else {
+            d->engine->inferiorSpontaneousStop();
+            d->listBreakpoints();
+            d->backtrace(d->currentFrameIndex);
+        }
+    } else {
+        //DO NOTHING
     }
+
 }
 
-void QmlV8DebuggerClient::setStackFrames(const QByteArray &message)
+void QmlV8DebuggerClient::updateStack(const QVariant &bodyVal, const QVariant &refsVal)
 {
-    d->frames = message;
-    JsonValue response(message);
-
-    JsonValue refs = response.findChild("refs");
-    JsonValue body = response.findChild("body");
-
-    int totalFrames = body.findChild("totalFrames").toVariant().toInt();
-    JsonValue stackFrames = body.findChild("frames");
-
-    StackFrames ideStackFrames;
-    for (int i = 0; i != totalFrames; ++i) {
+    //    { "seq"         : <number>,
+    //      "type"        : "response",
+    //      "request_seq" : <number>,
+    //      "command"     : "backtrace",
+    //      "body"        : { "fromFrame" : <number>
+    //                        "toFrame" : <number>
+    //                        "totalFrames" : <number>
+    //                        "frames" : <array of frames - see frame request for details>
+    //                      }
+    //      "running"     : <is the VM running after sending this response>
+    //      "success"     : true
+    //    }
+
+    StackFrames stackFrames;
+    const QVariantMap body = bodyVal.toMap();
+    const QVariantList frames = body.value(_("frames")).toList();
+
+    d->engine->watchHandler()->beginCycle();
+    foreach (const QVariant &frame, frames) {
+        stackFrames << createStackFrame(frame, refsVal);
+    }
+    d->engine->watchHandler()->endCycle();
 
-        JsonValue stackFrame = stackFrames.childAt(i);
+    d->currentFrameIndex = body.value(_("fromFrame")).toInt();
 
-        StackFrame frame;
+    if (!d->currentFrameIndex ) {
+        d->engine->stackHandler()->setFrames(stackFrames);
+    }
 
-        int frameIndex = stackFrame.findChild("index").toVariant().toInt();
-        frame.level = frameIndex;
+    if (d->updateCurrentStackFrameIndex) {
+        d->engine->stackHandler()->setCurrentIndex(d->currentFrameIndex);
+        d->engine->gotoLocation(stackFrames.value(d->currentFrameIndex));
+    }
 
-        frame.line = stackFrame.findChild("line").toVariant().toInt() + 1;
+    d->updateCurrentStackFrameIndex = true;
 
-        int index = indexInRef(refs,stackFrame.findChild("func").findChild("ref").toVariant().toInt());
-        if (index != -1) {
-            JsonValue func = refs.childAt(index);
-            frame.function = func.findChild("name").toVariant().toString();
-        }
+}
 
-        index = indexInRef(refs,stackFrame.findChild("script").findChild("ref").toVariant().toInt());
-        if (index != -1) {
-            JsonValue script = refs.childAt(index);
-            frame.file = d->engine->toFileInProject(script.findChild("name").toVariant().toString());
-            frame.usable = QFileInfo(frame.file).isReadable();
-        }
-        ideStackFrames << frame;
+StackFrame QmlV8DebuggerClient::createStackFrame(const QVariant &bodyVal, const QVariant &refsVal)
+{
+    //    { "seq"         : <number>,
+    //      "type"        : "response",
+    //      "request_seq" : <number>,
+    //      "command"     : "frame",
+    //      "body"        : { "index"          : <frame number>,
+    //                        "receiver"       : <frame receiver>,
+    //                        "func"           : <function invoked>,
+    //                        "script"         : <script for the function>,
+    //                        "constructCall"  : <boolean indicating whether the function was called as constructor>,
+    //                        "debuggerFrame"  : <boolean indicating whether this is an internal debugger frame>,
+    //                        "arguments"      : [ { name: <name of the argument - missing of anonymous argument>,
+    //                                               value: <value of the argument>
+    //                                             },
+    //                                             ... <the array contains all the arguments>
+    //                                           ],
+    //                        "locals"         : [ { name: <name of the local variable>,
+    //                                               value: <value of the local variable>
+    //                                             },
+    //                                             ... <the array contains all the locals>
+    //                                           ],
+    //                        "position"       : <source position>,
+    //                        "line"           : <source line>,
+    //                        "column"         : <source column within the line>,
+    //                        "sourceLineText" : <text for current source line>,
+    //                        "scopes"         : [ <array of scopes, see scope request below for format> ],
+
+    //                      }
+    //      "running"     : <is the VM running after sending this response>
+    //      "success"     : true
+    //    }
+
+    const QVariantMap body = bodyVal.toMap();
+
+    StackFrame stackFrame;
+    stackFrame.level = body.value(_("index")).toInt();
+
+    QVariantMap func = body.value(_("func")).toMap();
+    if (func.contains(_(REF))) {
+        func = valueFromRef(func.value(_(REF)).toInt(), refsVal).toMap();
     }
+    stackFrame.function = d->extractData(QVariant(func)).value.toString();
 
-    d->engine->stackHandler()->setFrames(ideStackFrames);
-
-    if (!ideStackFrames.isEmpty()) {
-        setLocals(0);
-        d->engine->gotoLocation(ideStackFrames.value(0));
+    QVariantMap file = body.value(_("script")).toMap();
+    if (file.contains(_(REF))) {
+        file = valueFromRef(file.value(_(REF)).toInt(), refsVal).toMap();
     }
+    stackFrame.file = d->engine->toFileInProject(d->extractData(QVariant(file)).value.toString());
+    stackFrame.usable = QFileInfo(stackFrame.file).isReadable();
 
-    if (d->handleException) {
-        handleException();
+    QVariantMap receiver = body.value(_("receiver")).toMap();
+    if (receiver.contains(_(REF))) {
+        receiver = valueFromRef(receiver.value(_(REF)).toInt(), refsVal).toMap();
     }
-}
-
-void QmlV8DebuggerClient::setLocals(int frameIndex)
-{
-    JsonValue response(d->frames);
+    stackFrame.to = d->extractData(QVariant(receiver)).value.toString();
 
-    JsonValue refs = response.findChild("refs");
-    JsonValue body = response.findChild("body");
+    stackFrame.line = body.value(_("line")).toInt() + 1;
 
-    int totalFrames = body.findChild("totalFrames").toVariant().toInt();
-    JsonValue stackFrames = body.findChild("frames");
+    const QVariant locals = body.value(_("locals"));
+    updateLocals(locals, refsVal);
 
+    return stackFrame;
+}
 
-    for (int i = 0; i != totalFrames; ++i) {
-
-        JsonValue stackFrame = stackFrames.childAt(i);
-        int index = stackFrame.findChild("index").toVariant().toInt();
-        if (index != frameIndex)
+void QmlV8DebuggerClient::updateLocals(const QVariant &localsVal, const QVariant &refsVal)
+{
+    //Add Locals
+    const QVariantList locals = localsVal.toList();
+    QList<WatchData> localDataList;
+    foreach (const QVariant &localValue, locals) {
+        QVariantMap localData = localValue.toMap();
+        WatchData data;
+        data.exp = localData.value(_(NAME)).toByteArray();
+        //Check for v8 specific local data
+        if (data.exp.startsWith(".") || data.exp.isEmpty())
             continue;
 
-        JsonValue locals = stackFrame.findChild("locals");
+        data.name = data.exp;
+        data.iname = "local." + data.exp;
 
-        d->engine->watchHandler()->beginCycle();
+        localData = valueFromRef(localData.value(_(VALUE)).toMap()
+                                 .value(_(REF)).toInt(), refsVal).toMap();
+        data.id = localData.value(_(HANDLE)).toInt();
 
-        int localsCount = locals.childCount();
-        for (int j = 0; j != localsCount; ++j) {
-            JsonValue local = locals.childAt(j);
-
-            WatchData data;
-            data.exp = local.findChild("name").toVariant().toByteArray();
-            //Check for v8 specific local
-            if (data.exp.startsWith("."))
-                continue;
+        QmlV8ObjectData objectData = d->extractData(QVariant(localData));
+        data.type = objectData.type;
+        data.value = objectData.value.toString();
 
-            data.name = data.exp;
-            data.iname = "local." + data.exp;
-            JsonValue val = refs.childAt(indexInRef(refs,local.findChild("value").findChild("ref").toVariant().toInt()));
-            data.type = val.findChild("type").toVariant().toByteArray();
+        data.setHasChildren(objectData.properties.toList().count());
 
-            if (data.type == "object") {
-                data.hasChildren = true;
-                data.value = val.findChild("className").toVariant().toByteArray();
+        localDataList << data;
+    }
 
-            } else if (data.type == "function" || data.type == "undefined") {
-                data.hasChildren = false;
-                data.value = val.findChild("text").toVariant().toByteArray();
+    d->engine->watchHandler()->insertBulkData(localDataList);
 
-            } else {
-                data.hasChildren = false;
-                data.value = val.findChild("value").toVariant().toByteArray();
-            }
+}
 
-            data.id = val.findChild("handle").toVariant().toInt();
+void QmlV8DebuggerClient::updateEvaluationResult(int sequence, const QVariant &bodyVal,
+                                                 const QVariant &refsVal)
+{
+    //    { "seq"         : <number>,
+    //      "type"        : "response",
+    //      "request_seq" : <number>,
+    //      "command"     : "evaluate",
+    //      "body"        : ...
+    //      "running"     : <is the VM running after sending this response>
+    //      "success"     : true
+    //    }
+    QVariantMap bodyMap = bodyVal.toMap();
+    if (bodyMap.contains(_(REF))) {
+        bodyMap = valueFromRef(bodyMap.value(_(REF)).toInt(),
+                               refsVal).toMap();
+    }
 
-            d->engine->watchHandler()->insertData(data);
+    QmlV8ObjectData body = d->extractData(QVariant(bodyMap));
 
-            if (d->engine->watchHandler()->expandedINames().contains(data.iname)) {
-                expandObject(data.iname, data.id);
-            }
-        }
+    if (!d->watches.contains(sequence)) {
+        //Console
+        d->engine->showMessage(body.value.toString(), ScriptConsoleOutput);
 
-        d->engine->watchHandler()->endCycle();
+    } else {
+        WatchDataPair pair = d->watches.value(sequence);
+        QByteArray iname = pair.first;
+        QByteArray exp = pair.second;
+        WatchData data;
+        data.exp = exp;
+        data.name = data.exp;
+        data.iname = iname;
+        data.id = bodyMap.value(_(HANDLE)).toInt();
+        data.type = body.type;
+        data.value = body.value.toString();
+
+        const QVariantList properties = body.properties.toList();
+        data.setHasChildren(properties.count());
+        //        data.setAllUnneeded();
+        //        data.setValueNeeded();
+        d->engine->watchHandler()->insertData(data);
+
+        //        foreach (const QVariant &property, properties) {
+        //            QVariantMap propertyData = property.toMap();
+        //            WatchData data;
+        //            data.exp = propertyData.value(_(NAME)).toByteArray();
+
+        //            //Check for v8 specific local data
+        //            if (data.exp.startsWith(".") || data.exp.isEmpty())
+        //                continue;
+
+        //            data.name = data.exp;
+        //            data.iname = prepend + '.' + data.exp;
+        //            propertyData = valueFromRef(propertyData.value(_(REF)).toInt(),
+        //                                        refsVal).toMap();
+        //            data.id = propertyData.value(_(HANDLE)).toInt();
+
+        //            QmlV8ObjectData objectData = d->extractData(QVariant(propertyData));
+        //            data.type = objectData.type;
+        //            data.value = objectData.value.toString();
+
+        //            data.setHasChildren(objectData.properties.toList().count());
+        //            d->engine->watchHandler()->insertData(data);
+        //        }
     }
 }
 
-void QmlV8DebuggerClient::expandLocal(const QByteArray &message)
+void QmlV8DebuggerClient::updateBreakpoints(const QVariant &bodyVal)
 {
-    JsonValue response(message);
+    //    { "seq"         : <number>,
+    //      "type"        : "response",
+    //      "request_seq" : <number>,
+    //      "command"     : "listbreakpoints",
+    //      "body"        : { "breakpoints": [ { "type"             : <string: "scriptId"  or "scriptName".>,
+    //                                           "script_id"        : <int: script id.  Only defined if type is scriptId.>,
+    //                                           "script_name"      : <string: script name.  Only defined if type is scriptName.>,
+    //                                           "number"           : <int: breakpoint number.  Starts from 1.>,
+    //                                           "line"             : <int: line number of this breakpoint.  Starts from 0.>,
+    //                                           "column"           : <int: column number of this breakpoint.  Starts from 0.>,
+    //                                           "groupId"          : <int: group id of this breakpoint.>,
+    //                                           "hit_count"        : <int: number of times this breakpoint has been hit.  Starts from 0.>,
+    //                                           "active"           : <bool: true if this breakpoint is enabled.>,
+    //                                           "ignoreCount"      : <int: remaining number of times to ignore breakpoint.  Starts from 0.>,
+    //                                           "actual_locations" : <actual locations of the breakpoint.>,
+    //                                         }
+    //                                       ],
+    //                        "breakOnExceptions"         : <true if break on all exceptions is enabled>,
+    //                        "breakOnUncaughtExceptions" : <true if break on uncaught exceptions is enabled>
+    //                      }
+    //      "running"     : <is the VM running after sending this response>
+    //      "success"     : true
+    //    }
+
+    const QVariantMap body = bodyVal.toMap();
+    const QVariantList breakpoints = body.value(_("breakpoints")).toList();
+    BreakHandler *handler = d->engine->breakHandler();
 
-    JsonValue refs = response.findChild("refs");
-    JsonValue body = response.findChild("body");
-    JsonValue details = body.childAt(0);
+    foreach (const QVariant &breakpoint, breakpoints) {
+        const QVariantMap breakpointData = breakpoint.toMap();
 
-    int id = QString(details.name()).toInt();
-    QByteArray prepend = d->locals.take(id);
+        int index = breakpointData.value(_("number")).toInt();
+        BreakpointModelId id = d->breakpoints.key(index);
+        BreakpointResponse br = handler->response(id);
 
-    JsonValue properties = details.findChild("properties");
-    int propertiesCount = properties.childCount();
+        const QVariantList actualLocations = breakpointData.value(_("actual_locations")).toList();
+        foreach (const QVariant &location, actualLocations) {
+            const QVariantMap locationData = location.toMap();
+            br.lineNumber = locationData.value(_("line")).toInt() + 1;;
+            br.enabled = breakpointData.value(_("active")).toBool();
+            br.hitCount = breakpointData.value(_("hit_count")).toInt();
+            br.ignoreCount = breakpointData.value(_("ignoreCount")).toInt();
 
-    for (int k = 0; k != propertiesCount; ++k) {
-        JsonValue property = properties.childAt(k);
-        setPropertyValue(refs,property,prepend);
+            handler->setResponse(id, br);
+        }
     }
 }
 
-void QmlV8DebuggerClient::setExpression(const QByteArray &message)
+QVariant QmlV8DebuggerClient::valueFromRef(int handle, const QVariant &refsVal)
 {
-    JsonValue response(message);
-    JsonValue body = response.findChild("body");
-
-    int seq = response.findChild("request_seq").toVariant().toInt();
-
-    //Console
-    if (!d->watches.contains(seq)) {
-        d->engine->showMessage(body.findChild("text").toVariant().toString(), ScriptConsoleOutput);
-        return;
+    QVariant variant;
+    const QVariantList refs = refsVal.toList();
+    foreach (const QVariant &ref, refs) {
+        const QVariantMap refData = ref.toMap();
+        if (refData.value(_(HANDLE)).toInt() == handle) {
+            variant = refData;
+            break;
+        }
     }
-
-    //TODO: For watch point
+    return variant;
 }
 
-void QmlV8DebuggerClient::updateBreakpoints(const QByteArray &message)
+void QmlV8DebuggerClient::expandLocal(const QVariant &bodyVal, const QVariant &refsVal)
 {
-    JsonValue response(message);
-
-    JsonValue body = response.findChild("body");
-
-    QList<JsonValue> breakpoints = body.findChild("breakpoints").children();
-    BreakHandler *handler = d->engine->breakHandler();
-
-    foreach (const JsonValue &bp, breakpoints) {
-
-        int bpIndex = bp.findChild("number").toVariant().toInt();
-        BreakpointModelId id = d->breakpoints.key(bpIndex);
-        BreakpointResponse br = handler->response(id);
-
-        if (!br.pending)
+    //    { "seq"         : <number>,
+    //      "type"        : "response",
+    //      "request_seq" : <number>,
+    //      "command"     : "lookup",
+    //      "body"        : <array of serialized objects indexed using their handle>
+    //      "running"     : <is the VM running after sending this response>
+    //      "success"     : true
+    //    }
+    const QVariantMap body = bodyVal.toMap();
+
+    int handle = body.keys().value(0).toInt();
+    QByteArray prepend = d->locals.take(handle);
+    const WatchData *parent = d->engine->watchHandler()->findItem(prepend);
+    QmlV8ObjectData bodyObjectData = d->extractData(
+                body.value(body.keys().value(0)));
+
+    const QVariantList properties = bodyObjectData.properties.toList();
+
+    QList<WatchData> children;
+    foreach (const QVariant &property, properties) {
+        QVariantMap propertyData = property.toMap();
+        WatchData data;
+        data.name = propertyData.value(_(NAME)).toString();
+
+        //Check for v8 specific local data
+        if (data.name.startsWith(".") || data.name.isEmpty())
             continue;
+        if (parent->type == "object") {
+            if (parent->value == _("Array"))
+                data.exp = parent->exp + '[' + data.name.toUtf8() + ']';
+            else if (parent->value == _("Object"))
+                data.exp = parent->exp + '.' + data.name.toUtf8();
+        }
+        data.iname = prepend + '.' + data.name.toUtf8();
+        propertyData = valueFromRef(propertyData.value(_(REF)).toInt(),
+                                    refsVal).toMap();
+        data.id = propertyData.value(_(HANDLE)).toInt();
 
-        br.hitCount = bp.findChild("hit_count").toVariant().toInt();
+        QmlV8ObjectData objectData = d->extractData(QVariant(propertyData));
+        data.type = objectData.type;
+        data.value = objectData.value.toString();
 
-        QList<JsonValue> actualLocations = bp.findChild("actual_locations").children();
-        foreach (const JsonValue &location, actualLocations) {
-            int line = location.findChild("line").toVariant().toInt() + 1; //Add the offset
-            br.lineNumber = line;
-            br.correctedLineNumber = line;
-            handler->setResponse(id,br);
-            handler->notifyBreakpointInsertOk(id);
-        }
+        data.setHasChildren(objectData.properties.toList().count());
+        children << data;
     }
+    d->engine->watchHandler()->insertBulkData(children);
 }
 
-void QmlV8DebuggerClient::setPropertyValue(const JsonValue &refs, const JsonValue &property, const QByteArray &prepend)
+void QmlV8DebuggerClient::highlightExceptionCode(int lineNumber,
+                                                 const QString &filePath,
+                                                 const QString &errorMessage)
 {
-    WatchData data;
-    data.exp = property.findChild("name").toVariant().toByteArray();
-    data.name = data.exp;
-    data.iname = prepend + '.' + data.exp;
-    JsonValue val = refs.childAt(indexInRef(refs,property.findChild("ref").toVariant().toInt()));
-    data.type = val.findChild("type").toVariant().toByteArray();
-
-    if (data.type == "object") {
-        data.hasChildren = true;
-        data.value = val.findChild("className").toVariant().toByteArray();
+    EditorManager *editorManager = EditorManager::instance();
+    QList<IEditor *> openedEditors = editorManager->openedEditors();
 
-    } else if (data.type == "function") {
-        data.hasChildren = false;
-        data.value = val.findChild("text").toVariant().toByteArray();
+    // set up the format for the errors
+    QTextCharFormat errorFormat;
+    errorFormat.setUnderlineStyle(QTextCharFormat::WaveUnderline);
+    errorFormat.setUnderlineColor(Qt::red);
 
-    } else {
-        data.hasChildren = false;
-        data.value = val.findChild("value").toVariant().toByteArray();
-    }
+    foreach (IEditor *editor, openedEditors) {
+        if (editor->file()->fileName() == filePath) {
+            TextEditor::BaseTextEditorWidget *ed = qobject_cast<TextEditor::BaseTextEditorWidget *>(editor->widget());
+            if (!ed)
+                continue;
 
-    data.id = val.findChild("handle").toVariant().toInt();
+            QList<QTextEdit::ExtraSelection> selections;
+            QTextEdit::ExtraSelection sel;
+            sel.format = errorFormat;
+            QTextCursor c(ed->document()->findBlockByNumber(lineNumber));
+            const QString text = c.block().text();
+            for (int i = 0; i < text.size(); ++i) {
+                if (! text.at(i).isSpace()) {
+                    c.setPosition(c.position() + i);
+                    break;
+                }
+            }
+            c.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
+            sel.cursor = c;
 
-    d->engine->watchHandler()->insertData(data);
+            sel.format.setToolTip(errorMessage);
 
-    if (d->engine->watchHandler()->expandedINames().contains(data.iname)) {
-        expandObject(data.iname, data.id);
+            selections.append(sel);
+            ed->setExtraSelections(TextEditor::BaseTextEditorWidget::DebuggerExceptionSelection, selections);
+        }
     }
 }
 
-int QmlV8DebuggerClient::indexInRef(const JsonValue &refs, int refIndex)
+void QmlV8DebuggerClient::clearExceptionSelection()
 {
-    for (int i = 0; i != refs.childCount(); ++i) {
-        JsonValue ref = refs.childAt(i);
-        int index = ref.findChild("handle").toVariant().toInt();
-        if (index == refIndex)
-            return i;
+    EditorManager *editorManager = EditorManager::instance();
+    QList<IEditor *> openedEditors = editorManager->openedEditors();
+    QList<QTextEdit::ExtraSelection> selections;
+
+    foreach (IEditor *editor, openedEditors) {
+        TextEditor::BaseTextEditorWidget *ed = qobject_cast<TextEditor::BaseTextEditorWidget *>(editor->widget());
+        if (!ed)
+            continue;
+
+        ed->setExtraSelections(TextEditor::BaseTextEditorWidget::DebuggerExceptionSelection, selections);
     }
-    return -1;
+
 }
 
-void QmlV8DebuggerClient::setEngine(QmlEngine *engine)
+void QmlV8DebuggerClient::reset()
 {
-    d->engine = engine;
+    clearExceptionSelection();
+    d->currentFrameIndex = 0;
+    d->updateCurrentStackFrameIndex = true;
 }
 
 } // Internal
diff --git a/src/plugins/debugger/qml/qmlv8debuggerclient.h b/src/plugins/debugger/qml/qmlv8debuggerclient.h
index 8c0c5cc13a5..830151232dc 100644
--- a/src/plugins/debugger/qml/qmlv8debuggerclient.h
+++ b/src/plugins/debugger/qml/qmlv8debuggerclient.h
@@ -36,8 +36,6 @@
 #include "qmldebuggerclient.h"
 #include "stackframe.h"
 #include "watchdata.h"
-#include "qmlengine.h"
-#include "json.h"
 
 namespace Debugger {
 namespace Internal {
@@ -84,12 +82,12 @@ public:
     void insertBreakpoint(const BreakpointModelId &id);
     void removeBreakpoint(const BreakpointModelId &id);
     void changeBreakpoint(const BreakpointModelId &id);
-    void updateBreakpoints();
+    void synchronizeBreakpoints();
 
     void assignValueInDebugger(const QByteArray expr, const quint64 &id,
                                        const QString &property, const QString &value);
 
-    void updateWatchData(const WatchData *data);
+    void updateWatchData(const WatchData &data);
     void executeDebuggerCommand(const QString &command);
 
     void synchronizeWatchers(const QStringList &watchers);
@@ -98,30 +96,27 @@ public:
 
     void setEngine(QmlEngine *engine);
 
-signals:
-    void notifyDebuggerStopped();
-
 protected:
     void messageReceived(const QByteArray &data);
 
 private:
-    void listBreakpoints();
-    void backtrace();
-    void setStackFrames(const QByteArray &message);
-    void setLocals(int frameIndex);
-    void setExpression(const QByteArray &message);
-    void updateBreakpoints(const QByteArray &message);
-    void expandLocal(const QByteArray &message);
-    void setPropertyValue(const Json::JsonValue &refs, const Json::JsonValue &property, const QByteArray &prepend);
-    int indexInRef(const Json::JsonValue &refs, int refIndex);
-    QByteArray packMessage(const QByteArray &message);
-
-    void breakOnException(Exceptions exceptionsType, bool enabled);
-    void storeExceptionInformation(const QByteArray &message);
-    void handleException();
+    void updateStack(const QVariant &bodyVal, const QVariant &refsVal);
+    StackFrame createStackFrame(const QVariant &bodyVal, const QVariant &refsVal);
+    void updateLocals(const QVariant &localsVal, const QVariant &refsVal);
+
+    void updateEvaluationResult(int sequence, const QVariant &bodyVal,
+                                const QVariant &refsVal);
+    void updateBreakpoints(const QVariant &bodyVal);
+
+    QVariant valueFromRef(int handle, const QVariant &refsVal);
+
+    void expandLocal(const QVariant &bodyVal, const QVariant &refsVal);
+
+    void highlightExceptionCode(int lineNumber, const QString &filePath,
+                                const QString &errorMessage);
     void clearExceptionSelection();
 
-    void continueDebugging(StepAction type);
+    void reset();
 
 private:
     QmlV8DebuggerClientPrivate *d;
diff --git a/src/plugins/debugger/qml/qmlv8debuggerclientconstants.h b/src/plugins/debugger/qml/qmlv8debuggerclientconstants.h
new file mode 100644
index 00000000000..40a39ddcde5
--- /dev/null
+++ b/src/plugins/debugger/qml/qmlv8debuggerclientconstants.h
@@ -0,0 +1,121 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at info@qt.nokia.com.
+**
+**************************************************************************/
+
+#ifndef QMLV8DEBUGGERCLIENTCONSTANTS_H
+#define QMLV8DEBUGGERCLIENTCONSTANTS_H
+
+namespace Debugger {
+namespace Internal {
+
+const char V8DEBUG[] = "V8DEBUG";
+const char SEQ[] = "seq";
+const char TYPE[] = "type";
+const char COMMAND[] = "command";
+const char ARGUMENTS[] = "arguments";
+const char STEPACTION[] = "stepaction";
+const char STEPCOUNT[] = "stepcount";
+const char EXPRESSION[] = "expression";
+const char FRAME[] = "frame";
+const char GLOBAL[] = "global";
+const char DISABLE_BREAK[] = "disable_break";
+const char ADDITIONAL_CONTEXT[] = "additional_context";
+const char HANDLES[] = "handles";
+const char INCLUDESOURCE[] = "includeSource";
+const char FROMFRAME[] = "fromFrame";
+const char TOFRAME[] = "toFrame";
+const char BOTTOM[] = "bottom";
+const char NUMBER[] = "number";
+const char FRAMENUMBER[] = "frameNumber";
+const char TYPES[] = "types";
+const char IDS[] = "ids";
+const char FILTER[] = "filter";
+const char FROMLINE[] = "fromLine";
+const char TOLINE[] = "toLine";
+const char TARGET[] = "target";
+const char LINE[] = "line";
+const char COLUMN[] = "column";
+const char ENABLED[] = "enabled";
+const char CONDITION[] = "condition";
+const char IGNORECOUNT[] = "ignoreCount";
+const char BREAKPOINT[] = "breakpoint";
+const char FLAGS[] = "flags";
+
+const char CONTINEDEBUGGING[] = "continue";
+const char EVALUATE[] = "evaluate";
+const char LOOKUP[] = "lookup";
+const char BACKTRACE[] = "backtrace";
+const char SCOPE[] = "scope";
+const char SCOPES[] = "scopes";
+const char SCRIPTS[] = "scripts";
+const char SOURCE[] = "source";
+const char SETBREAKPOINT[] = "setbreakpoint";
+const char CHANGEBREAKPOINT[] = "changebreakpoint";
+const char CLEARBREAKPOINT[] = "clearbreakpoint";
+const char SETEXCEPTIONBREAK[] = "setexceptionbreak";
+const char V8FLAGS[] = "v8flags";
+const char VERSION[] = "version";
+const char DISCONNECT[] = "disconnect";
+const char LISTBREAKPOINTS[] = "listbreakpoints";
+const char GARBAGECOLLECTOR[] = "gc";
+//const char PROFILE[] = "profile";
+
+const char CONNECT[] = "connect";
+const char INTERRUPT[] = "interrupt";
+
+const char REQUEST[] = "request";
+const char IN[] = "in";
+const char NEXT[] = "next";
+const char OUT[] = "out";
+
+const char FUNCTION[] = "function";
+const char SCRIPT[] = "script";
+const char EVENT[] = "event";
+
+const char ALL[] = "all";
+const char UNCAUGHT[] = "uncaught";
+
+//const char PAUSE[] = "pause";
+//const char RESUME[] = "resume";
+
+const char HANDLE[] = "handle";
+const char REF[] = "ref";
+const char REFS[] = "refs";
+const char BODY[] = "body";
+const char NAME[] = "name";
+const char VALUE[] = "value";
+
+const char OBJECT[] = "{}";
+const char ARRAY[] = "[]";
+
+} //Internal
+} //Debugger
+#endif // QMLV8DEBUGGERCLIENTCONSTANTS_H
diff --git a/src/plugins/debugger/qml/qscriptdebuggerclient.cpp b/src/plugins/debugger/qml/qscriptdebuggerclient.cpp
index 12710c44d10..aad0ffea864 100644
--- a/src/plugins/debugger/qml/qscriptdebuggerclient.cpp
+++ b/src/plugins/debugger/qml/qscriptdebuggerclient.cpp
@@ -240,7 +240,7 @@ void QScriptDebuggerClient::changeBreakpoint(const BreakpointModelId &/*id*/)
 {
 }
 
-void QScriptDebuggerClient::updateBreakpoints()
+void QScriptDebuggerClient::synchronizeBreakpoints()
 {
     QByteArray reply;
     QDataStream rs(&reply, QIODevice::WriteOnly);
@@ -261,13 +261,13 @@ void QScriptDebuggerClient::assignValueInDebugger(const QByteArray expr, const q
     sendMessage(reply);
 }
 
-void QScriptDebuggerClient::updateWatchData(const WatchData *data)
+void QScriptDebuggerClient::updateWatchData(const WatchData &data)
 {
     QByteArray reply;
     QDataStream rs(&reply, QIODevice::WriteOnly);
     QByteArray cmd = "EXEC";
     rs << cmd;
-    rs << data->iname << data->name;
+    rs << data.iname << data.name;
     sendMessage(reply);
 }
 
diff --git a/src/plugins/debugger/qml/qscriptdebuggerclient.h b/src/plugins/debugger/qml/qscriptdebuggerclient.h
index bd57ef60470..691fa2c829f 100644
--- a/src/plugins/debugger/qml/qscriptdebuggerclient.h
+++ b/src/plugins/debugger/qml/qscriptdebuggerclient.h
@@ -67,12 +67,12 @@ public:
     void insertBreakpoint(const BreakpointModelId &id);
     void removeBreakpoint(const BreakpointModelId &id);
     void changeBreakpoint(const BreakpointModelId &id);
-    void updateBreakpoints();
+    void synchronizeBreakpoints();
 
     void assignValueInDebugger(const QByteArray expr, const quint64 &id,
                                        const QString &property, const QString &value);
 
-    void updateWatchData(const WatchData *data);
+    void updateWatchData(const WatchData &data);
     void executeDebuggerCommand(const QString &command);
 
     void synchronizeWatchers(const QStringList &watchers);
@@ -81,9 +81,6 @@ public:
 
     void setEngine(QmlEngine *engine);
 
-signals:
-    void notifyDebuggerStopped();
-
 protected:
     void messageReceived(const QByteArray &data);
 
-- 
GitLab