diff --git a/src/libs/cplusplus/ExpressionUnderCursor.cpp b/src/libs/cplusplus/ExpressionUnderCursor.cpp
index 53dc9b4f2d114efa47d7c8b9e868939eb97121bd..aab83d53772c0265fe5941e96aae43484432550f 100644
--- a/src/libs/cplusplus/ExpressionUnderCursor.cpp
+++ b/src/libs/cplusplus/ExpressionUnderCursor.cpp
@@ -36,13 +36,100 @@
 
 using namespace CPlusPlus;
 
+namespace CPlusPlus {
+
+class BackwardsScanner
+{
+    enum { MAX_BLOCK_COUNT = 10 };
+
+public:
+    BackwardsScanner(const QTextCursor &cursor)
+        : _offset(0)
+        , _blocksTokenized(0)
+        , _block(cursor.block())
+    {
+        _tokenize.setSkipComments(true);
+        _text = _block.text().left(cursor.position() - cursor.block().position());
+        _tokens.append(_tokenize(_text, previousBlockState(_block)));
+    }
+
+    QList<SimpleToken> tokens() const { return _tokens; }
+
+    const SimpleToken &operator[](int i)
+    {
+        while (_offset + i < 0) {
+            _block = _block.previous();
+            if (_blocksTokenized == MAX_BLOCK_COUNT || !_block.isValid()) {
+                ++_offset;
+                _tokens.prepend(SimpleToken()); // sentinel
+                break;
+            } else {
+                ++_blocksTokenized;
+
+                QString blockText = _block.text();
+                _text.prepend(blockText);
+                QList<SimpleToken> adaptedTokens;
+                for (int i = 0; i < _tokens.size(); ++i) {
+                    const SimpleToken &t = _tokens.at(i);
+                    const int position = t.position() + blockText.length();
+                    adaptedTokens.append(SimpleToken(t.kind(),
+                                                     position,
+                                                     t.length(),
+                                                     _text.midRef(position, t.length())));
+                }
+
+                _tokens = _tokenize(blockText, previousBlockState(_block));
+                _offset += _tokens.size();
+                _tokens += adaptedTokens;
+            }
+        }
+
+        return _tokens.at(_offset + i);
+    }
+
+    int startPosition() const
+    { return _block.position(); }
+
+    const QString &text() const
+    { return _text; }
+
+    QString text(int begin, int end) const
+    {
+        const SimpleToken &firstToken = _tokens.at(begin + _offset);
+        const SimpleToken &lastToken = _tokens.at(end + _offset - 1);
+        return _text.mid(firstToken.begin(), lastToken.end() - firstToken.begin());
+    }
+
+    int previousBlockState(const QTextBlock &block)
+    {
+        const QTextBlock prevBlock = block.previous();
+        if (prevBlock.isValid()) {
+            int state = prevBlock.userState();
+
+            if (state != -1)
+                return state;
+        }
+        return 0;
+    }
+
+private:
+    QList<SimpleToken> _tokens;
+    int _offset;
+    int _blocksTokenized;
+    QTextBlock _block;
+    QString _text;
+    SimpleLexer _tokenize;
+};
+
+}
+
 ExpressionUnderCursor::ExpressionUnderCursor()
 { }
 
 ExpressionUnderCursor::~ExpressionUnderCursor()
 { }
 
-int ExpressionUnderCursor::startOfMatchingBrace(const QList<SimpleToken> &tk, int index)
+int ExpressionUnderCursor::startOfMatchingBrace(BackwardsScanner &tk, int index)
 {
     if (tk[index - 1].is(T_RPAREN)) {
         int i = index - 1;
@@ -54,7 +141,7 @@ int ExpressionUnderCursor::startOfMatchingBrace(const QList<SimpleToken> &tk, in
             } else if (tk[i].is(T_RPAREN))
                 --count;
             --i;
-        } while (count != 0 && i > -1);
+        } while (count != 0 && tk[i].isNot(T_EOF_SYMBOL));
     } else if (tk[index - 1].is(T_RBRACKET)) {
         int i = index - 1;
         int count = 0;
@@ -65,7 +152,7 @@ int ExpressionUnderCursor::startOfMatchingBrace(const QList<SimpleToken> &tk, in
             } else if (tk[i].is(T_RBRACKET))
                 --count;
             --i;
-        } while (count != 0 && i > -1);
+        } while (count != 0 && tk[i].isNot(T_EOF_SYMBOL));
     } else if (tk[index - 1].is(T_GREATER)) {
         int i = index - 1;
         int count = 0;
@@ -76,13 +163,13 @@ int ExpressionUnderCursor::startOfMatchingBrace(const QList<SimpleToken> &tk, in
             } else if (tk[i].is(T_GREATER))
                 --count;
             --i;
-        } while (count != 0 && i > -1);
+        } while (count != 0 && tk[i].isNot(T_EOF_SYMBOL));
     }
 
     return index;
 }
 
-int ExpressionUnderCursor::startOfExpression(const QList<SimpleToken> &tk, int index)
+int ExpressionUnderCursor::startOfExpression(BackwardsScanner &tk, int index)
 {
     // tk is a reference to a const QList. So, don't worry about [] access.
     // ### TODO implement multiline support. It should be pretty easy.
@@ -178,95 +265,37 @@ bool ExpressionUnderCursor::isAccessToken(const SimpleToken &tk)
     } // switch
 }
 
-int ExpressionUnderCursor::previousBlockState(const QTextBlock &block)
-{
-    const QTextBlock prevBlock = block.previous();
-    if (prevBlock.isValid()) {
-        int state = prevBlock.userState();
-
-        if (state != -1)
-            return state;
-    }
-    return 0;
-}
-
-void ExpressionUnderCursor::init(const QTextCursor &cursor,
-                                 QList<SimpleToken> *tokens,
-                                 QString *text,
-                                 int *startPosition)
-{
-    enum { MAX_BLOCK_COUNT = 5 };
-
-    QTextBlock block = cursor.block();
-    QTextBlock initialBlock = block;
-    for (int i = 0; i < MAX_BLOCK_COUNT; ++i) {
-        if (! initialBlock.previous().isValid())
-            break;
-
-        initialBlock = initialBlock.previous();
-    }
-
-    QTextBlock it = initialBlock;
-    for (; it.isValid(); it = it.next()) {
-        QString textBlock = it.text();
-
-        if (it == block)
-            textBlock = textBlock.left(cursor.position() - cursor.block().position());
-
-        text->append(textBlock);
-
-        if (it == block)
-            break;
-
-        text->append(QLatin1Char('\n'));
-    }
-
-    SimpleLexer tokenize;
-    tokenize.setSkipComments(true);
-    tokens->append(tokenize(*text, previousBlockState(initialBlock)));
-    tokens->prepend(SimpleToken()); // sentinel
-
-    if (startPosition)
-        *startPosition = initialBlock.position();
-}
-
 QString ExpressionUnderCursor::operator()(const QTextCursor &cursor)
 {
-    QList<SimpleToken> tokens;
-    QString text;
-
-    init(cursor, &tokens, &text);
+    BackwardsScanner scanner(cursor);
 
     _jumpedComma = false;
 
-    const int i = startOfExpression(tokens, tokens.size());
-    if (i == tokens.size())
+    const int initialSize = scanner.tokens().size();
+    const int i = startOfExpression(scanner, initialSize);
+    if (i == initialSize)
         return QString();
 
-    return text.mid(tokens.at(i).position(),
-                    tokens.last().position() + tokens.last().length()
-                                             - tokens.at(i).position());
+    return scanner.text(i, initialSize);
 }
 
 int ExpressionUnderCursor::startOfFunctionCall(const QTextCursor &cursor)
 {
-    QList<SimpleToken> tokens;
     QString text;
-    int startPosition;
 
-    init(cursor, &tokens, &text, &startPosition);
+    BackwardsScanner scanner(cursor);
 
-    int index = tokens.size();
+    int index = scanner.tokens().size();
 
     forever {
-        const SimpleToken &tk = tokens.at(index - 1);
+        const SimpleToken &tk = scanner[index - 1];
 
         if (tk.is(T_EOF_SYMBOL))
             break;
         else if (tk.is(T_LPAREN))
-            return startPosition + tk.position();
+            return scanner.startPosition() + tk.position();
         else if (tk.is(T_RPAREN)) {
-            int matchingBrace = startOfMatchingBrace(tokens, index);
+            int matchingBrace = startOfMatchingBrace(scanner, index);
 
             if (matchingBrace == index) // If no matching brace found
                 return -1;
diff --git a/src/libs/cplusplus/ExpressionUnderCursor.h b/src/libs/cplusplus/ExpressionUnderCursor.h
index dda77c406c5ed5944e259b826528d8cb146305bf..1214d08902de6acb895777611ae909733021e53f 100644
--- a/src/libs/cplusplus/ExpressionUnderCursor.h
+++ b/src/libs/cplusplus/ExpressionUnderCursor.h
@@ -41,6 +41,7 @@ QT_END_NAMESPACE
 
 namespace CPlusPlus {
 
+class BackwardsScanner;
 class SimpleToken;
 
 class CPLUSPLUS_EXPORT ExpressionUnderCursor
@@ -53,13 +54,8 @@ public:
     int startOfFunctionCall(const QTextCursor &cursor);
 
 private:
-    void init(const QTextCursor &cursor,
-              QList<SimpleToken> *tokens,
-              QString *text,
-              int *startPosition = 0);
-
-    int startOfMatchingBrace(const QList<SimpleToken> &tk, int index);
-    int startOfExpression(const QList<SimpleToken> &tk, int index);
+    int startOfMatchingBrace(BackwardsScanner &tk, int index);
+    int startOfExpression(BackwardsScanner &tk, int index);
     int previousBlockState(const QTextBlock &block);
     bool isAccessToken(const SimpleToken &tk);
 
diff --git a/src/libs/cplusplus/SimpleLexer.h b/src/libs/cplusplus/SimpleLexer.h
index 0366738c6bdb9a91841ae40f2fad69bd559979e1..666478016a7865a9e18b506a23a0b81d60a2ca90 100644
--- a/src/libs/cplusplus/SimpleLexer.h
+++ b/src/libs/cplusplus/SimpleLexer.h
@@ -41,6 +41,13 @@ class SimpleLexer;
 class CPLUSPLUS_EXPORT SimpleToken
 {
 public:
+    SimpleToken(int kind, int position, int length, const QStringRef &text)
+        : _kind(kind)
+        , _position(position)
+        , _length(length)
+        , _text(text)
+    { }
+
     SimpleToken()
         : _kind(0),
           _position(0),