diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp
index b814359e199ecf5d53ecb7feebc51024ab60912a..6f800d1c239440c92f1a4d2825cf64d09bc73261 100644
--- a/src/plugins/cppeditor/cppeditor.cpp
+++ b/src/plugins/cppeditor/cppeditor.cpp
@@ -73,6 +73,7 @@
 #include <QtCore/QTimer>
 #include <QtCore/QStack>
 #include <QtGui/QAction>
+#include <QtGui/QApplication>
 #include <QtGui/QHeaderView>
 #include <QtGui/QLayout>
 #include <QtGui/QMenu>
@@ -88,7 +89,8 @@ using namespace CPlusPlus;
 using namespace CppEditor::Internal;
 
 enum {
-    UPDATE_METHOD_BOX_INTERVAL = 150
+    UPDATE_METHOD_BOX_INTERVAL = 150,
+    UPDATE_USES_INTERVAL = 300
 };
 
 namespace {
@@ -653,6 +655,7 @@ CPPEditor::CPPEditor(QWidget *parent)
     : TextEditor::BaseTextEditor(parent)
     , m_mouseNavigationEnabled(true)
     , m_showingLink(false)
+    , m_currentRenameSelection(-1)
 {
     setParenthesesMatchingEnabled(true);
     setMarksVisible(true);
@@ -660,6 +663,9 @@ CPPEditor::CPPEditor(QWidget *parent)
     setCodeFoldingVisible(true);
     baseTextDocument()->setSyntaxHighlighter(new CppHighlighter);
 
+    new QShortcut(QKeySequence(tr("CTRL+SHIFT+r")), this, SLOT(renameInPlace()),
+                  /*ambiguousMember=*/ 0, Qt::WidgetShortcut);
+
 #ifdef WITH_TOKEN_MOVE_POSITION
     new QShortcut(QKeySequence::MoveToPreviousWord, this, SLOT(moveToPreviousToken()),
                   /*ambiguousMember=*/ 0, Qt::WidgetShortcut);
@@ -733,8 +739,14 @@ void CPPEditor::createToolBar(CPPEditorEditable *editable)
     m_updateMethodBoxTimer->setInterval(UPDATE_METHOD_BOX_INTERVAL);
     connect(m_updateMethodBoxTimer, SIGNAL(timeout()), this, SLOT(updateMethodBoxIndexNow()));
 
+    m_updateUsesTimer = new QTimer(this);
+    m_updateUsesTimer->setSingleShot(true);
+    m_updateUsesTimer->setInterval(UPDATE_USES_INTERVAL);
+    connect(m_updateUsesTimer, SIGNAL(timeout()), this, SLOT(updateUsesNow()));
+
     connect(m_methodCombo, SIGNAL(activated(int)), this, SLOT(jumpToMethod(int)));
     connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(updateMethodBoxIndex()));
+    connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(updateUses()));
     connect(m_methodCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(updateMethodBoxToolTip()));
 
     connect(file(), SIGNAL(changed()), this, SLOT(updateFileName()));
@@ -891,6 +903,24 @@ void CPPEditor::simplifyDeclarations()
     simplify(textCursor());
 }
 
+void CPPEditor::renameInPlace()
+{
+    QTextCursor c = textCursor();
+    m_currentRenameSelection = -1;
+
+    m_renameSelections = extraSelections(CodeSemanticsSelection);
+    for (int i = 0; i < m_renameSelections.size(); ++i) {
+        QTextEdit::ExtraSelection s = m_renameSelections.at(i);
+        if (c.position() >= s.cursor.anchor()
+                && c.position() < s.cursor.position()) {
+            m_currentRenameSelection = i;
+            m_renameSelections[i].format.setBackground(QColor(255, 200, 200));
+            setExtraSelections(CodeSemanticsSelection, m_renameSelections);
+            break;
+        }
+    }
+}
+
 void CPPEditor::updateFileName()
 { }
 
@@ -987,14 +1017,33 @@ void CPPEditor::updateMethodBoxIndexNow()
         lastIndex = index;
     }
 
-    QList<QTextEdit::ExtraSelection> selections;
-
     if (lastIndex.isValid()) {
         bool blocked = m_methodCombo->blockSignals(true);
         m_methodCombo->setCurrentIndex(m_proxyModel->mapFromSource(lastIndex).row());
         updateMethodBoxToolTip();
         (void) m_methodCombo->blockSignals(blocked);
     }
+}
+
+void CPPEditor::updateMethodBoxToolTip()
+{
+    m_methodCombo->setToolTip(m_methodCombo->currentText());
+}
+
+void CPPEditor::updateUses()
+{
+    m_updateUsesTimer->start(UPDATE_USES_INTERVAL);
+}
+
+void CPPEditor::updateUsesNow()
+{
+    m_updateUsesTimer->stop();
+
+    if (m_currentRenameSelection != -1)
+        return;
+
+    int line = 0, column = 0;
+    convertPosition(position(), &line, &column);
 
     const Snapshot snapshot = m_modelManager->snapshot();
     const QByteArray preprocessedCode = snapshot.preprocessedCode(toPlainText(), file()->fileName());
@@ -1008,11 +1057,13 @@ void CPPEditor::updateMethodBoxIndexNow()
     FunctionDefinitionAST *currentFunctionDefinition = functionDefinitionUnderCursor(ast, textCursor());
 
     QTextCharFormat format;
-    format.setBackground(Qt::lightGray);
+    format.setBackground(QColor(220, 220, 220));
 
     FindUses useTable(control);
     useTable(currentFunctionDefinition);
 
+    QList<QTextEdit::ExtraSelection> selections;
+
     FindUses::LocalUseIterator it(useTable.localUses);
     while (it.hasNext()) {
         it.next();
@@ -1034,7 +1085,7 @@ void CPPEditor::updateMethodBoxIndexNow()
         highlightUses(document(), format, translationUnit, uses, &selections);
         break; // done
     }
-
+#if 0
     FindUses::ExternalUseIterator it2(useTable.externalUses);
     while (it2.hasNext()) {
         it2.next();
@@ -1056,15 +1107,10 @@ void CPPEditor::updateMethodBoxIndexNow()
         highlightUses(document(), format, translationUnit, uses, &selections);
         break; // done
     }
-
+#endif
     setExtraSelections(CodeSemanticsSelection, selections);
 }
 
-void CPPEditor::updateMethodBoxToolTip()
-{
-    m_methodCombo->setToolTip(m_methodCombo->currentText());
-}
-
 static bool isCompatible(Name *name, Name *otherName)
 {
     if (NameId *nameId = name->asNameId()) {
@@ -1392,6 +1438,26 @@ void CPPEditor::indentBlock(QTextDocument *doc, QTextBlock block, QChar typedCha
     indentCPPBlock(tabSettings(), block, begin, end, typedChar);
 }
 
+bool CPPEditor::event(QEvent *e)
+{
+    switch (e->type()) {
+    case QEvent::ShortcutOverride:
+        qDebug () << "Override?";
+        if (static_cast<QKeyEvent*>(e)->key() == Qt::Key_Escape
+            && m_currentRenameSelection != -1) {
+
+            qDebug() << "Accept!";
+            e->accept();
+            return true;
+        }
+        break;
+    default:
+        break;
+    }
+
+    return BaseTextEditor::event(e);
+}
+
 void CPPEditor::contextMenuEvent(QContextMenuEvent *e)
 {
     QMenu *menu = createStandardContextMenu();
@@ -1412,6 +1478,16 @@ void CPPEditor::contextMenuEvent(QContextMenuEvent *e)
     connect(simplifyDeclarations, SIGNAL(triggered()), this, SLOT(simplifyDeclarations()));
     menu->addAction(simplifyDeclarations);
 
+    const QList<QTextEdit::ExtraSelection> selections =
+            extraSelections(BaseTextEditor::CodeSemanticsSelection);
+
+    if (! selections.isEmpty()) {
+        const QString name = selections.first().cursor.selectedText();
+        QAction *renameAction = new QAction(tr("Rename '%1'").arg(name), menu);
+        connect(renameAction, SIGNAL(triggered()), this, SLOT(renameInPlace()));
+        menu->addAction(renameAction);
+    }
+
     menu->exec(e->globalPos());
     delete menu;
 }
@@ -1477,6 +1553,122 @@ void CPPEditor::keyReleaseEvent(QKeyEvent *e)
     TextEditor::BaseTextEditor::keyReleaseEvent(e);
 }
 
+void CPPEditor::keyPressEvent(QKeyEvent *e)
+{
+    if (m_currentRenameSelection == -1) {
+        TextEditor::BaseTextEditor::keyPressEvent(e);
+        return;
+    }
+
+    QString text = e->text();
+    QTextEdit::ExtraSelection currentRenameSelection = m_renameSelections.at(m_currentRenameSelection);
+
+    QTextCursor::MoveMode moveMode = (e->modifiers() & Qt::ShiftModifier) ? QTextCursor::KeepAnchor : QTextCursor::MoveAnchor;
+
+    switch (e->key()) {
+    case Qt::Key_Enter:
+    case Qt::Key_Return:
+    case Qt::Key_Escape:
+        m_currentRenameSelection = -1;
+        m_renameSelections.clear();
+        setExtraSelections(CodeSemanticsSelection, m_renameSelections);
+        e->accept();
+        break;
+    case Qt::Key_Home: {
+        QTextCursor c = textCursor();
+        c.setPosition(currentRenameSelection.cursor.anchor(), moveMode);
+        setTextCursor(c);
+        e->accept();
+        break;
+    }
+    case Qt::Key_End: {
+        QTextCursor c = textCursor();
+        c.setPosition(currentRenameSelection.cursor.position(), moveMode);
+        setTextCursor(c);
+        e->accept();
+        break;
+    }
+    case Qt::Key_Left: {
+        QTextCursor c = textCursor();
+        c.setPosition(qMax(c.position() - 1, currentRenameSelection.cursor.anchor()), moveMode);
+        setTextCursor(c);
+        e->accept();
+        break;
+    }
+    case Qt::Key_Right: {
+        QTextCursor c = textCursor();
+        c.setPosition(qMin(c.position() + 1, currentRenameSelection.cursor.position()), moveMode);
+        setTextCursor(c);
+        e->accept();
+        break;
+    }
+    case Qt::Key_Backspace: {
+        QTextCursor c = textCursor();
+
+        if (c.position() > currentRenameSelection.cursor.anchor()
+                && c.position() <= currentRenameSelection.cursor.position()) {
+
+            int offset = c.position() - currentRenameSelection.cursor.anchor();
+
+            c.beginEditBlock();
+            for (int i = 0; i < m_renameSelections.size(); ++i) {
+                QTextEdit::ExtraSelection &s = m_renameSelections[i];
+                int pos = s.cursor.anchor();
+                int endPos = s.cursor.position();
+                s.cursor.setPosition(s.cursor.anchor() + offset);
+                s.cursor.deletePreviousChar();
+                s.cursor.setPosition(pos);
+                s.cursor.setPosition(endPos - 1, QTextCursor::KeepAnchor);
+            }
+            c.endEditBlock();
+
+            setTextCursor(c);
+            setExtraSelections(CodeSemanticsSelection, m_renameSelections);
+
+            e->accept();
+        } else {
+            e->accept();
+            qWarning() << "Backspace outside of where you can be";
+        }
+        break;
+    }
+    default: {
+        if (! text.isEmpty() && text.at(0).isPrint()) {
+            QTextCursor c = textCursor();
+
+            if (c.position() >= currentRenameSelection.cursor.anchor()
+                    && c.position() <= currentRenameSelection.cursor.position()) {
+
+                int offset = c.position() - currentRenameSelection.cursor.anchor();
+
+                c.beginEditBlock();
+                for (int i = 0; i < m_renameSelections.size(); ++i) {
+                    QTextEdit::ExtraSelection &s = m_renameSelections[i];
+                    int pos = s.cursor.anchor();
+                    int endPos = s.cursor.position();
+                    s.cursor.setPosition(s.cursor.anchor() + offset);
+                    s.cursor.insertText(text);
+                    s.cursor.setPosition(pos);
+                    s.cursor.setPosition(endPos + text.length(), QTextCursor::KeepAnchor);
+                }
+                c.endEditBlock();
+
+                setTextCursor(c);
+                setExtraSelections(CodeSemanticsSelection, m_renameSelections);
+
+                e->accept();
+            } else {
+                e->accept();
+                qWarning() << "Whaa!";
+            }
+        } else {
+            e->accept();
+        }
+        break;
+    }
+    }
+}
+
 void CPPEditor::showLink(const Link &link)
 {
     QTextEdit::ExtraSelection sel;
diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h
index 5b4f03f65684f388c680592ab59ba98e32d98a7b..7b9a47efa3717d658eeb3bd6529f6f3bff84fae2 100644
--- a/src/plugins/cppeditor/cppeditor.h
+++ b/src/plugins/cppeditor/cppeditor.h
@@ -103,11 +103,13 @@ public slots:
     void deleteEndOfToken();
 
 protected:
+    bool event(QEvent *e);
     void contextMenuEvent(QContextMenuEvent *);
     void mouseMoveEvent(QMouseEvent *);
     void mouseReleaseEvent(QMouseEvent *);
     void leaveEvent(QEvent *);
     void keyReleaseEvent(QKeyEvent *);
+    void keyPressEvent(QKeyEvent *);
 
     TextEditor::BaseTextEditorEditable *createEditableInterface();
 
@@ -120,9 +122,12 @@ private slots:
     void updateMethodBoxIndex();
     void updateMethodBoxIndexNow();
     void updateMethodBoxToolTip();
+    void updateUses();
+    void updateUsesNow();
     void onDocumentUpdated(CPlusPlus::Document::Ptr doc);
     void reformatDocument();
     void simplifyDeclarations();
+    void renameInPlace();
 
 private:
     bool sortedMethodOverview() const;
@@ -177,6 +182,10 @@ private:
     QSortFilterProxyModel *m_proxyModel;
     QAction *m_sortAction;
     QTimer *m_updateMethodBoxTimer;
+    QTimer *m_updateUsesTimer;
+
+    QList<QTextEdit::ExtraSelection> m_renameSelections;
+    int m_currentRenameSelection;
 };
 
 } // namespace Internal