diff --git a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp
index 2cb51e9f4d7e965428d94f4028d8ef4a526d3627..d7178c31203ffc271953705f7f5cec3eba0907d1 100644
--- a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp
+++ b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp
@@ -171,7 +171,7 @@ void CdbSymbolGroupContext::populateINameIndexMap(const QString &prefix, unsigne
     }
 }
 
-QString CdbSymbolGroupContext::toString() const
+QString CdbSymbolGroupContext::toString(bool verbose) const
 {
     QString rc;
     QTextStream str(&rc);
@@ -186,10 +186,12 @@ QString CdbSymbolGroupContext::toString() const
             str << " '" << getSymbolString(m_symbolGroup, &IDebugSymbolGroup2::GetSymbolTypeNameWide, i);
         str << p << '\n';
     }
-    str << "NameIndexMap\n";
-    NameIndexMap::const_iterator ncend = m_inameIndexMap.constEnd();
-    for (NameIndexMap::const_iterator it = m_inameIndexMap.constBegin() ; it != ncend; ++it)
-        str << it.key() << ' ' << it.value() << '\n';
+    if (verbose) {
+        str << "NameIndexMap\n";
+        NameIndexMap::const_iterator ncend = m_inameIndexMap.constEnd();
+        for (NameIndexMap::const_iterator it = m_inameIndexMap.constBegin() ; it != ncend; ++it)
+            str << it.key() << ' ' << it.value() << '\n';
+    }
     return rc;
 }
 
@@ -301,7 +303,7 @@ bool CdbSymbolGroupContext::expandSymbol(const QString &prefix, unsigned long in
             it.value() += newSymbolCount;
     // insert the new symbols
     populateINameIndexMap(prefix, index, index + 1, newSymbolCount);
-    if (debugCDB)
+    if (debugCDB > 1)
         qDebug() << '<' << Q_FUNC_INFO << '\n' << prefix << index << '\n' << toString();
     return true;
 }
@@ -397,17 +399,16 @@ private:
 static bool insertChildrenRecursion(const QString &iname,
                                     CdbSymbolGroupContext *sg,
                                     WatchHandler *watchHandler,
-                                    int visibleLevel,
+                                    bool forceRecursion,
                                     int level,
                                     QString *errorMessage,
                                     int *childCount = 0);
 
-// Insert a symbol and its children recursively if
-// they are known.
+// Insert a symbol (and its first level children depending on forceRecursion)
 static bool insertSymbolRecursion(WatchData wd,
                                   CdbSymbolGroupContext *sg,
                                   WatchHandler *watchHandler,
-                                  int visibleLevel,
+                                  bool forceRecursion,
                                   int level,
                                   QString *errorMessage)
 {    
@@ -415,29 +416,24 @@ static bool insertSymbolRecursion(WatchData wd,
         *errorMessage = QString::fromLatin1("Max recursion level %1 reached for '%2', bailing out.").arg(level).arg(wd.iname);
         return false;
     }
-
-    // Find out whether to recurse (either children are already
-    // available in the context or the parent item is visible
-    // in the view (which means its children must be complete)
-    // or the view item is expanded).
-    bool recurse = false;
-    if (wd.childCount || wd.isChildrenNeeded()) {
-        const bool contextExpanded = sg->isExpanded(wd.iname);
-        const bool viewExpanded = watchHandler->isExpandedIName(wd.iname);        
-        if (viewExpanded)
-            visibleLevel = level;
-        recurse = contextExpanded || (level - visibleLevel < 2);
-    }
+    // Find out whether to recurse (has children or at least knows it has children)
+    const bool recurse = forceRecursion && (wd.childCount > 0 || wd.isChildrenNeeded());
     if (debugCDB)
-        qDebug() << Q_FUNC_INFO << '\n' << wd.iname << "level=" << level << "visibleLevel=" << visibleLevel << "recurse=" << recurse;
+        qDebug() << Q_FUNC_INFO << '\n' << wd.iname << "level=" << level <<  "recurse=" << recurse;
     bool rc = true;
     if (recurse) { // Determine number of children and indicate in model
         int childCount;
-        rc = insertChildrenRecursion(wd.iname, sg, watchHandler, visibleLevel, level, errorMessage, &childCount);
+        rc = insertChildrenRecursion(wd.iname, sg, watchHandler, false, level, errorMessage, &childCount);
         if (rc) {
             wd.setChildCount(childCount);
             wd.setChildrenUnneeded();
         }
+    } else {
+        // No further recursion at this level, pretend entry is complete
+        if (wd.isChildrenNeeded()) {
+            wd.setChildCount(1);
+            wd.setChildrenUnneeded();
+        }
     }
     if (debugCDB)
         qDebug() << " INSERTING: at " << level << wd.toString();
@@ -449,7 +445,7 @@ static bool insertSymbolRecursion(WatchData wd,
 static bool insertChildrenRecursion(const QString &iname,
                                     CdbSymbolGroupContext *sg,
                                     WatchHandler *watchHandler,
-                                    int visibleLevel,
+                                    bool forceRecursion,
                                     int level,
                                     QString *errorMessage,
                                     int *childCountPtr)
@@ -458,7 +454,7 @@ static bool insertChildrenRecursion(const QString &iname,
         qDebug() << Q_FUNC_INFO << '\n' << iname << level;
 
     QList<WatchData> watchList;
-    // Implicitly enforces expansion
+    // This implicitly enforces expansion
     if (!sg->getChildSymbols(iname, WatchDataBackInserter(watchList), errorMessage))
         return false;
 
@@ -469,7 +465,7 @@ static bool insertChildrenRecursion(const QString &iname,
     for (int c = 0; c < childCount; c++) {
         const WatchData &wd = watchList.at(c);
         if (wd.isValid()) { // We sometimes get empty names for deeply nested data
-            if (!insertSymbolRecursion(wd, sg, watchHandler, visibleLevel, level + 1, errorMessage))
+            if (!insertSymbolRecursion(wd, sg, watchHandler, forceRecursion, level + 1, errorMessage))
                 return false;
             succeededChildCount++;
         }  else {
@@ -493,28 +489,17 @@ bool CdbSymbolGroupContext::populateModelInitially(CdbSymbolGroupContext *sg,
     if (!sg->expandTopLevel(errorMessage))
         return false;
 
-    // Insert root items and known children.
+    // Insert root items and known children of level 1
     QList<WatchData> watchList;
     if (!sg->getChildSymbols(sg->prefix(), WatchDataBackInserter(watchList), errorMessage))
         return false;
 
     foreach(const WatchData &wd, watchList)
-        if (!insertSymbolRecursion(wd, sg, watchHandler, 0, 0, errorMessage))
+        if (!insertSymbolRecursion(wd, sg, watchHandler, true, 0, errorMessage))
             return false;
     return true;
 }
 
-static inline QString parentIName(QString iname)
-{
-    const int lastDotPos = iname.lastIndexOf(QLatin1Char('.'));
-    if (lastDotPos == -1) {
-        iname.clear();
-    } else {
-        iname.truncate(lastDotPos);
-    }
-    return iname;
-}
-
 bool CdbSymbolGroupContext::completeModel(CdbSymbolGroupContext *sg,
                                           WatchHandler *watchHandler,
                                           QString *errorMessage)
@@ -522,21 +507,21 @@ bool CdbSymbolGroupContext::completeModel(CdbSymbolGroupContext *sg,
     const QList<WatchData> incomplete = watchHandler->takeCurrentIncompletes();
     if (debugCDB)
         qDebug().nospace() << "###>" << Q_FUNC_INFO << ' ' << incomplete.size() << '\n';
-    // At this point, it should be nodes with unknown children.
-    // Complete and re-insert provided their grand parent is expanded
-    // (rule being that children are displayed only if they are complete, that is,
-    // their children are known).
-    foreach(WatchData wd, incomplete) {
-        const bool grandParentExpanded = watchHandler->isExpandedIName(parentIName(parentIName(wd.iname)));
+    // The view reinserts any node being expanded with flag 'ChildrenNeeded'.
+    // Expand next level in context unless this is already the case.
+    foreach(WatchData wd, incomplete) {        
+        const bool contextExpanded = sg->isExpanded(wd.iname);
         if (debugCDB)
-            qDebug() << "  " << wd.iname << "grandParentExpanded=" << grandParentExpanded;
-        if (grandParentExpanded) {
-            if (!insertSymbolRecursion(wd, sg, watchHandler, 0, 1, errorMessage))
+            qDebug() << "  " << wd.iname << "CE=" << contextExpanded;
+        if (contextExpanded) { // You know that already.
+            wd.setChildrenUnneeded();
+            watchHandler->insertData(wd);
+        } else {
+            if (!insertSymbolRecursion(wd, sg, watchHandler, true, 0, errorMessage))
                 return false;
         }
     }
-    if (debugCDB)
-        qDebug() << "###<" << Q_FUNC_INFO;
+    watchHandler->rebuildModel();
     return true;
 }
 
diff --git a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.h b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.h
index f7fba92f6056257db7b06ed10d0d818c01e65a3b..50bc01d588133b2fa7b9584642de0fd76d3258b6 100644
--- a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.h
+++ b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.h
@@ -93,7 +93,7 @@ private:
 
     bool init(QString *errorMessage);
     void clear();
-    QString toString() const;
+    QString toString(bool verbose = false) const;
     bool getChildSymbolsPosition(const QString &prefix,
                                  unsigned long *startPos,
                                  unsigned long *parentId,
diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp
index 561397ed36e47c34abc150a9f196f6f745d79710..971eb1e8d9c3fe5294602ccee2dd80ef0bf9b1ec 100644
--- a/src/plugins/debugger/debuggermanager.cpp
+++ b/src/plugins/debugger/debuggermanager.cpp
@@ -1053,6 +1053,15 @@ void DebuggerManager::sessionLoaded()
     loadSessionData();
 }
 
+void DebuggerManager::sessionUnloaded()
+{
+    cleanupViews();
+    if (m_engine)
+        m_engine->shutdown();
+    setStatus(DebuggerProcessNotReady);
+    setBusyCursor(false);
+}
+
 void DebuggerManager::aboutToSaveSession()
 {
     saveSessionData();
diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h
index 4d9351d951d459ccd5fe0f565f4c52eb89841dc8..fb6bc9e36cfe2dee111d7df59282852dfbb7c94d 100644
--- a/src/plugins/debugger/debuggermanager.h
+++ b/src/plugins/debugger/debuggermanager.h
@@ -233,6 +233,7 @@ public slots:
     void updateWatchModel();
     
     void sessionLoaded();
+    void sessionUnloaded();
     void aboutToSaveSession();
 
     void assignValueInDebugger();
diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp
index 1046a9307bab311891471c6b6d897a4ea5c46075..2ecd00ffc2ad1a997bf7b1c1aa5608d1a9552752 100644
--- a/src/plugins/debugger/debuggerplugin.cpp
+++ b/src/plugins/debugger/debuggerplugin.cpp
@@ -752,6 +752,8 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess
        m_manager, SLOT(sessionLoaded()));
     connect(sessionManager(), SIGNAL(aboutToSaveSession()),
        m_manager, SLOT(aboutToSaveSession()));
+    connect(sessionManager(), SIGNAL(sessionUnloaded()),
+       m_manager, SLOT(sessionUnloaded()));
 
     // EditorManager
     QObject *editorManager = core->editorManager();
diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp
index c206831ad076b6fd6d0a97f8d3574bf0c145c025..17cb99081acaae01620b9ad178dbca6359bc012c 100644
--- a/src/plugins/debugger/gdbengine.cpp
+++ b/src/plugins/debugger/gdbengine.cpp
@@ -389,6 +389,19 @@ void GdbEngine::handleResponse(const QByteArray &buff)
                 handleAsyncOutput(record);
             } else if (asyncClass == "running") {
                 // Archer has 'thread-id="all"' here
+            } else if (asyncClass == "library-loaded") {
+                // Archer has 'id="/usr/lib/libdrm.so.2",
+                // target-name="/usr/lib/libdrm.so.2",
+                // host-name="/usr/lib/libdrm.so.2",
+                // symbols-loaded="0"
+            } else if (asyncClass == "thread-group-created") {
+                // Archer has "{id="28902"}" 
+            } else if (asyncClass == "thread-created") {
+                //"{id="1",group-id="28902"}" 
+            } else if (asyncClass == "thread-group-exited") {
+                // Archer has "{id="28902"}" 
+            } else if (asyncClass == "thread-exited") {
+                //"{id="1",group-id="28902"}" 
             #ifdef Q_OS_MAC
             } else if (asyncClass == "shlibs-updated") {
                 // MAC announces updated libs
diff --git a/src/plugins/debugger/registerhandler.h b/src/plugins/debugger/registerhandler.h
index 8c38c1544e7e516e631faa8eae7beee82e37e64f..57e138b2edd09d4bdde702920a9858610ad22502 100644
--- a/src/plugins/debugger/registerhandler.h
+++ b/src/plugins/debugger/registerhandler.h
@@ -54,7 +54,6 @@ class RegisterHandler : public QAbstractTableModel
 public:
     RegisterHandler(QObject *parent = 0);
 
-    void sessionClosed();
     QAbstractItemModel *model() { return this; }
 
     bool isEmpty() const; // nothing known so far?
diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp
index e9a651e622fe31b9abdc44f758fe0bc2f5d6d3aa..9458bac9f3800aeb69efa9cbed9502e300230f8b 100644
--- a/src/plugins/debugger/watchhandler.cpp
+++ b/src/plugins/debugger/watchhandler.cpp
@@ -202,6 +202,8 @@ QString WatchData::toString() const
          str << "parent=\"" << parentIndex << doubleQuoteComma;
     if (row != -1)
          str << "row=\"" << row << doubleQuoteComma;
+    if (childCount)
+         str << "childCount=\"" << childCount << doubleQuoteComma;
     if (const int childCount = childIndex.size()) {
         str << "child=\"";
         for (int i = 0; i < childCount; i++) {
diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp
index cc23eb100fa0b3bcaa46d8ca23a59dfb9aa82475..e2d777e8c4508e9a6a5d8b1dfee73a5db52b3195 100644
--- a/src/plugins/fakevim/fakevimhandler.cpp
+++ b/src/plugins/fakevim/fakevimhandler.cpp
@@ -29,7 +29,7 @@
 
 #include "fakevimhandler.h"
 
-// Please do not add any direct dependencies to other Qt Creator code  here. 
+// Please do not add any direct dependencies to other Qt Creator code  here.
 // Instead emit signals and let the FakeVimPlugin channel the information to
 // Qt Creator. The idea is to keep this file here in a "clean" state that
 // allows easy reuse with any QTextEdit or QPlainTextEdit derived class.
@@ -112,6 +112,7 @@ const int ParagraphSeparator = 0x00002029;
 
 using namespace Qt;
 
+
 enum Mode
 {
     InsertMode,
@@ -184,11 +185,11 @@ QDebug &operator<<(QDebug &ts, const EditOperation &op)
 
 QDebug &operator<<(QDebug &ts, const QList<QTextEdit::ExtraSelection> &sels)
 {
-    foreach (QTextEdit::ExtraSelection sel, sels) 
-        ts << "SEL: " << sel.cursor.anchor() << sel.cursor.position(); 
+    foreach (QTextEdit::ExtraSelection sel, sels)
+        ts << "SEL: " << sel.cursor.anchor() << sel.cursor.position();
     return ts;
 }
-        
+
 int lineCount(const QString &text)
 {
     //return text.count(QChar(ParagraphSeparator));
@@ -202,6 +203,8 @@ enum EventResult
     EventPassedToCore
 };
 
+class UndoBreaker;
+
 class FakeVimHandler::Private
 {
 public:
@@ -215,8 +218,8 @@ public:
     void setupWidget();
     void restoreWidget();
 
-private:
     friend class FakeVimHandler;
+    friend class UndoBreaker;
     static int shift(int key) { return key + 32; }
     static int control(int key) { return key + 256; }
 
@@ -313,7 +316,7 @@ public:
     int m_subsubdata;
     QString m_input;
     QTextCursor m_tc;
-    int m_anchor; 
+    int m_anchor;
     QHash<int, QString> m_registers;
     int m_register;
     QString m_mvcount;
@@ -333,28 +336,16 @@ public:
     bool m_lastSearchForward;
     QString m_lastInsertion;
 
-    // undo handling
-    void recordOperation(const EditOperation &op);
-    void recordInsert(int position, const QString &data);
-    void recordRemove(int position, const QString &data);
-    void recordRemove(int position, int length);
-
-    void recordRemoveNextChar();
-    void recordInsertText(const QString &data);
-    QString recordRemoveSelectedText();
-    void recordPosition();
-    void recordBeginGroup();
-    void recordEndGroup();
+    QString removeSelectedText();
     int anchor() const { return m_anchor; }
     int position() const { return m_tc.position(); }
     QString selectedText() const;
 
+    // undo handling
     void undo();
     void redo();
-    QStack<EditOperation> m_undoStack;
-    QStack<EditOperation> m_redoStack;
-    QStack<int> m_undoGroupStack;
-    QMap<int, int> m_undoCursorPosition;
+    QMap<int, int> m_undoCursorPosition; // revision -> position
+    bool m_needMoreUndo;
 
     // extra data for '.'
     QString m_dotCommand;
@@ -396,6 +387,7 @@ public:
     int m_cursorWidth;
 
     void recordJump();
+    void recordNewUndo();
     QList<int> m_jumpListUndo;
     QList<int> m_jumpListRedo;
 
@@ -515,7 +507,6 @@ EventResult FakeVimHandler::Private::handleEvent(QKeyEvent *ev)
         moveLeft();
 
     EDITOR(setTextCursor(m_tc));
-    //EDITOR(ensureCursorVisible());
     return result;
 }
 
@@ -534,7 +525,7 @@ void FakeVimHandler::Private::setupWidget()
         m_plaintextedit->setLineWrapMode(QPlainTextEdit::NoWrap);
     }
     m_wasReadOnly = EDITOR(isReadOnly());
-    //EDITOR(setReadOnly(true)); 
+    //EDITOR(setReadOnly(true));
 
     QTextCursor tc = EDITOR(textCursor());
     if (tc.hasSelection()) {
@@ -562,7 +553,7 @@ void FakeVimHandler::Private::restoreWidget()
     EDITOR(setReadOnly(m_wasReadOnly));
     EDITOR(setCursorWidth(m_cursorWidth));
     EDITOR(setOverwriteMode(false));
-    
+
     if (m_visualMode == VisualLineMode) {
         m_tc = EDITOR(textCursor());
         int beginLine = lineForPosition(m_marks['<']);
@@ -621,7 +612,7 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommand)
            m_anchor++;
         if (!dotCommand.isEmpty())
             m_dotCommand = "c" + dotCommand;
-        QString text = recordRemoveSelectedText();
+        QString text = removeSelectedText();
         //qDebug() << "CHANGING TO INSERT MODE" << text;
         m_registers[m_register] = text;
         m_mode = InsertMode;
@@ -633,8 +624,7 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommand)
            m_anchor++;
         if (!dotCommand.isEmpty())
             m_dotCommand = "d" + dotCommand;
-        m_registers[m_register] = recordRemoveSelectedText();
-        recordEndGroup();
+        m_registers[m_register] = removeSelectedText();
         m_submode = NoSubMode;
         if (atEndOfLine())
             moveLeft();
@@ -648,10 +638,12 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommand)
         indentRegion();
         m_submode = NoSubMode;
     } else if (m_submode == ShiftRightSubMode) {
+        recordJump();
         shiftRegionRight(1);
         m_submode = NoSubMode;
         updateMiniBuffer();
     } else if (m_submode == ShiftLeftSubMode) {
+        recordJump();
         shiftRegionLeft(1);
         m_submode = NoSubMode;
         updateMiniBuffer();
@@ -881,12 +873,10 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
     } else if (m_submode == ReplaceSubMode) {
         if (count() < rightDist() && text.size() == 1
                 && (text.at(0).isPrint() || text.at(0).isSpace())) {
-            recordBeginGroup();
             setAnchor();
             moveRight(count());
-            recordRemoveSelectedText();
-            recordInsertText(QString(count(), text.at(0)));
-            recordEndGroup();
+            removeSelectedText();
+            m_tc.insertText(QString(count(), text.at(0)));
             m_moveType = MoveExclusive;
             m_submode = NoSubMode;
             m_dotCommand = QString("%1r%2").arg(count()).arg(text);
@@ -1027,7 +1017,6 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
         finishMovement();
     } else if (key == 'a') {
         m_mode = InsertMode;
-        recordBeginGroup();
         m_lastInsertion.clear();
         if (!atEndOfLine())
             moveRight();
@@ -1035,7 +1024,6 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
     } else if (key == 'A') {
         m_mode = InsertMode;
         moveToEndOfLine();
-        recordBeginGroup();
         m_lastInsertion.clear();
     } else if (key == 'b') {
         m_moveType = MoveExclusive;
@@ -1047,30 +1035,25 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
         finishMovement();
     } else if (key == 'c' && m_visualMode == NoVisualMode) {
         setAnchor();
-        recordBeginGroup();
         m_submode = ChangeSubMode;
-    } else if (key == 'c' && m_visualMode == VisualCharMode) { 
-        recordBeginGroup();
+    } else if (key == 'c' && m_visualMode == VisualCharMode) {
         leaveVisualMode();
         m_submode = ChangeSubMode;
         finishMovement();
     } else if (key == 'C') {
         setAnchor();
-        recordBeginGroup();
         moveToEndOfLine();
-        m_registers[m_register] = recordRemoveSelectedText();
+        m_registers[m_register] = removeSelectedText();
         m_mode = InsertMode;
         finishMovement();
     } else if (key == 'd' && m_visualMode == NoVisualMode) {
         if (atEndOfLine())
             moveLeft();
         setAnchor();
-        recordBeginGroup();
         m_opcount = m_mvcount;
         m_mvcount.clear();
         m_submode = DeleteSubMode;
-    } else if ((key == 'd' || key == 'x') && m_visualMode == VisualCharMode) { 
-        recordBeginGroup();
+    } else if ((key == 'd' || key == 'x') && m_visualMode == VisualCharMode) {
         leaveVisualMode();
         m_submode = DeleteSubMode;
         finishMovement();
@@ -1079,10 +1062,9 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
         int beginLine = lineForPosition(m_marks['<']);
         int endLine = lineForPosition(m_marks['>']);
         selectRange(beginLine, endLine);
-        m_registers[m_register] = recordRemoveSelectedText();
+        m_registers[m_register] = removeSelectedText();
     } else if (key == 'D') {
         setAnchor();
-        recordBeginGroup();
         m_submode = DeleteSubMode;
         moveDown(qMax(count() - 1, 0));
         m_moveType = MoveExclusive;
@@ -1146,14 +1128,12 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
         moveToFirstNonBlankOnLine();
         finishMovement();
     } else if (key == 'i') {
-        recordBeginGroup();
         m_dotCommand = "i"; //QString("%1i").arg(count());
         enterInsertMode();
         updateMiniBuffer();
         if (atEndOfLine())
             moveLeft();
     } else if (key == 'I') {
-        recordBeginGroup();
         m_dotCommand = "I"; //QString("%1I").arg(count());
         enterInsertMode();
         if (m_gflag)
@@ -1182,20 +1162,20 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
         finishMovement("j");
         m_desiredColumn = savedColumn;
     } else if (key == 'J') {
-        recordBeginGroup();
         if (m_submode == NoSubMode) {
             for (int i = qMax(count(), 2) - 1; --i >= 0; ) {
                 moveToEndOfLine();
-                recordRemoveNextChar();
+                setAnchor();
+                moveRight();
                 while (characterAtCursor() == ' ')
-                    recordRemoveNextChar();
+                    moveRight();
+                removeSelectedText();
                 if (!m_gflag)
-                    recordInsertText(" ");
+                    m_tc.insertText(" ");
             }
             if (!m_gflag)
                 moveLeft();
         }
-        recordEndGroup();
     } else if (key == 'k' || key == Key_Up) {
         int savedColumn = m_desiredColumn;
         if (m_submode == NoSubMode || m_submode == ZSubMode
@@ -1235,8 +1215,6 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
         search(lastSearchString(), !m_lastSearchForward);
         recordJump();
     } else if (key == 'o' || key == 'O') {
-        recordBeginGroup();
-        recordPosition();
         m_dotCommand = QString("%1o").arg(count());
         enterInsertMode();
         moveToFirstNonBlankOnLine();
@@ -1244,31 +1222,29 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
         if (key == 'O')
             moveUp();
         moveToEndOfLine();
-        recordInsertText("\n");
+        m_tc.insertText("\n");
         moveToStartOfLine();
         if (0 && hasConfig(ConfigAutoIndent))
-            recordInsertText(QString(indentDist(), ' '));
+            m_tc.insertText(QString(indentDist(), ' '));
         else
-            recordInsertText(QString(numSpaces, ' '));
+            m_tc.insertText(QString(numSpaces, ' '));
     } else if (key == control('o')) {
         if (!m_jumpListUndo.isEmpty()) {
             m_jumpListRedo.append(position());
             setPosition(m_jumpListUndo.takeLast());
         }
     } else if (key == 'p' || key == 'P') {
-        recordBeginGroup();
         QString text = m_registers[m_register];
         int n = lineCount(text);
         //qDebug() << "REGISTERS: " << m_registers << "MOVE: " << m_moveType;
         //qDebug() << "LINES: " << n << text << m_register;
         if (n > 0) {
-            recordPosition();
             moveToStartOfLine();
             m_desiredColumn = 0;
             for (int i = count(); --i >= 0; ) {
                 if (key == 'p')
                     moveDown();
-                recordInsertText(text);
+                m_tc.insertText(text);
                 moveUp(n);
             }
         } else {
@@ -1276,20 +1252,18 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
             for (int i = count(); --i >= 0; ) {
                 if (key == 'p')
                     moveRight();
-                recordInsertText(text);
+                m_tc.insertText(text);
                 moveLeft();
             }
         }
-        recordEndGroup();
         m_dotCommand = QString("%1p").arg(count());
         finishMovement();
     } else if (key == 'r') {
         m_submode = ReplaceSubMode;
         m_dotCommand = "r";
     } else if (key == 'R') {
-        // FIXME: right now we repeat the insertion count() times, 
+        // FIXME: right now we repeat the insertion count() times,
         // but not the deletion
-        recordBeginGroup();
         m_lastInsertion.clear();
         m_mode = InsertMode;
         m_submode = ReplaceSubMode;
@@ -1297,10 +1271,11 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
     } else if (key == control('r')) {
         redo();
     } else if (key == 's') {
-        recordBeginGroup();
+        if (atEndOfLine())
+            moveLeft();
         setAnchor();
         moveRight(qMin(count(), rightDist()));
-        m_registers[m_register] = recordRemoveSelectedText();
+        m_registers[m_register] = removeSelectedText();
         m_dotCommand = "s"; //QString("%1s").arg(count());
         m_opcount.clear();
         m_mvcount.clear();
@@ -1352,7 +1327,6 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
         m_moveType = MoveExclusive;
         if (atEndOfLine())
             moveLeft();
-        recordBeginGroup();
         setAnchor();
         m_submode = DeleteSubMode;
         moveRight(qMin(count(), rightDist()));
@@ -1362,14 +1336,13 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
         if (leftDist() > 0) {
             setAnchor();
             moveLeft(qMin(count(), leftDist()));
-            m_registers[m_register] = recordRemoveSelectedText();
+            m_registers[m_register] = removeSelectedText();
         }
         finishMovement();
     } else if (key == 'y' && m_visualMode == NoVisualMode) {
         m_savedYankPosition = m_tc.position();
         if (atEndOfLine())
             moveLeft();
-        recordBeginGroup();
         setAnchor();
         m_submode = YankSubMode;
     } else if (key == 'y' && m_visualMode == VisualLineMode) {
@@ -1388,19 +1361,16 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
         m_moveType = MoveLineWise;
         finishMovement();
     } else if (key == 'z') {
-        recordBeginGroup();
         m_submode = ZSubMode;
     } else if (key == '~' && !atEndOfLine()) {
-        recordBeginGroup();
         setAnchor();
         moveRight(qMin(count(), rightDist()));
-        QString str = recordRemoveSelectedText();
+        QString str = removeSelectedText();
         for (int i = str.size(); --i >= 0; ) {
             QChar c = str.at(i);
             str[i] = c.isUpper() ? c.toLower() : c.toUpper();
         }
-        recordInsertText(str);
-        recordEndGroup();
+        m_tc.insertText(str);
     } else if (key == Key_PageDown || key == control('f')) {
         moveDown(count() * (linesOnScreen() - 2) - cursorLineOnScreen());
         scrollToLineInDocument(cursorLineInDocument());
@@ -1414,7 +1384,7 @@ EventResult FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
     } else if (key == Key_Delete) {
         setAnchor();
         moveRight(qMin(1, rightDist()));
-        recordRemoveSelectedText();
+        removeSelectedText();
     } else if (key == Key_Escape) {
         if (m_visualMode != NoVisualMode) {
             leaveVisualMode();
@@ -1443,12 +1413,10 @@ EventResult FakeVimHandler::Private::handleInsertMode(int key, int,
             m_tc.insertText(m_lastInsertion);
             data += m_lastInsertion;
         }
-        recordInsert(m_tc.position() - m_lastInsertion.size(), data);
-        recordEndGroup();
-        //qDebug() << "UNDO: " << m_undoStack;
         moveLeft(qMin(1, leftDist()));
         m_dotCommand += m_lastInsertion;
         m_dotCommand += QChar(27);
+        recordNewUndo();
         enterCommandMode();
     } else if (key == Key_Left) {
         moveLeft(count());
@@ -1505,8 +1473,8 @@ EventResult FakeVimHandler::Private::handleInsertMode(int key, int,
             if (leftText.simplified().isEmpty())
                 indentRegion(text.at(0));
         }
-       
-        if (!m_inReplay) 
+
+        if (!m_inReplay)
             emit q->completionRequested();
     } else {
         return EventUnhandled;
@@ -1602,7 +1570,7 @@ int FakeVimHandler::Private::readLineCode(QString &cmd)
         return linesInDocument();
     if (c == '\'' && !cmd.isEmpty()) {
         int mark = m_marks.value(cmd.at(0).unicode());
-        if (!mark) { 
+        if (!mark) {
             showRedMessage(tr("E20: Mark '%1' not set").arg(cmd.at(0)));
             cmd = cmd.mid(1);
             return -1;
@@ -1666,7 +1634,7 @@ void FakeVimHandler::Private::handleExCommand(const QString &cmd0)
     QString cmd = cmd0;
     if (cmd.startsWith("%"))
         cmd = "1,$" + cmd.mid(1);
-    
+
     int beginLine = -1;
     int endLine = -1;
 
@@ -1698,7 +1666,7 @@ void FakeVimHandler::Private::handleExCommand(const QString &cmd0)
     } else if (reDelete.indexIn(cmd) != -1) { // :d
         selectRange(beginLine, endLine);
         QString reg = reDelete.cap(2);
-        QString text = recordRemoveSelectedText(); 
+        QString text = removeSelectedText();
         if (!reg.isEmpty())
             m_registers[reg.at(0).unicode()] = text;
     } else if (reWrite.indexIn(cmd) != -1) { // :w
@@ -1721,7 +1689,7 @@ void FakeVimHandler::Private::handleExCommand(const QString &cmd0)
             file1.close();
             QTextCursor tc = m_tc;
             selectRange(beginLine, endLine);
-            QString contents = selectedText(); 
+            QString contents = selectedText();
             m_tc = tc;
             qDebug() << "LINES: " << beginLine << endLine;
             bool handled = false;
@@ -1761,8 +1729,7 @@ void FakeVimHandler::Private::handleExCommand(const QString &cmd0)
     } else if (cmd.startsWith("!")) {
         selectRange(beginLine, endLine);
         QString command = cmd.mid(1).trimmed();
-        recordBeginGroup();
-        QString text = recordRemoveSelectedText();
+        QString text = removeSelectedText();
         QProcess proc;
         proc.start(cmd.mid(1));
         proc.waitForStarted();
@@ -1770,18 +1737,9 @@ void FakeVimHandler::Private::handleExCommand(const QString &cmd0)
         proc.closeWriteChannel();
         proc.waitForFinished();
         QString result = QString::fromUtf8(proc.readAllStandardOutput());
-        recordInsertText(result);
-        recordEndGroup();
+        m_tc.insertText(result);
         leaveVisualMode();
-
         setPosition(firstPositionInLine(beginLine));
-        EditOperation op;
-        // FIXME: broken for "upward selection"
-        op.position = m_tc.position();
-        op.from = text;
-        op.to = result;
-        recordOperation(op);
-
         enterCommandMode();
         //qDebug() << "FILTER: " << command;
         showBlackMessage(tr("%1 lines filtered").arg(text.count('\n')));
@@ -1985,18 +1943,15 @@ void FakeVimHandler::Private::shiftRegionRight(int repeat)
     QString indent(len, ' ');
     int firstPos = firstPositionInLine(beginLine);
 
-    recordBeginGroup();
     //setPosition(firstPos);
-    //recordPosition();
 
     for (int line = beginLine; line <= endLine; ++line) {
         setPosition(firstPositionInLine(line));
-        recordInsertText(indent);
+        m_tc.insertText(indent);
     }
 
     setPosition(firstPos);
     moveToFirstNonBlankOnLine();
-    recordEndGroup();
     m_dotCommand = QString("%1>>").arg(endLine - beginLine + 1);
 }
 
@@ -2010,9 +1965,7 @@ void FakeVimHandler::Private::shiftRegionLeft(int repeat)
     int tab = config(ConfigTabStop).toInt();
     int firstPos = firstPositionInLine(beginLine);
 
-    recordBeginGroup();
     //setPosition(firstPos);
-    //recordPosition();
 
     for (int line = beginLine; line <= endLine; ++line) {
         int pos = firstPositionInLine(line);
@@ -2030,13 +1983,12 @@ void FakeVimHandler::Private::shiftRegionLeft(int repeat)
                 break;
         }
         setPosition(pos + i);
-        text = recordRemoveSelectedText();
+        text = removeSelectedText();
         setPosition(pos);
     }
 
     setPosition(firstPos);
     moveToFirstNonBlankOnLine();
-    recordEndGroup();
     m_dotCommand = QString("%1<<").arg(endLine - beginLine + 1);
 }
 
@@ -2260,174 +2212,51 @@ QWidget *FakeVimHandler::Private::editor() const
 
 void FakeVimHandler::Private::undo()
 {
+    int current = EDITOR(document())->revision();
+    m_tc.endEditBlock();
+    m_needMoreUndo = false;
     EDITOR(undo());
+    if (m_needMoreUndo)
+        EDITOR(undo());
+    m_tc.beginEditBlock();
     int rev = EDITOR(document())->revision();
-    if (m_undoCursorPosition.contains(rev))
-        m_tc.setPosition(m_undoCursorPosition[rev]);
-#if 0
-    if (m_undoStack.isEmpty()) {
+    if (current == rev)
         showBlackMessage(tr("Already at oldest change"));
-    } else {
-        EditOperation op = m_undoStack.pop();
-        //qDebug() << "UNDO " << op;
-        if (op.itemCount > 0) {
-            for (int i = op.itemCount; --i >= 0; )
-                undo();
-        } else {
-            m_tc.setPosition(op.position, MoveAnchor);
-            if (!op.to.isEmpty()) {
-                m_tc.setPosition(op.position + op.to.size(), KeepAnchor);
-                m_tc.removeSelectedText();
-            }
-            if (!op.from.isEmpty())
-                m_tc.insertText(op.from);
-            m_tc.setPosition(op.position, MoveAnchor);
-        }
-        m_redoStack.push(op);
+    else
         showBlackMessage(QString());
-    }
-#endif
+    if (m_undoCursorPosition.contains(rev))
+        m_tc.setPosition(m_undoCursorPosition[rev]);
 }
 
 void FakeVimHandler::Private::redo()
 {
     int current = EDITOR(document())->revision();
+    m_tc.endEditBlock();
+    m_needMoreUndo = false;
     EDITOR(redo());
+    if (m_needMoreUndo)
+        EDITOR(redo());
+    m_tc.beginEditBlock();
     int rev = EDITOR(document())->revision();
-    if (rev == current) {
+    if (rev == current)
         showBlackMessage(tr("Already at newest change"));
-    } else {
-        showBlackMessage(QString());
-        if (m_undoCursorPosition.contains(rev))
-            m_tc.setPosition(m_undoCursorPosition[rev]);
-    }
-#if 0
-    if (m_redoStack.isEmpty()) {
-        showBlackMessage(tr("Already at newest change"));
-    } else {
-        EditOperation op = m_redoStack.pop();
-        //qDebug() << "REDO " << op;
-        if (op.itemCount > 0) {
-            for (int i = op.itemCount; --i >= 0; )
-                redo();
-        } else {
-            m_tc.setPosition(op.position, MoveAnchor);
-            if (!op.from.isEmpty()) {
-                m_tc.setPosition(op.position + op.from.size(), KeepAnchor);
-                m_tc.removeSelectedText();
-            }
-            if (!op.to.isEmpty())
-                m_tc.insertText(op.to);
-            m_tc.setPosition(op.position, MoveAnchor);
-        }
-        m_undoStack.push(op);
+    else
         showBlackMessage(QString());
-    }
-#endif
-}
-
-void FakeVimHandler::Private::recordBeginGroup()
-{
-    //qDebug() << "PUSH";
-    m_undoGroupStack.push(m_undoStack.size());
-    EditOperation op;
-    op.position = m_tc.position();
-    recordOperation(op);
-}
-
-void FakeVimHandler::Private::recordEndGroup()
-{
-    if (m_undoGroupStack.isEmpty()) {
-        qWarning("fakevim: undo groups not balanced.\n");
-        return;
-    }
-    EditOperation op;
-    op.itemCount = m_undoStack.size() - m_undoGroupStack.pop();
-    //qDebug() << "POP " << op.itemCount << m_undoStack;
-    recordOperation(op);
+    if (m_undoCursorPosition.contains(rev))
+        m_tc.setPosition(m_undoCursorPosition[rev]);
 }
 
-QString FakeVimHandler::Private::recordRemoveSelectedText()
+QString FakeVimHandler::Private::removeSelectedText()
 {
-    EditOperation op;
     //qDebug() << "POS: " << position() << " ANCHOR: " << anchor() << m_tc.anchor();
     int pos = m_tc.position();
     if (pos == anchor())
         return QString();
     m_tc.setPosition(anchor(), MoveAnchor);
     m_tc.setPosition(pos, KeepAnchor);
-    op.position = qMin(pos, anchor());
-    op.from = m_tc.selection().toPlainText();
-    //qDebug() << "OP: " << op;
-    recordOperation(op);
+    QString from = m_tc.selection().toPlainText();
     m_tc.removeSelectedText();
-    return op.from;
-}
-
-void FakeVimHandler::Private::recordRemoveNextChar()
-{
-    setAnchor();
-    moveRight();
-    recordRemoveSelectedText();
-}
-
-void FakeVimHandler::Private::recordInsertText(const QString &data)
-{
-    EditOperation op;
-    op.position = m_tc.position();
-    op.to = data;
-    recordOperation(op);
-    m_tc.insertText(data);
-}
-
-void FakeVimHandler::Private::recordPosition()
-{
-    EditOperation op;
-    op.position = m_tc.position();
-    m_undoStack.push(op);
-    m_redoStack.clear();
-    UNDO_DEBUG("MOVE: " << op);
-    UNDO_DEBUG("\nUNDO STACK: " << m_undoStack << "\n");
-    UNDO_DEBUG("\nREDO STACK: " << m_redoStack << "\n");
-}
-
-void FakeVimHandler::Private::recordOperation(const EditOperation &op)
-{
-    UNDO_DEBUG("RECORD OP: " << op);
-    // No need to record operations that actually do not change anything.
-    if (op.from.isEmpty() && op.to.isEmpty() && op.itemCount == 0)
-        return;
-    // No need to create groups with only one member.
-    if (op.itemCount == 1)
-        return;
-    m_undoStack.push(op);
-    m_redoStack.clear();
-    UNDO_DEBUG("\nUNDO STACK: " << m_undoStack << "\n");
-    UNDO_DEBUG("\nREDO STACK: " << m_redoStack << "\n");
-}
-
-void FakeVimHandler::Private::recordInsert(int position, const QString &data)
-{
-    EditOperation op;
-    op.position = position;
-    op.to = data;
-    recordOperation(op);
-}
-
-void FakeVimHandler::Private::recordRemove(int position, int length)
-{
-    QTextCursor tc = m_tc;
-    tc.setPosition(position, MoveAnchor);
-    tc.setPosition(position + length, KeepAnchor);
-    recordRemove(position, tc.selection().toPlainText());
-}
-
-void FakeVimHandler::Private::recordRemove(int position, const QString &data)
-{
-    EditOperation op;
-    op.position = position;
-    op.from = data;
-    recordOperation(op);
+    return from;
 }
 
 void FakeVimHandler::Private::enterInsertMode()
@@ -2459,6 +2288,21 @@ void FakeVimHandler::Private::recordJump()
     UNDO_DEBUG("jumps: " << m_jumpListUndo);
 }
 
+struct UndoBreaker : public QAbstractUndoItem
+{
+    UndoBreaker(FakeVimHandler::Private *doc) : m_doc(doc) {}
+    void undo() { m_doc->m_needMoreUndo = true; }
+    void redo() { m_doc->m_needMoreUndo = true; }
+    FakeVimHandler::Private *m_doc;
+};
+
+void FakeVimHandler::Private::recordNewUndo()
+{
+    m_tc.endEditBlock();
+    m_tc.document()->appendUndoItem(new UndoBreaker(this));
+    m_tc.beginEditBlock();
+}
+
 
 ///////////////////////////////////////////////////////////////////////
 //
diff --git a/src/plugins/fakevim/fakevimhandler.h b/src/plugins/fakevim/fakevimhandler.h
index 045d1502b5ddf1d8eeda38859e3908dba48877a9..74ec43c97712e9bb41b4ac78fc4b6c6ac0269b63 100644
--- a/src/plugins/fakevim/fakevimhandler.h
+++ b/src/plugins/fakevim/fakevimhandler.h
@@ -73,10 +73,11 @@ signals:
     void indentRegion(int *amount, int beginLine, int endLine, QChar typedChar);
     void completionRequested();
 
+public:
+    class Private;
+
 private:
     bool eventFilter(QObject *ob, QEvent *ev);
-
-    class Private;
     friend class Private;
     Private *d;
 };
diff --git a/src/plugins/projectexplorer/session.cpp b/src/plugins/projectexplorer/session.cpp
index 54d46e2e5bfdf9fe3ff575175455ee6677fd4905..ad09041e9cf52ff5eea8a8cd68eb26605638e535 100644
--- a/src/plugins/projectexplorer/session.cpp
+++ b/src/plugins/projectexplorer/session.cpp
@@ -996,16 +996,16 @@ void SessionManager::removeProjects(QList<Project *> remove)
 
 void SessionManager::setValue(const QString &name, const QVariant &value)
 {
-    m_file->m_values.insert(name, value);
+    if (m_file)
+        m_file->m_values.insert(name, value);
 }
 
 QVariant SessionManager::value(const QString &name)
 {
-    QMap<QString, QVariant>::const_iterator it = m_file->m_values.find(name);
-    if (it != m_file->m_values.constEnd())
-        return *it;
-    else
+    if (!m_file)
         return QVariant();
+    QMap<QString, QVariant>::const_iterator it = m_file->m_values.find(name);
+    return (it == m_file->m_values.constEnd()) ? QVariant() : *it;
 }
 
 QString SessionManager::activeSession() const
diff --git a/src/plugins/qt4projectmanager/qmakestep.cpp b/src/plugins/qt4projectmanager/qmakestep.cpp
index 8171aacc62bdd6bab98a8b6162048e5a38128ee5..37eca5ad3a97612d4fe62bb2a46dbffdb2c66e29 100644
--- a/src/plugins/qt4projectmanager/qmakestep.cpp
+++ b/src/plugins/qt4projectmanager/qmakestep.cpp
@@ -85,7 +85,7 @@ QStringList QMakeStep::arguments(const QString &buildConfiguration)
         if (!(defaultBuildConfiguration & QtVersion::DebugBuild) && (projectBuildConfiguration & QtVersion::DebugBuild))
             configarguments << "CONFIG+=debug";
         if (!configarguments.isEmpty())
-            arguments << "-after" << configarguments;
+            arguments << configarguments;
     } else {
         arguments << "CONFIG+=debug_and_release";
     }
diff --git a/src/plugins/qt4projectmanager/qtversionmanager.cpp b/src/plugins/qt4projectmanager/qtversionmanager.cpp
index c09c169ed5903d922736449ef6943a81cb0a9238..033ae8b1b0d9be05ad7c28ea1c963e96be8c1fe6 100644
--- a/src/plugins/qt4projectmanager/qtversionmanager.cpp
+++ b/src/plugins/qt4projectmanager/qtversionmanager.cpp
@@ -1453,7 +1453,7 @@ QString QtVersion::buildDebuggingHelperLibrary()
 
         output += QString("Building debugging helper library in %1\n").arg(directory);
         output += "\n";
-        output += "Runinng qmake...\n";
+        output += QString("Runinng %1 ...\n").arg(qmakeCommand());
 
         QProcess qmake;
         ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment();
@@ -1487,7 +1487,7 @@ QString QtVersion::buildDebuggingHelperLibrary()
         QString makeFullPath = env.searchInPath(make);
         output += "\n";
         if (!makeFullPath.isEmpty()) {
-            output += QString("Running %1...\n").arg(makeFullPath);
+            output += QString("Running %1 ...\n").arg(makeFullPath);
             qmake.start(makeFullPath, QStringList());
             qmake.waitForFinished();
             output += qmake.readAll();
diff --git a/src/plugins/qtscripteditor/parser/gen.sh b/src/plugins/qtscripteditor/parser/gen.sh
index ebf34b2c2b458d3cc36da5eb88458e6d85685b51..cc4054e06ad5bffd02deb494cbaf3c21137cec17 100644
--- a/src/plugins/qtscripteditor/parser/gen.sh
+++ b/src/plugins/qtscripteditor/parser/gen.sh
@@ -13,6 +13,11 @@ rm -f javascriptlexer_p.h
 rm -f javascriptmemorypool_p.h
 rm -f javascriptnodepool_p.h
 
+rm -f javascriptgrammar_p.h
+rm -f javascriptgrammar.cpp
+rm -f javascriptparser_p.h
+rm -f javascriptparser.cpp
+
 sed -f $me/cmd.sed $QTDIR/src/script/qscript.g > javascript.g
 
 sed -f $me/cmd.sed $QTDIR/src/script/qscriptast.cpp > javascriptast.cpp
@@ -25,7 +30,7 @@ sed -f $me/cmd.sed $QTDIR/src/script/qscriptlexer.cpp > javascriptlexer.cpp
 sed -f $me/cmd.sed $QTDIR/src/script/qscriptmemorypool_p.h > javascriptmemorypool_p.h
 sed -f $me/cmd.sed $QTDIR/src/script/qscriptnodepool_p.h > javascriptnodepool_p.h
 
-qlalr $me/javascript.g
+qlalr --troll --no-lines --no-debug $me/javascript.g
 
 chmod ugo-w javascript.g
 chmod ugo-w javascriptast.cpp
diff --git a/src/plugins/qtscripteditor/parser/javascript.g b/src/plugins/qtscripteditor/parser/javascript.g
index 743e80a1c3db4079b09da8055c1b6f1ac835c2ca..dc23055ae26c6c2f1e265cc60b77d02b9283afd2 100644
--- a/src/plugins/qtscripteditor/parser/javascript.g
+++ b/src/plugins/qtscripteditor/parser/javascript.g
@@ -214,6 +214,7 @@
 
 
 #include "javascriptastfwd_p.h"
+#include <QtCore/QList>
 
 QT_BEGIN_NAMESPACE
 
@@ -259,18 +260,48 @@ public:
       int endColumn;
     };
 
+    struct DiagnosticMessage {
+        enum Kind { Warning, Error };
+
+        DiagnosticMessage()
+            : kind(Error), line(0), column(0) {}
+
+        DiagnosticMessage(Kind kind, int line, int column, const QString &message)
+            : kind(kind), line(line), column(column), message(message) {}
+
+        Kind kind;
+        int line;
+        int column;
+        QString message;
+    };
+
 public:
     JavaScriptParser();
     ~JavaScriptParser();
 
     bool parse(JavaScriptEnginePrivate *driver);
 
+    QList<DiagnosticMessage> diagnosticMessages() const
+    { return diagnostic_messages; }
+
+    inline DiagnosticMessage diagnosticMessage() const
+    {
+        foreach (const DiagnosticMessage &d, diagnostic_messages) {
+            if (! d.kind == DiagnosticMessage::Warning)
+                return d;
+        }
+
+        return DiagnosticMessage();
+    }
+
     inline QString errorMessage() const
-    { return error_message; }
+    { return diagnosticMessage().message; }
+
     inline int errorLineNumber() const
-    { return error_lineno; }
+    { return diagnosticMessage().line; }
+
     inline int errorColumnNumber() const
-    { return error_column; }
+    { return diagnosticMessage().column; }
 
 protected:
     inline void reallocateStack();
@@ -287,9 +318,24 @@ protected:
     Value *sym_stack;
     int *state_stack;
     Location *location_stack;
-    QString error_message;
-    int error_lineno;
-    int error_column;
+
+    // error recovery
+    enum { TOKEN_BUFFER_SIZE = 3 };
+
+    struct SavedToken {
+       int token;
+       double dval;
+       Location loc;
+    };
+
+    double yylval;
+    Location yylloc;
+
+    SavedToken token_buffer[TOKEN_BUFFER_SIZE];
+    SavedToken *first_token;
+    SavedToken *last_token;
+
+    QList<DiagnosticMessage> diagnostic_messages;
 };
 
 inline void JavaScriptParser::reallocateStack()
@@ -332,8 +378,8 @@ JavaScriptParser::JavaScriptParser():
     sym_stack(0),
     state_stack(0),
     location_stack(0),
-    error_lineno(0),
-    error_column(0)
+    first_token(0),
+    last_token(0)
 {
 }
 
@@ -358,56 +404,48 @@ static inline JavaScriptParser::Location location(JavaScript::Lexer *lexer)
 
 bool JavaScriptParser::parse(JavaScriptEnginePrivate *driver)
 {
-  const int INITIAL_STATE = 0;
-  JavaScript::Lexer *lexer = driver->lexer();
-
-  int yytoken = -1;
-  int saved_yytoken = -1;
-
-  reallocateStack();
+    JavaScript::Lexer *lexer = driver->lexer();
+    bool hadErrors = false;
+    int yytoken = -1;
+    int action = 0;
 
-  tos = 0;
-  state_stack[++tos] = INITIAL_STATE;
+    first_token = last_token = 0;
 
-  while (true)
-    {
-      const int state = state_stack [tos];
-      if (yytoken == -1 && - TERMINAL_COUNT != action_index [state])
-        {
-          if (saved_yytoken == -1)
-            {
-              yytoken = lexer->lex();
-              location_stack [tos] = location(lexer);
-            }
-          else
-            {
-              yytoken = saved_yytoken;
-              saved_yytoken = -1;
-            }
-        }
+    tos = -1;
 
-      int act = t_action (state, yytoken);
-
-      if (act == ACCEPT_STATE)
-        return true;
-
-      else if (act > 0)
-        {
-          if (++tos == stack_size)
+    do {
+        if (++tos == stack_size)
             reallocateStack();
 
-          sym_stack [tos].dval = lexer->dval ();
-          state_stack [tos] = act;
-          location_stack [tos] = location(lexer);
-          yytoken = -1;
+        state_stack[tos] = action;
+
+    _Lcheck_token:
+        if (yytoken == -1 && -TERMINAL_COUNT != action_index[action]) {
+            if (first_token == last_token) {
+                yytoken = lexer->lex();
+                yylval = lexer->dval();
+                yylloc = location(lexer);
+            } else {
+                yytoken = first_token->token;
+                yylval = first_token->dval;
+                yylloc = first_token->loc;
+                ++first_token;
+            }
         }
 
-      else if (act < 0)
-        {
-          int r = - act - 1;
-
-          tos -= rhs [r];
-          act = state_stack [tos++];
+        action = t_action(action, yytoken);
+        if (action > 0) {
+            if (action != ACCEPT_STATE) {
+                yytoken = -1;
+                sym(1).dval = yylval;
+                loc(1) = yylloc;
+            } else {
+              --tos;
+              return ! hadErrors;
+            }
+        } else if (action < 0) {
+          const int r = -action - 1;
+          tos -= rhs[r];
 
           switch (r) {
 ./
@@ -476,9 +514,8 @@ PrimaryExpression: T_DIVIDE_ ;
 case $rule_number: {
   bool rx = lexer->scanRegExp(JavaScript::Lexer::NoPrefix);
   if (!rx) {
-      error_message = lexer->errorMessage();
-      error_lineno = lexer->startLineNo();
-      error_column = lexer->startColumnNo();
+    diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, lexer->startLineNo(),
+        lexer->startColumnNo(), lexer->errorMessage()));
       return false;
   }
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::RegExpLiteral> (driver->nodePool(), lexer->pattern, lexer->flags);
@@ -494,9 +531,8 @@ PrimaryExpression: T_DIVIDE_EQ ;
 case $rule_number: {
   bool rx = lexer->scanRegExp(JavaScript::Lexer::EqualPrefix);
   if (!rx) {
-      error_message = lexer->errorMessage();
-      error_lineno = lexer->startLineNo();
-      error_column = lexer->startColumnNo();
+    diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, lexer->startLineNo(),
+        lexer->startColumnNo(), lexer->errorMessage()));
       return false;
   }
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::RegExpLiteral> (driver->nodePool(), lexer->pattern, lexer->flags);
@@ -2032,79 +2068,116 @@ case $rule_number: {
 PropertyNameAndValueListOpt: PropertyNameAndValueList ;
 
 /.
-          } // switch
+            } // switch
+            action = nt_action(state_stack[tos], lhs[r] - TERMINAL_COUNT);
+        } // if
+    } while (action != 0);
+
+    if (first_token == last_token) {
+        const int errorState = state_stack[tos];
+
+        // automatic insertion of `;'
+        if (t_action(errorState, T_AUTOMATIC_SEMICOLON) && automatic(driver, yytoken)) {
+            SavedToken &tk = token_buffer[0];
+            tk.token = yytoken;
+            tk.dval = yylval;
+            tk.loc = yylloc;
+
+#if 0
+            const QString msg = QString::fromUtf8("Missing `;'");
+
+            diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Warning,
+                yylloc.startLine, yylloc.startColumn, msg));
+#endif
+
+            first_token = &token_buffer[0];
+            last_token = &token_buffer[1];
 
-          state_stack [tos] = nt_action (act, lhs [r] - TERMINAL_COUNT);
+            yytoken = T_AUTOMATIC_SEMICOLON;
+            yylval = 0;
 
-          if (rhs[r] > 1) {
-              location_stack[tos - 1].endLine = location_stack[tos + rhs[r] - 2].endLine;
-              location_stack[tos - 1].endColumn = location_stack[tos + rhs[r] - 2].endColumn;
-              location_stack[tos] = location_stack[tos + rhs[r] - 1];
-          }
+            action = errorState;
+
+            goto _Lcheck_token;
         }
 
-      else
-        {
-          if (saved_yytoken == -1 && automatic (driver, yytoken) && t_action (state, T_AUTOMATIC_SEMICOLON) > 0)
-            {
-              saved_yytoken = yytoken;
-              yytoken = T_SEMICOLON;
-              continue;
-            }
+        hadErrors = true;
 
-          else if ((state == INITIAL_STATE) && (yytoken == 0)) {
-              // accept empty input
-              yytoken = T_SEMICOLON;
-              continue;
-          }
-
-          int ers = state;
-          int shifts = 0;
-          int reduces = 0;
-          int expected_tokens [3];
-          for (int tk = 0; tk < TERMINAL_COUNT; ++tk)
-            {
-              int k = t_action (ers, tk);
-
-              if (! k)
-                continue;
-              else if (k < 0)
-                ++reduces;
-              else if (spell [tk])
-                {
-                  if (shifts < 3)
-                    expected_tokens [shifts] = tk;
-                  ++shifts;
-                }
-            }
+        static int tokens[] = {
+            T_PLUS,
+            T_EQ,
+
+            T_COMMA,
+            T_COLON,
+            T_SEMICOLON,
+
+            T_RPAREN, T_RBRACKET, T_RBRACE,
+
+            T_NUMERIC_LITERAL,
+            T_IDENTIFIER,
+
+            T_LPAREN, T_LBRACKET, T_LBRACE,
 
-          error_message.clear ();
-          if (shifts && shifts < 3)
-            {
-              bool first = true;
-
-              for (int s = 0; s < shifts; ++s)
-                {
-                  if (first)
-                    error_message += QLatin1String ("Expected ");
-                  else
-                    error_message += QLatin1String (", ");
-
-                  first = false;
-                  error_message += QLatin1String("`");
-                  error_message += QLatin1String (spell [expected_tokens [s]]);
-                  error_message += QLatin1String("'");
-                }
+            EOF_SYMBOL
+        };
+
+        token_buffer[0].token = yytoken;
+        token_buffer[0].dval = yylval;
+        token_buffer[0].loc = yylloc;
+
+        token_buffer[1].token = yytoken = lexer->lex();
+        token_buffer[1].dval  = yylval  = lexer->dval();
+        token_buffer[1].loc   = yylloc  = location(lexer);
+
+        if (t_action(errorState, yytoken)) {
+            const QString msg = QString::fromUtf8("Removed token: `%1'").arg(spell[token_buffer[0].token]);
+
+            diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error,
+                token_buffer[0].loc.startLine, token_buffer[0].loc.startColumn, msg));
+
+            action = errorState;
+            goto _Lcheck_token;
+        }
+
+        for (int *tk = tokens; *tk != EOF_SYMBOL; ++tk) {
+            int a = t_action(errorState, *tk);
+            if (a > 0 && t_action(a, yytoken)) {
+                const QString msg = QString::fromUtf8("Inserted token: `%1'").arg(spell[*tk]);
+
+                diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error,
+                    token_buffer[0].loc.startLine, token_buffer[0].loc.startColumn, msg));
+
+                yytoken = *tk;
+                yylval = 0;
+                yylloc = token_buffer[0].loc;
+
+                first_token = &token_buffer[0];
+                last_token = &token_buffer[2];
+
+                action = errorState;
+                goto _Lcheck_token;
             }
+        }
 
-          if (error_message.isEmpty())
-              error_message = lexer->errorMessage();
+        for (int tk = 1; tk < TERMINAL_COUNT; ++tk) {
+            int a = t_action(errorState, tk);
+            if (a > 0 && t_action(a, yytoken)) {
+                const QString msg = QString::fromUtf8("Inserted token: `%1'").arg(spell[tk]);
+                diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error,
+                    token_buffer[0].loc.startLine, token_buffer[0].loc.startColumn, msg));
 
-          error_lineno = lexer->startLineNo();
-          error_column = lexer->startColumnNo();
+                yytoken = tk;
+                yylval = 0;
+                yylloc = token_buffer[0].loc;
 
-          return false;
+                action = errorState;
+                goto _Lcheck_token;
+            }
         }
+
+        const QString msg = QString::fromUtf8("Unexpected token: `%1'").arg(token_buffer[0].token);
+        diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error,
+            token_buffer[0].loc.startLine, token_buffer[0].loc.startColumn, msg));
     }
 
     return false;
diff --git a/src/plugins/qtscripteditor/parser/javascriptgrammar.cpp b/src/plugins/qtscripteditor/parser/javascriptgrammar.cpp
index a86c20d271303c0deda0546cd9bb865fc35457c9..d5b7765ebc523136361bd34ca65f86fbc23309ac 100644
--- a/src/plugins/qtscripteditor/parser/javascriptgrammar.cpp
+++ b/src/plugins/qtscripteditor/parser/javascriptgrammar.cpp
@@ -1,4 +1,45 @@
 // This file was generated by qlalr - DO NOT EDIT!
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
 #include "javascriptgrammar_p.h"
 
 const char *const JavaScriptGrammar::spell [] = {
@@ -10,20 +51,7 @@ const char *const JavaScriptGrammar::spell [] = {
   "||", "+", "+=", "++", "?", "}", "]", "%", "%=", "return", 
   ")", ";", 0, "*", "*=", "string literal", "switch", "this", "throw", "~", 
   "try", "typeof", "var", "void", "while", "with", "^", "^=", "null", "true", 
-  "false", "const", "debugger", "reserved word", 
-#ifndef QLALR_NO_JAVASCRIPTGRAMMAR_DEBUG_INFO
-"Program", "PrimaryExpression", "ElisionOpt", "ElementList", "PropertyNameAndValueListOpt", "PropertyNameAndValueList", 
-  "Expression", "AssignmentExpression", "Elision", "PropertyName", "ReservedIdentifier", "PropertyIdentifier", "MemberExpression", "FunctionExpression", "Arguments", "NewExpression", 
-  "CallExpression", "ArgumentList", "LeftHandSideExpression", "PostfixExpression", "UnaryExpression", "MultiplicativeExpression", "AdditiveExpression", "ShiftExpression", "RelationalExpression", "RelationalExpressionNotIn", 
-  "EqualityExpression", "EqualityExpressionNotIn", "BitwiseANDExpression", "BitwiseANDExpressionNotIn", "BitwiseXORExpression", "BitwiseXORExpressionNotIn", "BitwiseORExpression", "BitwiseORExpressionNotIn", "LogicalANDExpression", "LogicalANDExpressionNotIn", 
-  "LogicalORExpression", "LogicalORExpressionNotIn", "ConditionalExpression", "ConditionalExpressionNotIn", "AssignmentExpressionNotIn", "AssignmentOperator", "ExpressionOpt", "ExpressionNotIn", "ExpressionNotInOpt", "Statement", 
-  "Block", "VariableStatement", "EmptyStatement", "ExpressionStatement", "IfStatement", "IterationStatement", "ContinueStatement", "BreakStatement", "ReturnStatement", "WithStatement", 
-  "LabelledStatement", "SwitchStatement", "ThrowStatement", "TryStatement", "DebuggerStatement", "StatementListOpt", "StatementList", "VariableDeclarationKind", "VariableDeclarationList", "VariableDeclaration", 
-  "VariableDeclarationListNotIn", "VariableDeclarationNotIn", "InitialiserOpt", "InitialiserNotInOpt", "Initialiser", "InitialiserNotIn", "CaseBlock", "CaseClausesOpt", "DefaultClause", "CaseClauses", 
-  "CaseClause", "Catch", "Finally", "FunctionDeclaration", "FormalParameterListOpt", "FunctionBodyOpt", "IdentifierOpt", "FormalParameterList", "FunctionBody", "SourceElements", 
-  "SourceElement", "$accept"
-#endif // QLALR_NO_JAVASCRIPTGRAMMAR_DEBUG_INFO
-};
+  "false", "const", "debugger", "reserved word"};
 
 const int JavaScriptGrammar::lhs [] = {
   85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 
@@ -83,309 +111,6 @@ const int JavaScriptGrammar:: rhs[] = {
   8, 8, 1, 3, 0, 1, 0, 1, 1, 1, 
   1, 2, 1, 1, 0, 1, 0, 1, 2};
 
-
-#ifndef QLALR_NO_JAVASCRIPTGRAMMAR_DEBUG_INFO
-const int JavaScriptGrammar::rule_info [] = {
-    85, 67
-  , 85, 29
-  , 85, 78
-  , 85, 79
-  , 85, 80
-  , 85, 47
-  , 85, 65
-  , 85, 12
-  , 85, 13
-  , 85, 34, 86, 56
-  , 85, 34, 87, 56
-  , 85, 34, 87, 8, 86, 56
-  , 85, 33, 88, 55
-  , 85, 33, 89, 8, 55
-  , 85, 36, 90, 60
-  , 87, 86, 91
-  , 87, 87, 8, 86, 91
-  , 92, 8
-  , 92, 92, 8
-  , 86
-  , 86, 92
-  , 89, 93, 7, 91
-  , 89, 89, 8, 93, 7, 91
-  , 93, 29
-  , 93, 65
-  , 93, 47
-  , 93, 94
-  , 94, 4
-  , 94, 5
-  , 94, 6
-  , 94, 9
-  , 94, 10
-  , 94, 11
-  , 94, 14
-  , 94, 16
-  , 94, 80
-  , 94, 20
-  , 94, 21
-  , 94, 22
-  , 94, 30
-  , 94, 31
-  , 94, 32
-  , 94, 43
-  , 94, 78
-  , 94, 59
-  , 94, 66
-  , 94, 67
-  , 94, 68
-  , 94, 79
-  , 94, 70
-  , 94, 71
-  , 94, 72
-  , 94, 73
-  , 94, 74
-  , 94, 81
-  , 94, 82
-  , 94, 83
-  , 94, 75
-  , 95, 29
-  , 95, 94
-  , 96, 85
-  , 96, 97
-  , 96, 96, 34, 90, 56
-  , 96, 96, 15, 95
-  , 96, 43, 96, 98
-  , 99, 96
-  , 99, 43, 99
-  , 100, 96, 98
-  , 100, 100, 98
-  , 100, 100, 34, 90, 56
-  , 100, 100, 15, 95
-  , 98, 36, 60
-  , 98, 36, 101, 60
-  , 101, 91
-  , 101, 101, 8, 91
-  , 102, 99
-  , 102, 100
-  , 103, 102
-  , 103, 102, 53
-  , 103, 102, 42
-  , 104, 103
-  , 104, 11, 104
-  , 104, 73, 104
-  , 104, 71, 104
-  , 104, 53, 104
-  , 104, 42, 104
-  , 104, 51, 104
-  , 104, 40, 104
-  , 104, 69, 104
-  , 104, 44, 104
-  , 105, 104
-  , 105, 105, 63, 104
-  , 105, 105, 12, 104
-  , 105, 105, 57, 104
-  , 106, 105
-  , 106, 106, 51, 105
-  , 106, 106, 40, 105
-  , 107, 106
-  , 107, 107, 38, 106
-  , 107, 107, 25, 106
-  , 107, 107, 27, 106
-  , 108, 107
-  , 108, 108, 37, 107
-  , 108, 108, 24, 107
-  , 108, 108, 35, 107
-  , 108, 108, 23, 107
-  , 108, 108, 32, 107
-  , 108, 108, 31, 107
-  , 109, 107
-  , 109, 109, 37, 107
-  , 109, 109, 24, 107
-  , 109, 109, 35, 107
-  , 109, 109, 23, 107
-  , 109, 109, 32, 107
-  , 110, 108
-  , 110, 110, 18, 108
-  , 110, 110, 45, 108
-  , 110, 110, 19, 108
-  , 110, 110, 46, 108
-  , 111, 109
-  , 111, 111, 18, 109
-  , 111, 111, 45, 109
-  , 111, 111, 19, 109
-  , 111, 111, 46, 109
-  , 112, 110
-  , 112, 112, 1, 110
-  , 113, 111
-  , 113, 113, 1, 111
-  , 114, 112
-  , 114, 114, 76, 112
-  , 115, 113
-  , 115, 115, 76, 113
-  , 116, 114
-  , 116, 116, 48, 114
-  , 117, 115
-  , 117, 117, 48, 115
-  , 118, 116
-  , 118, 118, 2, 116
-  , 119, 117
-  , 119, 119, 2, 117
-  , 120, 118
-  , 120, 120, 50, 118
-  , 121, 119
-  , 121, 121, 50, 119
-  , 122, 120
-  , 122, 120, 54, 91, 7, 91
-  , 123, 121
-  , 123, 121, 54, 124, 7, 124
-  , 91, 122
-  , 91, 102, 125, 91
-  , 124, 123
-  , 124, 102, 125, 124
-  , 125, 17
-  , 125, 64
-  , 125, 13
-  , 125, 58
-  , 125, 52
-  , 125, 41
-  , 125, 39
-  , 125, 26
-  , 125, 28
-  , 125, 3
-  , 125, 77
-  , 125, 49
-  , 90, 91
-  , 90, 90, 8, 91
-  , 126
-  , 126, 90
-  , 127, 124
-  , 127, 127, 8, 124
-  , 128
-  , 128, 127
-  , 129, 130
-  , 129, 131
-  , 129, 132
-  , 129, 133
-  , 129, 134
-  , 129, 135
-  , 129, 136
-  , 129, 137
-  , 129, 138
-  , 129, 139
-  , 129, 140
-  , 129, 141
-  , 129, 142
-  , 129, 143
-  , 129, 144
-  , 130, 33, 145, 55
-  , 146, 129
-  , 146, 146, 129
-  , 145
-  , 145, 146
-  , 131, 147, 148, 62
-  , 131, 147, 148, 61
-  , 147, 81
-  , 147, 72
-  , 148, 149
-  , 148, 148, 8, 149
-  , 150, 151
-  , 150, 150, 8, 151
-  , 149, 29, 152
-  , 151, 29, 153
-  , 154, 17, 91
-  , 152
-  , 152, 154
-  , 155, 17, 124
-  , 153
-  , 153, 155
-  , 132, 61
-  , 133, 90, 62
-  , 133, 90, 61
-  , 134, 30, 36, 90, 60, 129, 16, 129
-  , 134, 30, 36, 90, 60, 129
-  , 135, 14, 129, 74, 36, 90, 60, 62
-  , 135, 14, 129, 74, 36, 90, 60, 61
-  , 135, 74, 36, 90, 60, 129
-  , 135, 21, 36, 128, 61, 126, 61, 126, 60, 129
-  , 135, 21, 36, 72, 150, 61, 126, 61, 126, 60, 129
-  , 135, 21, 36, 102, 31, 90, 60, 129
-  , 135, 21, 36, 72, 151, 31, 90, 60, 129
-  , 136, 9, 62
-  , 136, 9, 61
-  , 136, 9, 29, 62
-  , 136, 9, 29, 61
-  , 137, 4, 62
-  , 137, 4, 61
-  , 137, 4, 29, 62
-  , 137, 4, 29, 61
-  , 138, 59, 126, 62
-  , 138, 59, 126, 61
-  , 139, 75, 36, 90, 60, 129
-  , 141, 66, 36, 90, 60, 156
-  , 156, 33, 157, 55
-  , 156, 33, 157, 158, 157, 55
-  , 159, 160
-  , 159, 159, 160
-  , 157
-  , 157, 159
-  , 160, 5, 90, 7, 145
-  , 158, 10, 7, 145
-  , 140, 29, 7, 129
-  , 142, 68, 90, 62
-  , 142, 68, 90, 61
-  , 143, 70, 130, 161
-  , 143, 70, 130, 162
-  , 143, 70, 130, 161, 162
-  , 161, 6, 36, 29, 60, 130
-  , 162, 20, 130
-  , 144, 82, 62
-  , 144, 82, 61
-  , 163, 22, 29, 36, 164, 60, 33, 165, 55
-  , 97, 22, 166, 36, 164, 60, 33, 165, 55
-  , 167, 29
-  , 167, 167, 8, 29
-  , 164
-  , 164, 167
-  , 165
-  , 165, 168
-  , 168, 169
-  , 84, 169
-  , 169, 170
-  , 169, 169, 170
-  , 170, 129
-  , 170, 163
-  , 166
-  , 166, 29
-  , 88
-  , 88, 89
-  , 171, 84, 0};
-
-const int JavaScriptGrammar::rule_index [] = {
-  0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 
-  22, 26, 32, 36, 41, 45, 48, 53, 55, 58, 
-  59, 61, 65, 71, 73, 75, 77, 79, 81, 83, 
-  85, 87, 89, 91, 93, 95, 97, 99, 101, 103, 
-  105, 107, 109, 111, 113, 115, 117, 119, 121, 123, 
-  125, 127, 129, 131, 133, 135, 137, 139, 141, 143, 
-  145, 147, 149, 154, 158, 162, 164, 167, 170, 173, 
-  178, 182, 185, 189, 191, 195, 197, 199, 201, 204, 
-  207, 209, 212, 215, 218, 221, 224, 227, 230, 233, 
-  236, 238, 242, 246, 250, 252, 256, 260, 262, 266, 
-  270, 274, 276, 280, 284, 288, 292, 296, 300, 302, 
-  306, 310, 314, 318, 322, 324, 328, 332, 336, 340, 
-  342, 346, 350, 354, 358, 360, 364, 366, 370, 372, 
-  376, 378, 382, 384, 388, 390, 394, 396, 400, 402, 
-  406, 408, 412, 414, 418, 420, 426, 428, 434, 436, 
-  440, 442, 446, 448, 450, 452, 454, 456, 458, 460, 
-  462, 464, 466, 468, 470, 472, 476, 477, 479, 481, 
-  485, 486, 488, 490, 492, 494, 496, 498, 500, 502, 
-  504, 506, 508, 510, 512, 514, 516, 518, 522, 524, 
-  527, 528, 530, 534, 538, 540, 542, 544, 548, 550, 
-  554, 557, 560, 563, 564, 566, 569, 570, 572, 574, 
-  577, 580, 588, 594, 602, 610, 616, 626, 637, 645, 
-  654, 657, 660, 664, 668, 671, 674, 678, 682, 686, 
-  690, 696, 702, 706, 712, 714, 717, 718, 720, 725, 
-  729, 733, 737, 741, 745, 749, 754, 760, 763, 766, 
-  769, 778, 787, 789, 793, 794, 796, 797, 799, 801, 
-  803, 805, 808, 810, 812, 813, 815, 816, 818};
-#endif // QLALR_NO_JAVASCRIPTGRAMMAR_DEBUG_INFO
-
 const int JavaScriptGrammar::action_default [] = {
   0, 98, 165, 129, 137, 133, 173, 180, 77, 149, 
   179, 187, 175, 125, 0, 176, 264, 62, 177, 178, 
diff --git a/src/plugins/qtscripteditor/parser/javascriptgrammar_p.h b/src/plugins/qtscripteditor/parser/javascriptgrammar_p.h
index 2d9e2f92d7d2adea60148b4e426df05ee251ddca..3b51d8e42426a7fffbba5a555c27e4723100df26 100644
--- a/src/plugins/qtscripteditor/parser/javascriptgrammar_p.h
+++ b/src/plugins/qtscripteditor/parser/javascriptgrammar_p.h
@@ -1,4 +1,56 @@
 // This file was generated by qlalr - DO NOT EDIT!
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+//  W A R N I N G
+//  -------------
+//
+// This file is not part of the Qt API.  It exists for the convenience
+// of other Qt classes.  This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
 #ifndef JAVASCRIPTGRAMMAR_P_H
 #define JAVASCRIPTGRAMMAR_P_H
 
@@ -105,12 +157,6 @@ public:
   static const char  *const spell [];
   static const int            lhs [];
   static const int            rhs [];
-
-#ifndef QLALR_NO_JAVASCRIPTGRAMMAR_DEBUG_INFO
-  static const int     rule_index [];
-  static const int      rule_info [];
-#endif // QLALR_NO_JAVASCRIPTGRAMMAR_DEBUG_INFO
-
   static const int   goto_default [];
   static const int action_default [];
   static const int   action_index [];
diff --git a/src/plugins/qtscripteditor/parser/javascriptparser.cpp b/src/plugins/qtscripteditor/parser/javascriptparser.cpp
index ac9dd96d0cd54140deead7b196fd2207bcd329ae..b1d1508b6042caca5e3e98e04dd40ba9e74ece03 100644
--- a/src/plugins/qtscripteditor/parser/javascriptparser.cpp
+++ b/src/plugins/qtscripteditor/parser/javascriptparser.cpp
@@ -1,7 +1,5 @@
 // This file was generated by qlalr - DO NOT EDIT!
 
-#line 84 "./javascript.g"
-
 /****************************************************************************
 **
 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
@@ -45,7 +43,7 @@
 
 #include <QtCore/QtDebug>
 
-#ifndef QT_NO_JAVASCRIPT
+
 
 #include <string.h>
 
@@ -59,7 +57,7 @@
 #include "javascriptast_p.h"
 #include "javascriptnodepool_p.h"
 
-#define Q_JAVASCRIPT_UPDATE_POSITION(node, startloc, endloc) do { \
+#define J_SCRIPT_UPDATE_POSITION(node, startloc, endloc) do { \
     node->startLine = startloc.startLine; \
     node->startColumn = startloc.startColumn; \
     node->endLine = endloc.endLine; \
@@ -67,8 +65,6 @@
 } while (0)
 
 
-#line 310 "./javascript.g"
-
 
 #include "javascriptparser_p.h"
 
@@ -93,8 +89,8 @@ JavaScriptParser::JavaScriptParser():
     sym_stack(0),
     state_stack(0),
     location_stack(0),
-    error_lineno(0),
-    error_column(0)
+    first_token(0),
+    last_token(0)
 {
 }
 
@@ -119,1463 +115,1080 @@ static inline JavaScriptParser::Location location(JavaScript::Lexer *lexer)
 
 bool JavaScriptParser::parse(JavaScriptEnginePrivate *driver)
 {
-  const int INITIAL_STATE = 0;
-  JavaScript::Lexer *lexer = driver->lexer();
-
-  int yytoken = -1;
-  int saved_yytoken = -1;
-
-  reallocateStack();
-
-  tos = 0;
-  state_stack[++tos] = INITIAL_STATE;
-
-  while (true)
-    {
-      const int state = state_stack [tos];
-      if (yytoken == -1 && - TERMINAL_COUNT != action_index [state])
-        {
-          if (saved_yytoken == -1)
-            {
-              yytoken = lexer->lex();
-              location_stack [tos] = location(lexer);
-            }
-          else
-            {
-              yytoken = saved_yytoken;
-              saved_yytoken = -1;
-            }
-        }
+    JavaScript::Lexer *lexer = driver->lexer();
+    bool hadErrors = false;
+    int yytoken = -1;
+    int action = 0;
 
-      int act = t_action (state, yytoken);
+    first_token = last_token = 0;
 
-      if (act == ACCEPT_STATE)
-        return true;
+    tos = -1;
 
-      else if (act > 0)
-        {
-          if (++tos == stack_size)
+    do {
+        if (++tos == stack_size)
             reallocateStack();
 
-          sym_stack [tos].dval = lexer->dval ();
-          state_stack [tos] = act;
-          location_stack [tos] = location(lexer);
-          yytoken = -1;
+        state_stack[tos] = action;
+
+    _Lcheck_token:
+        if (yytoken == -1 && -TERMINAL_COUNT != action_index[action]) {
+            if (first_token == last_token) {
+                yytoken = lexer->lex();
+                yylval = lexer->dval();
+                yylloc = location(lexer);
+            } else {
+                yytoken = first_token->token;
+                yylval = first_token->dval;
+                yylloc = first_token->loc;
+                ++first_token;
+            }
         }
 
-      else if (act < 0)
-        {
-          int r = - act - 1;
-
-          tos -= rhs [r];
-          act = state_stack [tos++];
+        action = t_action(action, yytoken);
+        if (action > 0) {
+            if (action != ACCEPT_STATE) {
+                yytoken = -1;
+                sym(1).dval = yylval;
+                loc(1) = yylloc;
+            } else {
+              --tos;
+              return ! hadErrors;
+            }
+        } else if (action < 0) {
+          const int r = -action - 1;
+          tos -= rhs[r];
 
           switch (r) {
 
-#line 416 "./javascript.g"
-
 case 0: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::ThisExpression> (driver->nodePool());
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
 } break;
 
-#line 424 "./javascript.g"
-
 case 1: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::IdentifierExpression> (driver->nodePool(), sym(1).sval);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
 } break;
 
-#line 432 "./javascript.g"
-
 case 2: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::NullExpression> (driver->nodePool());
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
 } break;
 
-#line 440 "./javascript.g"
-
 case 3: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::TrueLiteral> (driver->nodePool());
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
 } break;
 
-#line 448 "./javascript.g"
-
 case 4: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::FalseLiteral> (driver->nodePool());
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
 } break;
 
-#line 456 "./javascript.g"
-
 case 5: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::NumericLiteral> (driver->nodePool(), sym(1).dval);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
 } break;
 
-#line 464 "./javascript.g"
-
 case 6: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::StringLiteral> (driver->nodePool(), sym(1).sval);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
 } break;
 
-#line 475 "./javascript.g"
-
 case 7: {
   bool rx = lexer->scanRegExp(JavaScript::Lexer::NoPrefix);
   if (!rx) {
-      error_message = lexer->errorMessage();
-      error_lineno = lexer->startLineNo();
-      error_column = lexer->startColumnNo();
+    diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, lexer->startLineNo(),
+        lexer->startColumnNo(), lexer->errorMessage()));
       return false;
   }
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::RegExpLiteral> (driver->nodePool(), lexer->pattern, lexer->flags);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
 } break;
 
-#line 493 "./javascript.g"
-
 case 8: {
   bool rx = lexer->scanRegExp(JavaScript::Lexer::EqualPrefix);
   if (!rx) {
-      error_message = lexer->errorMessage();
-      error_lineno = lexer->startLineNo();
-      error_column = lexer->startColumnNo();
+    diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, lexer->startLineNo(),
+        lexer->startColumnNo(), lexer->errorMessage()));
       return false;
   }
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::RegExpLiteral> (driver->nodePool(), lexer->pattern, lexer->flags);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
 } break;
 
-#line 508 "./javascript.g"
-
 case 9: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::ArrayLiteral> (driver->nodePool(), sym(2).Elision);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 516 "./javascript.g"
-
 case 10: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::ArrayLiteral> (driver->nodePool(), sym(2).ElementList->finish ());
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 524 "./javascript.g"
-
 case 11: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::ArrayLiteral> (driver->nodePool(), sym(2).ElementList->finish (), sym(4).Elision);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(5));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(5));
 } break;
 
-#line 540 "./javascript.g"
-
 case 12: {
   if (sym(2).Node)
     sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::ObjectLiteral> (driver->nodePool(), sym(2).PropertyNameAndValueList->finish ());
   else
     sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::ObjectLiteral> (driver->nodePool());
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 551 "./javascript.g"
-
 case 13: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::ObjectLiteral> (driver->nodePool(), sym(2).PropertyNameAndValueList->finish ());
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(4));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(4));
 } break;
 
-#line 559 "./javascript.g"
-
 case 14: {
   sym(1) = sym(2);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 567 "./javascript.g"
-
 case 15: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::ElementList> (driver->nodePool(), sym(1).Elision, sym(2).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
 } break;
 
-#line 575 "./javascript.g"
-
 case 16: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::ElementList> (driver->nodePool(), sym(1).ElementList, sym(3).Elision, sym(4).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(4));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(4));
 } break;
 
-#line 583 "./javascript.g"
-
 case 17: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::Elision> (driver->nodePool());
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
 } break;
 
-#line 591 "./javascript.g"
-
 case 18: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::Elision> (driver->nodePool(), sym(1).Elision);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
 } break;
 
-#line 599 "./javascript.g"
-
 case 19: {
   sym(1).Node = 0;
 } break;
 
-#line 606 "./javascript.g"
-
 case 20: {
   sym(1).Elision = sym(1).Elision->finish ();
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
 } break;
 
-#line 614 "./javascript.g"
-
 case 21: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::PropertyNameAndValueList> (driver->nodePool(), sym(1).PropertyName, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 622 "./javascript.g"
-
 case 22: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::PropertyNameAndValueList> (driver->nodePool(), sym(1).PropertyNameAndValueList, sym(3).PropertyName, sym(5).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(5));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(5));
 } break;
 
-#line 630 "./javascript.g"
-
 case 23: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::IdentifierPropertyName> (driver->nodePool(), sym(1).sval);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
 } break;
 
-#line 638 "./javascript.g"
-
 case 24: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::StringLiteralPropertyName> (driver->nodePool(), sym(1).sval);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
 } break;
 
-#line 646 "./javascript.g"
-
 case 25: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::NumericLiteralPropertyName> (driver->nodePool(), sym(1).dval);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
 } break;
 
-#line 654 "./javascript.g"
-
 case 26: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::IdentifierPropertyName> (driver->nodePool(), sym(1).sval);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
 } break;
 
-#line 662 "./javascript.g"
-
 case 27:
 
-#line 666 "./javascript.g"
-
 case 28:
 
-#line 670 "./javascript.g"
-
 case 29:
 
-#line 674 "./javascript.g"
-
 case 30:
 
-#line 678 "./javascript.g"
-
 case 31:
 
-#line 682 "./javascript.g"
-
 case 32:
 
-#line 686 "./javascript.g"
-
 case 33:
 
-#line 690 "./javascript.g"
-
 case 34:
 
-#line 694 "./javascript.g"
-
 case 35:
 
-#line 698 "./javascript.g"
-
 case 36:
 
-#line 702 "./javascript.g"
-
 case 37:
 
-#line 706 "./javascript.g"
-
 case 38:
 
-#line 710 "./javascript.g"
-
 case 39:
 
-#line 714 "./javascript.g"
-
 case 40:
 
-#line 718 "./javascript.g"
-
 case 41:
 
-#line 722 "./javascript.g"
-
 case 42:
 
-#line 726 "./javascript.g"
-
 case 43:
 
-#line 730 "./javascript.g"
-
 case 44:
 
-#line 734 "./javascript.g"
-
 case 45:
 
-#line 738 "./javascript.g"
-
 case 46:
 
-#line 742 "./javascript.g"
-
 case 47:
 
-#line 746 "./javascript.g"
-
 case 48:
 
-#line 750 "./javascript.g"
-
 case 49:
 
-#line 754 "./javascript.g"
-
 case 50:
 
-#line 758 "./javascript.g"
-
 case 51:
 
-#line 762 "./javascript.g"
-
 case 52:
 
-#line 766 "./javascript.g"
-
 case 53:
 
-#line 770 "./javascript.g"
-
 case 54:
 
-#line 774 "./javascript.g"
-
 case 55:
 
-#line 778 "./javascript.g"
-
 case 56:
 
-#line 782 "./javascript.g"
-
 case 57:
 {
   sym(1).sval = driver->intern(lexer->characterBuffer(), lexer->characterCount());
 } break;
 
-#line 796 "./javascript.g"
-
 case 62: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::ArrayMemberExpression> (driver->nodePool(), sym(1).Expression, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(4));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(4));
 } break;
 
-#line 804 "./javascript.g"
-
 case 63: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::FieldMemberExpression> (driver->nodePool(), sym(1).Expression, sym(3).sval);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(4));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(4));
 } break;
 
-#line 812 "./javascript.g"
-
 case 64: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::NewMemberExpression> (driver->nodePool(), sym(2).Expression, sym(3).ArgumentList);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 822 "./javascript.g"
-
 case 66: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::NewExpression> (driver->nodePool(), sym(2).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
 } break;
 
-#line 830 "./javascript.g"
-
 case 67: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::CallExpression> (driver->nodePool(), sym(1).Expression, sym(2).ArgumentList);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
 } break;
 
-#line 838 "./javascript.g"
-
 case 68: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::CallExpression> (driver->nodePool(), sym(1).Expression, sym(2).ArgumentList);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
 } break;
 
-#line 846 "./javascript.g"
-
 case 69: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::ArrayMemberExpression> (driver->nodePool(), sym(1).Expression, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(4));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(4));
 } break;
 
-#line 854 "./javascript.g"
-
 case 70: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::FieldMemberExpression> (driver->nodePool(), sym(1).Expression, sym(3).sval);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 862 "./javascript.g"
-
 case 71: {
   sym(1).Node = 0;
 } break;
 
-#line 869 "./javascript.g"
-
 case 72: {
   sym(1).Node = sym(2).ArgumentList->finish ();
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 877 "./javascript.g"
-
 case 73: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::ArgumentList> (driver->nodePool(), sym(1).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
 } break;
 
-#line 885 "./javascript.g"
-
 case 74: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::ArgumentList> (driver->nodePool(), sym(1).ArgumentList, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 897 "./javascript.g"
-
 case 78: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::PostIncrementExpression> (driver->nodePool(), sym(1).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
 } break;
 
-#line 905 "./javascript.g"
-
 case 79: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::PostDecrementExpression> (driver->nodePool(), sym(1).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
 } break;
 
-#line 915 "./javascript.g"
-
 case 81: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::DeleteExpression> (driver->nodePool(), sym(2).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
 } break;
 
-#line 923 "./javascript.g"
-
 case 82: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::VoidExpression> (driver->nodePool(), sym(2).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
 } break;
 
-#line 931 "./javascript.g"
-
 case 83: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::TypeOfExpression> (driver->nodePool(), sym(2).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
 } break;
 
-#line 939 "./javascript.g"
-
 case 84: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::PreIncrementExpression> (driver->nodePool(), sym(2).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
 } break;
 
-#line 947 "./javascript.g"
-
 case 85: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::PreDecrementExpression> (driver->nodePool(), sym(2).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
 } break;
 
-#line 955 "./javascript.g"
-
 case 86: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::UnaryPlusExpression> (driver->nodePool(), sym(2).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
 } break;
 
-#line 963 "./javascript.g"
-
 case 87: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::UnaryMinusExpression> (driver->nodePool(), sym(2).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
 } break;
 
-#line 971 "./javascript.g"
-
 case 88: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::TildeExpression> (driver->nodePool(), sym(2).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
 } break;
 
-#line 979 "./javascript.g"
-
 case 89: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::NotExpression> (driver->nodePool(), sym(2).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
 } break;
 
-#line 989 "./javascript.g"
-
 case 91: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Mul, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 997 "./javascript.g"
-
 case 92: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Div, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1005 "./javascript.g"
-
 case 93: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Mod, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1015 "./javascript.g"
-
 case 95: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Add, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1023 "./javascript.g"
-
 case 96: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Sub, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1033 "./javascript.g"
-
 case 98: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::LShift, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1041 "./javascript.g"
-
 case 99: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::RShift, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1049 "./javascript.g"
-
 case 100: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::URShift, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1059 "./javascript.g"
-
 case 102: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Lt, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1067 "./javascript.g"
-
 case 103: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Gt, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1075 "./javascript.g"
-
 case 104: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Le, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1083 "./javascript.g"
-
 case 105: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Ge, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1091 "./javascript.g"
-
 case 106: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::InstanceOf, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1099 "./javascript.g"
-
 case 107: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::In, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1109 "./javascript.g"
-
 case 109: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Lt, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1117 "./javascript.g"
-
 case 110: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Gt, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1125 "./javascript.g"
-
 case 111: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Le, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1133 "./javascript.g"
-
 case 112: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Ge, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1141 "./javascript.g"
-
 case 113: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::InstanceOf, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1151 "./javascript.g"
-
 case 115: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Equal, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1159 "./javascript.g"
-
 case 116: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::NotEqual, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1167 "./javascript.g"
-
 case 117: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::StrictEqual, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1175 "./javascript.g"
-
 case 118: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::StrictNotEqual, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1185 "./javascript.g"
-
 case 120: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Equal, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1193 "./javascript.g"
-
 case 121: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::NotEqual, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1201 "./javascript.g"
-
 case 122: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::StrictEqual, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1209 "./javascript.g"
-
 case 123: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::StrictNotEqual, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1219 "./javascript.g"
-
 case 125: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::BitAnd, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1229 "./javascript.g"
-
 case 127: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::BitAnd, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1239 "./javascript.g"
-
 case 129: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::BitXor, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1249 "./javascript.g"
-
 case 131: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::BitXor, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1259 "./javascript.g"
-
 case 133: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::BitOr, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1269 "./javascript.g"
-
 case 135: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::BitOr, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1279 "./javascript.g"
-
 case 137: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::And, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1289 "./javascript.g"
-
 case 139: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::And, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1299 "./javascript.g"
-
 case 141: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Or, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1309 "./javascript.g"
-
 case 143: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Or, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1319 "./javascript.g"
-
 case 145: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::ConditionalExpression> (driver->nodePool(), sym(1).Expression, sym(3).Expression, sym(5).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1329 "./javascript.g"
-
 case 147: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::ConditionalExpression> (driver->nodePool(), sym(1).Expression, sym(3).Expression, sym(5).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1339 "./javascript.g"
-
 case 149: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, sym(2).ival, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1349 "./javascript.g"
-
 case 151: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, sym(2).ival, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1357 "./javascript.g"
-
 case 152: {
   sym(1).ival = QSOperator::Assign;
 } break;
 
-#line 1364 "./javascript.g"
-
 case 153: {
   sym(1).ival = QSOperator::InplaceMul;
 } break;
 
-#line 1371 "./javascript.g"
-
 case 154: {
   sym(1).ival = QSOperator::InplaceDiv;
 } break;
 
-#line 1378 "./javascript.g"
-
 case 155: {
   sym(1).ival = QSOperator::InplaceMod;
 } break;
 
-#line 1385 "./javascript.g"
-
 case 156: {
   sym(1).ival = QSOperator::InplaceAdd;
 } break;
 
-#line 1392 "./javascript.g"
-
 case 157: {
   sym(1).ival = QSOperator::InplaceSub;
 } break;
 
-#line 1399 "./javascript.g"
-
 case 158: {
   sym(1).ival = QSOperator::InplaceLeftShift;
 } break;
 
-#line 1406 "./javascript.g"
-
 case 159: {
   sym(1).ival = QSOperator::InplaceRightShift;
 } break;
 
-#line 1413 "./javascript.g"
-
 case 160: {
   sym(1).ival = QSOperator::InplaceURightShift;
 } break;
 
-#line 1420 "./javascript.g"
-
 case 161: {
   sym(1).ival = QSOperator::InplaceAnd;
 } break;
 
-#line 1427 "./javascript.g"
-
 case 162: {
   sym(1).ival = QSOperator::InplaceXor;
 } break;
 
-#line 1434 "./javascript.g"
-
 case 163: {
   sym(1).ival = QSOperator::InplaceOr;
 } break;
 
-#line 1443 "./javascript.g"
-
 case 165: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::Expression> (driver->nodePool(), sym(1).Expression, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1451 "./javascript.g"
-
 case 166: {
   sym(1).Node = 0;
 } break;
 
-#line 1462 "./javascript.g"
-
 case 169: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::Expression> (driver->nodePool(), sym(1).Expression, sym(3).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1470 "./javascript.g"
-
 case 170: {
   sym(1).Node = 0;
 } break;
 
-#line 1496 "./javascript.g"
-
 case 187: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::Block> (driver->nodePool(), sym(2).StatementList);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1504 "./javascript.g"
-
 case 188: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::StatementList> (driver->nodePool(), sym(1).Statement);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
 } break;
 
-#line 1512 "./javascript.g"
-
 case 189: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::StatementList> (driver->nodePool(), sym(1).StatementList, sym(2).Statement);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
 } break;
 
-#line 1520 "./javascript.g"
-
 case 190: {
   sym(1).Node = 0;
 } break;
 
-#line 1527 "./javascript.g"
-
 case 191: {
   sym(1).Node = sym(1).StatementList->finish ();
 } break;
 
-#line 1535 "./javascript.g"
-
 case 193: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::VariableStatement> (driver->nodePool(), sym(2).VariableDeclarationList->finish (/*readOnly=*/sym(1).ival == T_CONST));
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1543 "./javascript.g"
-
 case 194: {
   sym(1).ival = T_CONST;
 } break;
 
-#line 1550 "./javascript.g"
-
 case 195: {
   sym(1).ival = T_VAR;
 } break;
 
-#line 1557 "./javascript.g"
-
 case 196: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::VariableDeclarationList> (driver->nodePool(), sym(1).VariableDeclaration);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
 } break;
 
-#line 1565 "./javascript.g"
-
 case 197: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::VariableDeclarationList> (driver->nodePool(), sym(1).VariableDeclarationList, sym(3).VariableDeclaration);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1573 "./javascript.g"
-
 case 198: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::VariableDeclarationList> (driver->nodePool(), sym(1).VariableDeclaration);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
 } break;
 
-#line 1581 "./javascript.g"
-
 case 199: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::VariableDeclarationList> (driver->nodePool(), sym(1).VariableDeclarationList, sym(3).VariableDeclaration);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1589 "./javascript.g"
-
 case 200: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::VariableDeclaration> (driver->nodePool(), sym(1).sval, sym(2).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
 } break;
 
-#line 1597 "./javascript.g"
-
 case 201: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::VariableDeclaration> (driver->nodePool(), sym(1).sval, sym(2).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
 } break;
 
-#line 1605 "./javascript.g"
-
 case 202: {
   sym(1) = sym(2);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
 } break;
 
-#line 1613 "./javascript.g"
-
 case 203: {
   sym(1).Node = 0;
 } break;
 
-#line 1622 "./javascript.g"
-
 case 205: {
   sym(1) = sym(2);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
 } break;
 
-#line 1630 "./javascript.g"
-
 case 206: {
   sym(1).Node = 0;
 } break;
 
-#line 1639 "./javascript.g"
-
 case 208: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::EmptyStatement> (driver->nodePool());
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
 } break;
 
-#line 1648 "./javascript.g"
-
 case 210: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::ExpressionStatement> (driver->nodePool(), sym(1).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
 } break;
 
-#line 1656 "./javascript.g"
-
 case 211: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::IfStatement> (driver->nodePool(), sym(3).Expression, sym(5).Statement, sym(7).Statement);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(7));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(7));
 } break;
 
-#line 1664 "./javascript.g"
-
 case 212: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::IfStatement> (driver->nodePool(), sym(3).Expression, sym(5).Statement);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(5));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(5));
 } break;
 
-#line 1674 "./javascript.g"
-
 case 214: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::DoWhileStatement> (driver->nodePool(), sym(2).Statement, sym(5).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(7));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(7));
 } break;
 
-#line 1682 "./javascript.g"
-
 case 215: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::WhileStatement> (driver->nodePool(), sym(3).Expression, sym(5).Statement);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(5));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(5));
 } break;
 
-#line 1690 "./javascript.g"
-
 case 216: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::ForStatement> (driver->nodePool(), sym(3).Expression, sym(5).Expression, sym(7).Expression, sym(9).Statement);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(9));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(9));
 } break;
 
-#line 1698 "./javascript.g"
-
 case 217: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::LocalForStatement> (driver->nodePool(), sym(4).VariableDeclarationList->finish (/*readOnly=*/false), sym(6).Expression, sym(8).Expression, sym(10).Statement);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(10));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(10));
 } break;
 
-#line 1706 "./javascript.g"
-
 case 218: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::ForEachStatement> (driver->nodePool(), sym(3).Expression, sym(5).Expression, sym(7).Statement);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(7));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(7));
 } break;
 
-#line 1714 "./javascript.g"
-
 case 219: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::LocalForEachStatement> (driver->nodePool(), sym(4).VariableDeclaration, sym(6).Expression, sym(8).Statement);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(8));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(8));
 } break;
 
-#line 1723 "./javascript.g"
-
 case 221: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::ContinueStatement> (driver->nodePool());
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
 } break;
 
-#line 1732 "./javascript.g"
-
 case 223: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::ContinueStatement> (driver->nodePool(), sym(2).sval);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1741 "./javascript.g"
-
 case 225: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BreakStatement> (driver->nodePool());
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
 } break;
 
-#line 1750 "./javascript.g"
-
 case 227: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::BreakStatement> (driver->nodePool(), sym(2).sval);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1759 "./javascript.g"
-
 case 229: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::ReturnStatement> (driver->nodePool(), sym(2).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1767 "./javascript.g"
-
 case 230: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::WithStatement> (driver->nodePool(), sym(3).Expression, sym(5).Statement);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(5));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(5));
 } break;
 
-#line 1775 "./javascript.g"
-
 case 231: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::SwitchStatement> (driver->nodePool(), sym(3).Expression, sym(5).CaseBlock);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(5));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(5));
 } break;
 
-#line 1783 "./javascript.g"
-
 case 232: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::CaseBlock> (driver->nodePool(), sym(2).CaseClauses);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1791 "./javascript.g"
-
 case 233: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::CaseBlock> (driver->nodePool(), sym(2).CaseClauses, sym(3).DefaultClause, sym(4).CaseClauses);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(5));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(5));
 } break;
 
-#line 1799 "./javascript.g"
-
 case 234: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::CaseClauses> (driver->nodePool(), sym(1).CaseClause);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
 } break;
 
-#line 1807 "./javascript.g"
-
 case 235: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::CaseClauses> (driver->nodePool(), sym(1).CaseClauses, sym(2).CaseClause);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
 } break;
 
-#line 1815 "./javascript.g"
-
 case 236: {
   sym(1).Node = 0;
 } break;
 
-#line 1822 "./javascript.g"
-
 case 237: {
   sym(1).Node = sym(1).CaseClauses->finish ();
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
 } break;
 
-#line 1830 "./javascript.g"
-
 case 238: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::CaseClause> (driver->nodePool(), sym(2).Expression, sym(4).StatementList);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(4));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(4));
 } break;
 
-#line 1838 "./javascript.g"
-
 case 239: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::DefaultClause> (driver->nodePool(), sym(3).StatementList);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1846 "./javascript.g"
-
 case 240: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::LabelledStatement> (driver->nodePool(), sym(1).sval, sym(3).Statement);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1855 "./javascript.g"
-
 case 242: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::ThrowStatement> (driver->nodePool(), sym(2).Expression);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1863 "./javascript.g"
-
 case 243: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::TryStatement> (driver->nodePool(), sym(2).Statement, sym(3).Catch);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1871 "./javascript.g"
-
 case 244: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::TryStatement> (driver->nodePool(), sym(2).Statement, sym(3).Finally);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1879 "./javascript.g"
-
 case 245: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::TryStatement> (driver->nodePool(), sym(2).Statement, sym(3).Catch, sym(4).Finally);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(4));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(4));
 } break;
 
-#line 1887 "./javascript.g"
-
 case 246: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::Catch> (driver->nodePool(), sym(3).sval, sym(5).Statement);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(5));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(5));
 } break;
 
-#line 1895 "./javascript.g"
-
 case 247: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::Finally> (driver->nodePool(), sym(2).Statement);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
 } break;
 
-#line 1904 "./javascript.g"
-
 case 249: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::DebuggerStatement> (driver->nodePool());
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
 } break;
 
-#line 1912 "./javascript.g"
-
 case 250: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::FunctionDeclaration> (driver->nodePool(), sym(2).sval, sym(4).FormalParameterList, sym(7).FunctionBody);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(8));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(8));
 } break;
 
-#line 1920 "./javascript.g"
-
 case 251: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::FunctionExpression> (driver->nodePool(), sym(2).sval, sym(4).FormalParameterList, sym(7).FunctionBody);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(8));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(8));
 } break;
 
-#line 1928 "./javascript.g"
-
 case 252: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::FormalParameterList> (driver->nodePool(), sym(1).sval);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
 } break;
 
-#line 1936 "./javascript.g"
-
 case 253: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::FormalParameterList> (driver->nodePool(), sym(1).FormalParameterList, sym(3).sval);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(3));
 } break;
 
-#line 1944 "./javascript.g"
-
 case 254: {
   sym(1).Node = 0;
 } break;
 
-#line 1951 "./javascript.g"
-
 case 255: {
   sym(1).Node = sym(1).FormalParameterList->finish ();
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
 } break;
 
-#line 1959 "./javascript.g"
-
 case 256: {
   sym(1).Node = 0;
 } break;
 
-#line 1968 "./javascript.g"
-
 case 258: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::FunctionBody> (driver->nodePool(), sym(1).SourceElements->finish ());
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
 } break;
 
-#line 1976 "./javascript.g"
-
 case 259: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::Program> (driver->nodePool(), sym(1).SourceElements->finish ());
   driver->changeAbstractSyntaxTree(sym(1).Node);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
 } break;
 
-#line 1985 "./javascript.g"
-
 case 260: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::SourceElements> (driver->nodePool(), sym(1).SourceElement);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
 } break;
 
-#line 1993 "./javascript.g"
-
 case 261: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::SourceElements> (driver->nodePool(), sym(1).SourceElements, sym(2).SourceElement);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(2));
 } break;
 
-#line 2001 "./javascript.g"
-
 case 262: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::StatementSourceElement> (driver->nodePool(), sym(1).Statement);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
 } break;
 
-#line 2009 "./javascript.g"
-
 case 263: {
   sym(1).Node = JavaScript::makeAstNode<JavaScript::AST::FunctionSourceElement> (driver->nodePool(), sym(1).FunctionDeclaration);
-  Q_JAVASCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
+  J_SCRIPT_UPDATE_POSITION(sym(1).Node, loc(1), loc(1));
 } break;
 
-#line 2017 "./javascript.g"
-
 case 264: {
   sym(1).sval = 0;
 } break;
 
-#line 2026 "./javascript.g"
-
 case 266: {
   sym(1).Node = 0;
 } break;
 
-#line 2034 "./javascript.g"
+            } // switch
+            action = nt_action(state_stack[tos], lhs[r] - TERMINAL_COUNT);
+        } // if
+    } while (action != 0);
+
+    if (first_token == last_token) {
+        const int errorState = state_stack[tos];
+
+        // automatic insertion of `;'
+        if (t_action(errorState, T_AUTOMATIC_SEMICOLON) && automatic(driver, yytoken)) {
+            SavedToken &tk = token_buffer[0];
+            tk.token = yytoken;
+            tk.dval = yylval;
+            tk.loc = yylloc;
+
+#if 0
+            const QString msg = QString::fromUtf8("Missing `;'");
+
+            diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Warning,
+                yylloc.startLine, yylloc.startColumn, msg));
+#endif
+
+            first_token = &token_buffer[0];
+            last_token = &token_buffer[1];
 
-          } // switch
+            yytoken = T_AUTOMATIC_SEMICOLON;
+            yylval = 0;
 
-          state_stack [tos] = nt_action (act, lhs [r] - TERMINAL_COUNT);
+            action = errorState;
 
-          if (rhs[r] > 1) {
-              location_stack[tos - 1].endLine = location_stack[tos + rhs[r] - 2].endLine;
-              location_stack[tos - 1].endColumn = location_stack[tos + rhs[r] - 2].endColumn;
-              location_stack[tos] = location_stack[tos + rhs[r] - 1];
-          }
+            goto _Lcheck_token;
         }
 
-      else
-        {
-          if (saved_yytoken == -1 && automatic (driver, yytoken) && t_action (state, T_AUTOMATIC_SEMICOLON) > 0)
-            {
-              saved_yytoken = yytoken;
-              yytoken = T_SEMICOLON;
-              continue;
-            }
+        hadErrors = true;
 
-          else if ((state == INITIAL_STATE) && (yytoken == 0)) {
-              // accept empty input
-              yytoken = T_SEMICOLON;
-              continue;
-          }
-
-          int ers = state;
-          int shifts = 0;
-          int reduces = 0;
-          int expected_tokens [3];
-          for (int tk = 0; tk < TERMINAL_COUNT; ++tk)
-            {
-              int k = t_action (ers, tk);
-
-              if (! k)
-                continue;
-              else if (k < 0)
-                ++reduces;
-              else if (spell [tk])
-                {
-                  if (shifts < 3)
-                    expected_tokens [shifts] = tk;
-                  ++shifts;
-                }
-            }
+        static int tokens[] = {
+            T_PLUS,
+            T_EQ,
+
+            T_COMMA,
+            T_COLON,
+            T_SEMICOLON,
+
+            T_RPAREN, T_RBRACKET, T_RBRACE,
+
+            T_NUMERIC_LITERAL,
+            T_IDENTIFIER,
+
+            T_LPAREN, T_LBRACKET, T_LBRACE,
+
+            EOF_SYMBOL
+        };
 
-          error_message.clear ();
-          if (shifts && shifts < 3)
-            {
-              bool first = true;
-
-              for (int s = 0; s < shifts; ++s)
-                {
-                  if (first)
-                    error_message += QLatin1String ("Expected ");
-                  else
-                    error_message += QLatin1String (", ");
-
-                  first = false;
-                  error_message += QLatin1String("`");
-                  error_message += QLatin1String (spell [expected_tokens [s]]);
-                  error_message += QLatin1String("'");
-                }
+        token_buffer[0].token = yytoken;
+        token_buffer[0].dval = yylval;
+        token_buffer[0].loc = yylloc;
+
+        token_buffer[1].token = yytoken = lexer->lex();
+        token_buffer[1].dval  = yylval  = lexer->dval();
+        token_buffer[1].loc   = yylloc  = location(lexer);
+
+        if (t_action(errorState, yytoken)) {
+            const QString msg = QString::fromUtf8("Removed token: `%1'").arg(spell[token_buffer[0].token]);
+
+            diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error,
+                token_buffer[0].loc.startLine, token_buffer[0].loc.startColumn, msg));
+
+            action = errorState;
+            goto _Lcheck_token;
+        }
+
+        for (int *tk = tokens; *tk != EOF_SYMBOL; ++tk) {
+            int a = t_action(errorState, *tk);
+            if (a > 0 && t_action(a, yytoken)) {
+                const QString msg = QString::fromUtf8("Inserted token: `%1'").arg(spell[*tk]);
+
+                diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error,
+                    token_buffer[0].loc.startLine, token_buffer[0].loc.startColumn, msg));
+
+                yytoken = *tk;
+                yylval = 0;
+                yylloc = token_buffer[0].loc;
+
+                first_token = &token_buffer[0];
+                last_token = &token_buffer[2];
+
+                action = errorState;
+                goto _Lcheck_token;
             }
+        }
 
-          if (error_message.isEmpty())
-              error_message = lexer->errorMessage();
+        for (int tk = 1; tk < TERMINAL_COUNT; ++tk) {
+            int a = t_action(errorState, tk);
+            if (a > 0 && t_action(a, yytoken)) {
+                const QString msg = QString::fromUtf8("Inserted token: `%1'").arg(spell[tk]);
+                diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error,
+                    token_buffer[0].loc.startLine, token_buffer[0].loc.startColumn, msg));
 
-          error_lineno = lexer->startLineNo();
-          error_column = lexer->startColumnNo();
+                yytoken = tk;
+                yylval = 0;
+                yylloc = token_buffer[0].loc;
 
-          return false;
+                action = errorState;
+                goto _Lcheck_token;
+            }
         }
+
+        const QString msg = QString::fromUtf8("Unexpected token: `%1'").arg(token_buffer[0].token);
+        diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error,
+            token_buffer[0].loc.startLine, token_buffer[0].loc.startColumn, msg));
     }
 
     return false;
@@ -1583,4 +1196,4 @@ case 266: {
 
 QT_END_NAMESPACE
 
-#endif // QT_NO_JAVASCRIPT
+
diff --git a/src/plugins/qtscripteditor/parser/javascriptparser_p.h b/src/plugins/qtscripteditor/parser/javascriptparser_p.h
index 2119936332f5a75c3de49ceec7f0ff9f03729778..17a1f250adcc23c34109c6d5f8d0088acbc51e42 100644
--- a/src/plugins/qtscripteditor/parser/javascriptparser_p.h
+++ b/src/plugins/qtscripteditor/parser/javascriptparser_p.h
@@ -1,7 +1,5 @@
 // This file was generated by qlalr - DO NOT EDIT!
 
-#line 151 "./javascript.g"
-
 /****************************************************************************
 **
 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
@@ -59,14 +57,15 @@
 // Changes will be lost.
 //
 
-#ifndef JAVAJAVASCRIPTPARSER_P_H
-#define JAVAJAVASCRIPTPARSER_P_H
+#ifndef JAVASCRIPTPARSER_P_H
+#define JAVASCRIPTPARSER_P_H
 
 #include "javascriptgrammar_p.h"
 
-#ifndef QT_NO_JAVASCRIPT
+
 
 #include "javascriptastfwd_p.h"
+#include <QtCore/QList>
 
 QT_BEGIN_NAMESPACE
 
@@ -112,18 +111,48 @@ public:
       int endColumn;
     };
 
+    struct DiagnosticMessage {
+        enum Kind { Warning, Error };
+
+        DiagnosticMessage()
+            : kind(Error), line(0), column(0) {}
+
+        DiagnosticMessage(Kind kind, int line, int column, const QString &message)
+            : kind(kind), line(line), column(column), message(message) {}
+
+        Kind kind;
+        int line;
+        int column;
+        QString message;
+    };
+
 public:
     JavaScriptParser();
     ~JavaScriptParser();
 
     bool parse(JavaScriptEnginePrivate *driver);
 
+    QList<DiagnosticMessage> diagnosticMessages() const
+    { return diagnostic_messages; }
+
+    inline DiagnosticMessage diagnosticMessage() const
+    {
+        foreach (const DiagnosticMessage &d, diagnostic_messages) {
+            if (! d.kind == DiagnosticMessage::Warning)
+                return d;
+        }
+
+        return DiagnosticMessage();
+    }
+
     inline QString errorMessage() const
-    { return error_message; }
+    { return diagnosticMessage().message; }
+
     inline int errorLineNumber() const
-    { return error_lineno; }
+    { return diagnosticMessage().line; }
+
     inline int errorColumnNumber() const
-    { return error_column; }
+    { return diagnosticMessage().column; }
 
 protected:
     inline void reallocateStack();
@@ -140,9 +169,24 @@ protected:
     Value *sym_stack;
     int *state_stack;
     Location *location_stack;
-    QString error_message;
-    int error_lineno;
-    int error_column;
+
+    // error recovery
+    enum { TOKEN_BUFFER_SIZE = 3 };
+
+    struct SavedToken {
+       int token;
+       double dval;
+       Location loc;
+    };
+
+    double yylval;
+    Location yylloc;
+
+    SavedToken token_buffer[TOKEN_BUFFER_SIZE];
+    SavedToken *first_token;
+    SavedToken *last_token;
+
+    QList<DiagnosticMessage> diagnostic_messages;
 };
 
 inline void JavaScriptParser::reallocateStack()
@@ -158,18 +202,12 @@ inline void JavaScriptParser::reallocateStack()
 }
 
 
-#line 472 "./javascript.g"
-
-#define Q_JAVASCRIPT_REGEXPLITERAL_RULE1 7
-
-#line 490 "./javascript.g"
+#define J_SCRIPT_REGEXPLITERAL_RULE1 7
 
-#define Q_JAVASCRIPT_REGEXPLITERAL_RULE2 8
-
-#line 2117 "./javascript.g"
+#define J_SCRIPT_REGEXPLITERAL_RULE2 8
 
 QT_END_NAMESPACE
 
-#endif // QT_NO_JAVASCRIPT
 
-#endif // JAVAJAVASCRIPTPARSER_P_H
+
+#endif // JAVASCRIPTPARSER_P_H
diff --git a/src/plugins/qtscripteditor/qtscripteditor.cpp b/src/plugins/qtscripteditor/qtscripteditor.cpp
index 2d618417b6cad655ba32f45fb1a1882193ab94b6..e6968645041d390a5da2ef8f6cf0d8ddf79e34a8 100644
--- a/src/plugins/qtscripteditor/qtscripteditor.cpp
+++ b/src/plugins/qtscripteditor/qtscripteditor.cpp
@@ -156,6 +156,9 @@ ScriptEditor::~ScriptEditor()
 {
 }
 
+QList<Declaration> ScriptEditor::declarations() const
+{ return m_declarations; }
+
 Core::IEditor *ScriptEditorEditable::duplicate(QWidget *parent)
 {
     ScriptEditor *newEditor = new ScriptEditor(m_context, parent);
@@ -198,35 +201,48 @@ void ScriptEditor::updateDocumentNow()
     lexer.setCode(code, /*line = */ 1);
     driver.setLexer(&lexer);
 
-    QList<QTextEdit::ExtraSelection> selections;
+    parser.parse(&driver);
 
-    if (parser.parse(&driver)) {
+    FindDeclarations decls;
+    m_declarations = decls.accept(driver.ast());
 
-        FindDeclarations decls;
-        m_declarations = decls.accept(driver.ast());
+    QStringList items;
+    items.append(tr("<Select Symbol>"));
 
-        QStringList items;
-        items.append(tr("<Select Symbol>"));
+    foreach (Declaration decl, m_declarations)
+        items.append(decl.text);
 
-        foreach (Declaration decl, m_declarations)
-            items.append(decl.text);
+    m_methodCombo->clear();
+    m_methodCombo->addItems(items);
+    updateMethodBoxIndex();
+
+    QList<QTextEdit::ExtraSelection> selections;
 
-        m_methodCombo->clear();
-        m_methodCombo->addItems(items);
-        updateMethodBoxIndex();
+    QTextCharFormat errorFormat;
+    errorFormat.setUnderlineColor(Qt::red);
+    errorFormat.setUnderlineStyle(QTextCharFormat::WaveUnderline);
 
-    } else {
-        QTextEdit::ExtraSelection sel;
-        sel.format.setUnderlineColor(Qt::red);
-        sel.format.setUnderlineStyle(QTextCharFormat::WaveUnderline);
+    QTextCharFormat warningFormat;
+    warningFormat.setUnderlineColor(Qt::yellow);
+    warningFormat.setUnderlineStyle(QTextCharFormat::WaveUnderline);
 
-        const int line = parser.errorLineNumber();
+    QTextEdit::ExtraSelection sel;
+
+    foreach (const JavaScriptParser::DiagnosticMessage &d, parser.diagnosticMessages()) {
+        const int line = d.line;
 
         QTextCursor c(document()->findBlockByNumber(line - 1));
         sel.cursor = c;
 
         if (parser.errorColumnNumber() > 1)
-            sel.cursor.setPosition(c.position() + parser.errorColumnNumber() - 1);
+            sel.cursor.setPosition(c.position() + d.column - 1);
+
+        if (d.kind == JavaScriptParser::DiagnosticMessage::Warning) {
+            sel.format = warningFormat;
+            sel.cursor.movePosition(QTextCursor::StartOfWord);
+        } else {
+            sel.format = errorFormat;
+        }
 
         sel.cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
 
diff --git a/src/plugins/qtscripteditor/qtscripteditor.h b/src/plugins/qtscripteditor/qtscripteditor.h
index eb91a7bdb9e55e5ef0e822915e6a8ada04d38b5d..dc6aa364b1178abedef299695a670c07c4da64b9 100644
--- a/src/plugins/qtscripteditor/qtscripteditor.h
+++ b/src/plugins/qtscripteditor/qtscripteditor.h
@@ -90,6 +90,8 @@ public:
                  QWidget *parent = 0);
     ~ScriptEditor();
 
+    QList<Declaration> declarations() const;
+
 public slots:
     virtual void setFontSettings(const TextEditor::FontSettings &);
 
diff --git a/src/plugins/qtscripteditor/qtscripteditor.pro b/src/plugins/qtscripteditor/qtscripteditor.pro
index 7694856c4cb0e332b821beaa0acc9dab7c344593..125b97e26c90d42798a5d20ba3631163c133c643 100644
--- a/src/plugins/qtscripteditor/qtscripteditor.pro
+++ b/src/plugins/qtscripteditor/qtscripteditor.pro
@@ -20,4 +20,5 @@ qtscripteditorfactory.cpp \
 qtscripteditorplugin.cpp \
 qtscripthighlighter.cpp \
 qtscripteditoractionhandler.cpp
+
 RESOURCES += qtscripteditor.qrc
diff --git a/tests/manual/fakevim/main.cpp b/tests/manual/fakevim/main.cpp
index 1d31d998403c7eae8cf93cf14b342cf097c93a33..ec007922ff85a19cf55e9e7cd303eda21d672a51 100644
--- a/tests/manual/fakevim/main.cpp
+++ b/tests/manual/fakevim/main.cpp
@@ -119,6 +119,9 @@ int main(int argc, char *argv[])
         &proxy, SLOT(changeStatusData(QString)));
 
     theFakeVimSetting(ConfigUseFakeVim)->setValue(true);
+    theFakeVimSetting(ConfigShiftWidth)->setValue(8);
+    theFakeVimSetting(ConfigTabStop)->setValue(8);
+
     handler.installEventFilter();
     handler.setupWidget();
     if (args.size() >= 1)