diff --git a/src/plugins/cppeditor/cppquickfix.cpp b/src/plugins/cppeditor/cppquickfix.cpp
index f5819b74ed7c04c10723c141586167b757d15301..31080555fe71f5412c66d3ae182a614a6990767b 100644
--- a/src/plugins/cppeditor/cppquickfix.cpp
+++ b/src/plugins/cppeditor/cppquickfix.cpp
@@ -144,24 +144,12 @@ public:
 
     virtual void apply()
     {
-        // nothing to do.
-
-        QTextCursor binaryOp = selectToken(pattern->binary_op_token);
-        QTextCursor firstUnaryOp = selectToken(left->unary_op_token);
-        QTextCursor secondUnaryOp = selectToken(right->unary_op_token);
-
-        QTextCursor tc = textCursor();
-        tc.beginEditBlock();
-        firstUnaryOp.removeSelectedText();
-        secondUnaryOp.removeSelectedText();
-        binaryOp.insertText(QLatin1String("||"));
-        firstUnaryOp.insertText(QLatin1String("!("));
+        replace(pattern->binary_op_token, QLatin1String("||"));
+        replace(left->unary_op_token, QLatin1String("!("));
+        replace(right->unary_op_token, QLatin1String(""));
+        insert(endOf(pattern), QLatin1String(")"));
 
-        QTextCursor endOfRightUnaryExpression = selectToken(right->lastToken() - 1);
-        endOfRightUnaryExpression.setPosition(endOfRightUnaryExpression.position()); // ### method
-
-        endOfRightUnaryExpression.insertText(QLatin1String(")"));
-        tc.endEditBlock();
+        execute();
     }
 
 private:
@@ -193,36 +181,88 @@ void QuickFixOperation::setTextCursor(const QTextCursor &cursor)
 const CPlusPlus::Token &QuickFixOperation::tokenAt(unsigned index) const
 { return _doc->translationUnit()->tokenAt(index); }
 
-int QuickFixOperation::tokenStartPosition(unsigned index) const
+int QuickFixOperation::startOf(unsigned index) const
 {
     unsigned line, column;
     _doc->translationUnit()->getPosition(tokenAt(index).begin(), &line, &column);
     return _textCursor.document()->findBlockByNumber(line - 1).position() + column - 1;
 }
 
-int QuickFixOperation::tokenEndPosition(unsigned index) const
+int QuickFixOperation::startOf(const CPlusPlus::AST *ast) const
+{
+    return startOf(ast->firstToken());
+}
+
+int QuickFixOperation::endOf(unsigned index) const
 {
     unsigned line, column;
     _doc->translationUnit()->getPosition(tokenAt(index).end(), &line, &column);
     return _textCursor.document()->findBlockByNumber(line - 1).position() + column - 1;
 }
 
+int QuickFixOperation::endOf(const CPlusPlus::AST *ast) const
+{
+    return endOf(ast->lastToken() - 1);
+}
+
 QTextCursor QuickFixOperation::selectToken(unsigned index) const
 {
     QTextCursor tc = _textCursor;
-    tc.setPosition(tokenStartPosition(index));
-    tc.setPosition(tokenEndPosition(index), QTextCursor::KeepAnchor);
+    tc.setPosition(startOf(index));
+    tc.setPosition(endOf(index), QTextCursor::KeepAnchor);
     return tc;
 }
 
 QTextCursor QuickFixOperation::selectNode(AST *ast) const
 {
     QTextCursor tc = _textCursor;
-    tc.setPosition(tokenStartPosition(ast->firstToken()));
-    tc.setPosition(tokenEndPosition(ast->lastToken() - 1), QTextCursor::KeepAnchor);
+    tc.setPosition(startOf(ast->firstToken()));
+    tc.setPosition(endOf(ast->lastToken() - 1), QTextCursor::KeepAnchor);
     return tc;
 }
 
+void QuickFixOperation::move(int start, int end, int to)
+{
+    if (end > start)
+        _textWriter.move(start, end-start, to);
+}
+
+void QuickFixOperation::move(unsigned tokenIndex, int to)
+{
+    move(startOf(tokenIndex), endOf(tokenIndex), to);
+}
+
+void QuickFixOperation::move(const CPlusPlus::AST *ast, int to)
+{
+    move(startOf(ast), endOf(ast), to);
+}
+
+void QuickFixOperation::replace(int start, int end, const QString &replacement)
+{
+    if (end >= start)
+        _textWriter.replace(start, end-start, replacement);
+}
+
+void QuickFixOperation::replace(unsigned tokenIndex, const QString &replacement)
+{
+    replace(startOf(tokenIndex), endOf(tokenIndex), replacement);
+}
+
+void QuickFixOperation::replace(const CPlusPlus::AST *ast, const QString &replacement)
+{
+    replace(startOf(ast), endOf(ast), replacement);
+}
+
+void QuickFixOperation::insert(int at, const QString &text)
+{
+    replace(at, at, text);
+}
+
+void QuickFixOperation::execute()
+{
+    _textWriter.write(&_textCursor);
+}
+
 CPPQuickFixCollector::CPPQuickFixCollector()
     : _modelManager(CppTools::CppModelManagerInterface::instance()), _editor(0)
 { }
diff --git a/src/plugins/cppeditor/cppquickfix.h b/src/plugins/cppeditor/cppquickfix.h
index d519db556f3898ec9f3b1857107d91acd064ee45..c90010c0106a007ef09154d95ce2e05ca8dc8f6e 100644
--- a/src/plugins/cppeditor/cppquickfix.h
+++ b/src/plugins/cppeditor/cppquickfix.h
@@ -35,6 +35,8 @@
 #include <cplusplus/CppDocument.h>
 #include <ASTfwd.h>
 
+#include <utils/textwriter.h>
+
 #include <QtCore/QSharedPointer>
 #include <QtGui/QTextCursor>
 
@@ -70,16 +72,29 @@ public:
 
 protected:
     const CPlusPlus::Token &tokenAt(unsigned index) const;
-    int tokenStartPosition(unsigned index) const;
-    int tokenEndPosition(unsigned index) const;
-
     QTextCursor selectToken(unsigned index) const;
     QTextCursor selectNode(CPlusPlus::AST *ast) const;
 
+    int startOf(unsigned index) const;
+    int startOf(const CPlusPlus::AST *ast) const;
+    int endOf(unsigned index) const;
+    int endOf(const CPlusPlus::AST *ast) const;
+
+    void move(int start, int end, int to);
+    void move(unsigned tokenIndex, int to);
+    void move(const CPlusPlus::AST *ast, int to);
+    void replace(int start, int end, const QString &replacement);
+    void replace(unsigned tokenIndex, const QString &replacement);
+    void replace(const CPlusPlus::AST *ast, const QString &replacement);
+    void insert(int at, const QString &text);
+
+    void execute();
+
 private:
     CPlusPlus::Document::Ptr _doc;
     CPlusPlus::Snapshot _snapshot;
     QTextCursor _textCursor;
+    Utils::TextWriter _textWriter;
 };
 
 class CPPQuickFixCollector: public TextEditor::IQuickFixCollector