diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp
index 78d2522639b22d572a29c9c915516465bcddc200..79530908c770d8021941a660f865b9a99f0b961b 100644
--- a/src/plugins/debugger/gdbengine.cpp
+++ b/src/plugins/debugger/gdbengine.cpp
@@ -2988,6 +2988,12 @@ void GdbEngine::runCustomDumper(const WatchData & data0, bool dumpChildren)
             //extraArgs[extraArgCount++] = sizeofTypeExpression(data.type);
             //extraArgs[extraArgCount++] = "(size_t)&(('" + data.type + "'*)0)->value";
         }
+    } else if (outertype == "std::deque") {
+        // remove 'std::allocator<...>':
+        extraArgs[1] = "0";
+    } else if (outertype == "std::stack") {
+        // remove 'std::allocator<...>':
+        extraArgs[1] = "0";
     } else if (outertype == "std::map") {
         // We don't want the comparator and the allocator confuse gdb.
         // But we need the offset of the second item in the value pair.
diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp
index 92c38397332c65b08d5cfc74e0ccf5989da35421..09542b807dac03ab1bf920f8251f1ab5e1d33293 100644
--- a/src/plugins/fakevim/fakevimhandler.cpp
+++ b/src/plugins/fakevim/fakevimhandler.cpp
@@ -254,11 +254,18 @@ public:
     void recordRemove(int position, const QString &data);
     void recordRemove(int position, int length);
     void recordMove(int position, int nestedCount);
-    void removeSelectedText(QTextCursor &tc);
+
+    void recordRemoveNextChar();
+    void recordInsertText(const QString &data);
+    void recordRemoveSelectedText();
+    void recordBeginGroup();
+    void recordEndGroup();
+
     void undo();
     void redo();
     QStack<EditOperation> m_undoStack;
     QStack<EditOperation> m_redoStack;
+    QStack<int> m_undoGroupStack;
 
     // extra data for '.'
     QString m_dotCount;
@@ -394,7 +401,7 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommand)
         if (!dotCommand.isEmpty())
             m_dotCommand = "c" + dotCommand;
         m_registers[m_register] = m_tc.selectedText();
-        removeSelectedText(m_tc);
+        recordRemoveSelectedText();
         m_mode = InsertMode;
         m_submode = NoSubMode;
     } else if (m_submode == DeleteSubMode) {
@@ -402,7 +409,7 @@ void FakeVimHandler::Private::finishMovement(const QString &dotCommand)
             m_dotCommand = "d" + dotCommand;
         recordRemove(qMin(m_tc.position(), m_tc.anchor()), m_tc.selectedText());
         m_registers[m_register] = m_tc.selectedText();
-        removeSelectedText(m_tc);
+        recordRemoveSelectedText();
         m_submode = NoSubMode;
         if (atEol())
             m_tc.movePosition(Left, MoveAnchor, 1);
@@ -725,7 +732,7 @@ bool FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
         int beginLine = lineForPosition(m_marks['<']);
         int endLine = lineForPosition(m_marks['>']);
         m_tc = selectRange(beginLine, endLine);
-        removeSelectedText(m_tc);
+        recordRemoveSelectedText();
     } else if (key == 'D') {
         m_submode = DeleteSubMode;
         m_tc.movePosition(Down, KeepAnchor, qMax(count() - 1, 0));
@@ -772,27 +779,29 @@ bool FakeVimHandler::Private::handleCommandMode(int key, int unmodified,
             moveToFirstNonBlankOnLine();
     } else if (key == 'j' || key == Key_Down) {
         int savedColumn = m_desiredColumn;
-        if (m_submode == NoSubMode || m_submode == ZSubMode || m_submode == RegisterSubMode) {
+        if (m_submode == NoSubMode || m_submode == ZSubMode
+                || m_submode == RegisterSubMode) {
             m_tc.movePosition(Down, KeepAnchor, count());
             moveToDesiredColumn();
         } else {
             m_tc.movePosition(StartOfLine, MoveAnchor);
-            m_tc.movePosition(Down, KeepAnchor, count()+1);
+            m_tc.movePosition(Down, KeepAnchor, count() + 1);
         }
         finishMovement();
         m_desiredColumn = savedColumn;
     } else if (key == 'J') {
-        EditOperation op;
+        recordBeginGroup();
         if (m_submode == NoSubMode) {
             for (int i = qMax(count(), 2) - 1; --i >= 0; ) {
                 m_tc.movePosition(EndOfLine);
-                m_tc.deleteChar();
+                recordRemoveNextChar();
                 if (!m_gflag)
-                    m_tc.insertText(" ");
+                    recordInsertText(" ");
             }
             if (!m_gflag)
                 m_tc.movePosition(Left, MoveAnchor, 1);
         }
+        recordEndGroup();
     } else if (key == 'k' || key == Key_Up) {
         int savedColumn = m_desiredColumn;
         if (m_submode == NoSubMode || m_submode == ZSubMode || m_submode == RegisterSubMode) {
@@ -1707,13 +1716,41 @@ void FakeVimHandler::Private::redo()
 #endif
 }
 
-void FakeVimHandler::Private::removeSelectedText(QTextCursor &tc)
+void FakeVimHandler::Private::recordBeginGroup()
+{
+    m_undoGroupStack.push(m_undoStack.size());
+}
+
+void FakeVimHandler::Private::recordEndGroup()
+{
+    EditOperation op;
+    op.m_itemCount = m_undoStack.size() - m_undoGroupStack.pop();
+    recordOperation(op);
+}
+
+void FakeVimHandler::Private::recordRemoveSelectedText()
 {
     EditOperation op;
-    op.m_position = qMin(tc.position(), tc.anchor());
-    op.m_from = tc.selection().toPlainText();
+    op.m_position = qMin(m_tc.position(), m_tc.anchor());
+    op.m_from = m_tc.selection().toPlainText();
+    recordOperation(op);
+    m_tc.removeSelectedText();
+}
+
+void FakeVimHandler::Private::recordRemoveNextChar()
+{
+    m_tc.setPosition(m_tc.position(), MoveAnchor);
+    m_tc.movePosition(Right, KeepAnchor);
+    recordRemoveSelectedText();
+}
+
+void FakeVimHandler::Private::recordInsertText(const QString &data)
+{
+    EditOperation op;
+    op.m_position = m_tc.position();
+    op.m_to = data;
     recordOperation(op);
-    tc.removeSelectedText();
+    m_tc.insertText(data);
 }
 
 void FakeVimHandler::Private::recordOperation(const EditOperation &op)