diff --git a/src/libs/cplusplus/BackwardsScanner.cpp b/src/libs/cplusplus/BackwardsScanner.cpp
index df2916a6d757f1249a9ba61f2431f90ff5fedd32..251fa9bd19e1f51010857c10db0fea9fdcc06375 100644
--- a/src/libs/cplusplus/BackwardsScanner.cpp
+++ b/src/libs/cplusplus/BackwardsScanner.cpp
@@ -27,6 +27,7 @@
 **
 **************************************************************************/
 #include "BackwardsScanner.h"
+#include <Token.h>
 #include <QtGui/QTextCursor>
 
 using namespace CPlusPlus;
@@ -42,10 +43,16 @@ BackwardsScanner::BackwardsScanner(const QTextCursor &cursor, int maxBlockCount)
     _tokens.append(_tokenize(_text, previousBlockState(_block)));
 }
 
-QList<SimpleToken> BackwardsScanner::tokens() const
+int BackwardsScanner::state() const
+{ return _tokenize.state(); }
+
+const QList<SimpleToken> &BackwardsScanner::tokens() const
 { return _tokens; }
 
-const SimpleToken &BackwardsScanner::operator[](int i)
+const SimpleToken &BackwardsScanner::operator[](int i) const
+{ return const_cast<BackwardsScanner *>(this)->fetchToken(i); }
+
+const SimpleToken &BackwardsScanner::fetchToken(int i)
 {
     while (_offset + i < 0) {
         _block = _block.previous();
@@ -77,10 +84,13 @@ const SimpleToken &BackwardsScanner::operator[](int i)
     return _tokens.at(_offset + i);
 }
 
+int BackwardsScanner::startToken() const
+{ return _tokens.size(); }
+
 int BackwardsScanner::startPosition() const
 { return _block.position(); }
 
-const QString &BackwardsScanner::text() const
+QString BackwardsScanner::text() const
 { return _text; }
 
 QString BackwardsScanner::text(int begin, int end) const
@@ -90,7 +100,14 @@ QString BackwardsScanner::text(int begin, int end) const
     return _text.mid(firstToken.begin(), lastToken.end() - firstToken.begin());
 }
 
-int BackwardsScanner::previousBlockState(const QTextBlock &block)
+QStringRef BackwardsScanner::textRef(int begin, int end) const
+{
+    const SimpleToken &firstToken = _tokens.at(begin + _offset);
+    const SimpleToken &lastToken = _tokens.at(end + _offset - 1);
+    return _text.midRef(firstToken.begin(), lastToken.end() - firstToken.begin());
+}
+
+int BackwardsScanner::previousBlockState(const QTextBlock &block) const
 {
     const QTextBlock prevBlock = block.previous();
 
@@ -103,3 +120,45 @@ int BackwardsScanner::previousBlockState(const QTextBlock &block)
 
     return 0;
 }
+
+int BackwardsScanner::startOfMatchingBrace(int index) const
+{
+    const BackwardsScanner &tk = *this;
+
+    if (tk[index - 1].is(T_RPAREN)) {
+        int i = index - 1;
+        int count = 0;
+        do {
+            if (tk[i].is(T_LPAREN)) {
+                if (! ++count)
+                    return i;
+            } else if (tk[i].is(T_RPAREN))
+                --count;
+            --i;
+        } while (count != 0 && tk[i].isNot(T_EOF_SYMBOL));
+    } else if (tk[index - 1].is(T_RBRACKET)) {
+        int i = index - 1;
+        int count = 0;
+        do {
+            if (tk[i].is(T_LBRACKET)) {
+                if (! ++count)
+                    return i;
+            } else if (tk[i].is(T_RBRACKET))
+                --count;
+            --i;
+        } while (count != 0 && tk[i].isNot(T_EOF_SYMBOL));
+    } else if (tk[index - 1].is(T_GREATER)) {
+        int i = index - 1;
+        int count = 0;
+        do {
+            if (tk[i].is(T_LESS)) {
+                if (! ++count)
+                    return i;
+            } else if (tk[i].is(T_GREATER))
+                --count;
+            --i;
+        } while (count != 0 && tk[i].isNot(T_EOF_SYMBOL));
+    }
+
+    return index;
+}
diff --git a/src/libs/cplusplus/BackwardsScanner.h b/src/libs/cplusplus/BackwardsScanner.h
index c38060040bc3e62d9047bebde8b8d0b321f28913..925527cbcf1b39793b4c2377cdc3d3f178f492ce 100644
--- a/src/libs/cplusplus/BackwardsScanner.h
+++ b/src/libs/cplusplus/BackwardsScanner.h
@@ -43,13 +43,23 @@ class CPLUSPLUS_EXPORT BackwardsScanner
 public:
     BackwardsScanner(const QTextCursor &cursor, int maxBlockCount = MAX_BLOCK_COUNT);
 
-    QList<SimpleToken> tokens() const;
+    int state() const;
+    int startToken() const;
+
     int startPosition() const;
-    const QString &text() const;
 
-    const SimpleToken &operator[](int i);
+    QString text() const;
     QString text(int begin, int end) const;
-    int previousBlockState(const QTextBlock &block);
+    QStringRef textRef(int begin, int end) const;
+
+    const SimpleToken &operator[](int i) const;
+
+    int startOfMatchingBrace(int index) const;
+    int previousBlockState(const QTextBlock &block) const;
+
+private:
+    const SimpleToken &fetchToken(int i);
+    const QList<SimpleToken> &tokens() const;
 
 private:
     QList<SimpleToken> _tokens;
diff --git a/src/libs/cplusplus/ExpressionUnderCursor.cpp b/src/libs/cplusplus/ExpressionUnderCursor.cpp
index 1cc546de2265068f5919ab932468e2699eeacb5f..622b420048b6b845fddf8c2f575b6babca341444 100644
--- a/src/libs/cplusplus/ExpressionUnderCursor.cpp
+++ b/src/libs/cplusplus/ExpressionUnderCursor.cpp
@@ -43,46 +43,6 @@ ExpressionUnderCursor::ExpressionUnderCursor()
 ExpressionUnderCursor::~ExpressionUnderCursor()
 { }
 
-int ExpressionUnderCursor::startOfMatchingBrace(BackwardsScanner &tk, int index)
-{
-    if (tk[index - 1].is(T_RPAREN)) {
-        int i = index - 1;
-        int count = 0;
-        do {
-            if (tk[i].is(T_LPAREN)) {
-                if (! ++count)
-                    return i;
-            } else if (tk[i].is(T_RPAREN))
-                --count;
-            --i;
-        } while (count != 0 && tk[i].isNot(T_EOF_SYMBOL));
-    } else if (tk[index - 1].is(T_RBRACKET)) {
-        int i = index - 1;
-        int count = 0;
-        do {
-            if (tk[i].is(T_LBRACKET)) {
-                if (! ++count)
-                    return i;
-            } else if (tk[i].is(T_RBRACKET))
-                --count;
-            --i;
-        } while (count != 0 && tk[i].isNot(T_EOF_SYMBOL));
-    } else if (tk[index - 1].is(T_GREATER)) {
-        int i = index - 1;
-        int count = 0;
-        do {
-            if (tk[i].is(T_LESS)) {
-                if (! ++count)
-                    return i;
-            } else if (tk[i].is(T_GREATER))
-                --count;
-            --i;
-        } while (count != 0 && tk[i].isNot(T_EOF_SYMBOL));
-    }
-
-    return index;
-}
-
 int ExpressionUnderCursor::startOfExpression(BackwardsScanner &tk, int index)
 {
     // tk is a reference to a const QList. So, don't worry about [] access.
@@ -122,10 +82,10 @@ int ExpressionUnderCursor::startOfExpression(BackwardsScanner &tk, int index)
         }
         return index - 1;
     } else if (tk[index - 1].is(T_RPAREN)) {
-        int rparenIndex = startOfMatchingBrace(tk, index);
+        int rparenIndex = tk.startOfMatchingBrace(index);
         if (rparenIndex != index) {
             if (tk[rparenIndex - 1].is(T_GREATER)) {
-                int lessIndex = startOfMatchingBrace(tk, rparenIndex);
+                int lessIndex = tk.startOfMatchingBrace(rparenIndex);
                 if (lessIndex != rparenIndex - 1) {
                     if (tk[lessIndex - 1].is(T_DYNAMIC_CAST)     ||
                         tk[lessIndex - 1].is(T_STATIC_CAST)      ||
@@ -144,13 +104,13 @@ int ExpressionUnderCursor::startOfExpression(BackwardsScanner &tk, int index)
         }
         return index;
     } else if (tk[index - 1].is(T_RBRACKET)) {
-        int rbracketIndex = startOfMatchingBrace(tk, index);
+        int rbracketIndex = tk.startOfMatchingBrace(index);
         if (rbracketIndex != index)
             return startOfExpression(tk, rbracketIndex);
         return index;
     } else if (tk[index - 1].is(T_COLON_COLON)) {
         if (tk[index - 2].is(T_GREATER)) { // ### not exactly
-            int lessIndex = startOfMatchingBrace(tk, index - 1);
+            int lessIndex = tk.startOfMatchingBrace(index - 1);
             if (lessIndex != index - 1)
                 return startOfExpression(tk, lessIndex);
             return index - 1;
@@ -185,7 +145,7 @@ QString ExpressionUnderCursor::operator()(const QTextCursor &cursor)
 
     _jumpedComma = false;
 
-    const int initialSize = scanner.tokens().size();
+    const int initialSize = scanner.startToken();
     const int i = startOfExpression(scanner, initialSize);
     if (i == initialSize)
         return QString();
@@ -199,7 +159,7 @@ int ExpressionUnderCursor::startOfFunctionCall(const QTextCursor &cursor)
 
     BackwardsScanner scanner(cursor);
 
-    int index = scanner.tokens().size();
+    int index = scanner.startToken();
 
     forever {
         const SimpleToken &tk = scanner[index - 1];
@@ -209,7 +169,7 @@ int ExpressionUnderCursor::startOfFunctionCall(const QTextCursor &cursor)
         else if (tk.is(T_LPAREN))
             return scanner.startPosition() + tk.position();
         else if (tk.is(T_RPAREN)) {
-            int matchingBrace = startOfMatchingBrace(scanner, index);
+            int matchingBrace = scanner.startOfMatchingBrace(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 50404d2d5d13b5242adc27714944644add269a3c..2c5ca12bcb6ae612146f0195e5d9ce73953af88a 100644
--- a/src/libs/cplusplus/ExpressionUnderCursor.h
+++ b/src/libs/cplusplus/ExpressionUnderCursor.h
@@ -54,7 +54,6 @@ public:
     int startOfFunctionCall(const QTextCursor &cursor);
 
 private:
-    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/MatchingText.cpp b/src/libs/cplusplus/MatchingText.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..14449584d140db21803c82b60a50c12d38645bb8
--- /dev/null
+++ b/src/libs/cplusplus/MatchingText.cpp
@@ -0,0 +1,131 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+#include "MatchingText.h"
+#include "BackwardsScanner.h"
+
+#include <Token.h>
+#include <QtDebug>
+
+using namespace CPlusPlus;
+
+MatchingText::MatchingText()
+{ }
+
+QString MatchingText::insertParagraphSeparator(const QTextCursor &tc) const
+{
+    BackwardsScanner tk(tc, 400);
+    int index = tk.startToken();
+
+    if (tk[index - 1].isNot(T_LBRACE))
+        return QString(); // nothing to do.
+
+    --index; // consume the `{'
+
+    const SimpleToken &token = tk[index - 1];
+
+    if (token.is(T_STRING_LITERAL) && tk[index - 2].is(T_EXTERN)) {
+        // recognized extern "C"
+        return QLatin1String("}");
+
+    } else if (token.is(T_IDENTIFIER)) {
+        int i = index - 1;
+
+        forever {
+            const SimpleToken &current = tk[i - 1];
+
+            if (current.is(T_EOF_SYMBOL))
+                break;
+
+            else if (current.is(T_CLASS) || current.is(T_STRUCT) || current.is(T_UNION))
+                return QLatin1String("};"); // found a class key.
+
+            else if (current.is(T_NAMESPACE))
+                return QLatin1String("}"); // found a namespace declaration
+
+            else if (current.is(T_SEMICOLON))
+                break; // found the `;' sync token
+
+            else if (current.is(T_LBRACE) || current.is(T_RBRACE))
+                break; // braces are considered sync tokens
+
+            else if (current.is(T_LPAREN) || current.is(T_RPAREN))
+                break; // sync token
+
+            else if (current.is(T_LBRACKET) || current.is(T_RBRACKET))
+                break; // sync token
+
+            --i;
+        }
+    }
+
+    if (token.is(T_NAMESPACE)) {
+        // anonymous namespace
+        return QLatin1String("}");
+
+    } else if (token.is(T_CLASS) || token.is(T_STRUCT) || token.is(T_UNION)) {
+        if (tk[index - 2].is(T_TYPEDEF)) {
+            // recognized:
+            //   typedef struct {
+            //
+            // in this case we don't want to insert the extra semicolon+newline.
+            return QLatin1String("}");
+        }
+
+        // anonymous class
+        return QLatin1String("};");
+
+    } else if (token.is(T_RPAREN)) {
+        // search the matching brace.
+        const int lparenIndex = tk.startOfMatchingBrace(index);
+
+        if (lparenIndex == index) {
+            // found an unmatched brace. We don't really know to do in this case.
+            return QString();
+        }
+
+        // look at the token before the matched brace
+        const SimpleToken &tokenBeforeBrace = tk[lparenIndex - 1];
+
+        if (tokenBeforeBrace.is(T_IF)) {
+            // recognized an if statement
+            return QLatin1String("}");
+
+        } else if (tokenBeforeBrace.is(T_FOR) || tokenBeforeBrace.is(T_WHILE)) {
+            // recognized a for-like statement
+            return QLatin1String("}");
+
+        }
+
+        // if we reached this point there is a good chance that we are parsing a function definition
+        return QLatin1String("}");
+    }
+
+    // match the block
+    return QLatin1String("}");
+}
diff --git a/src/libs/cplusplus/MatchingText.h b/src/libs/cplusplus/MatchingText.h
new file mode 100644
index 0000000000000000000000000000000000000000..3f7ef2cebf97c3481315cd576992c27950e7437c
--- /dev/null
+++ b/src/libs/cplusplus/MatchingText.h
@@ -0,0 +1,49 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+#ifndef MATCHINGTEXT_H
+#define MATCHINGTEXT_H
+
+#include <CPlusPlusForwardDeclarations.h>
+#include <QtGui/QTextCursor>
+
+namespace CPlusPlus {
+
+class BackwardsScanner;
+
+class CPLUSPLUS_EXPORT MatchingText
+{
+public:
+    MatchingText();
+
+    QString insertParagraphSeparator(const QTextCursor &tc) const;
+};
+
+} // end of namespace CPlusPlus
+
+#endif // MATCHINGTEXT_H
diff --git a/src/libs/cplusplus/cplusplus-lib.pri b/src/libs/cplusplus/cplusplus-lib.pri
index 1cc2bd08e10666da9451b4efa2a723194a02fce5..34caa520a80b538ac0af4d7eb9ad637cf9b23899 100644
--- a/src/libs/cplusplus/cplusplus-lib.pri
+++ b/src/libs/cplusplus/cplusplus-lib.pri
@@ -9,6 +9,7 @@ HEADERS += \
     $$PWD/ExpressionUnderCursor.h \
     $$PWD/TokenUnderCursor.h \
     $$PWD/BackwardsScanner.h \
+    $$PWD/MatchingText.h \
     $$PWD/OverviewModel.h
 
 SOURCES += \
@@ -16,6 +17,7 @@ SOURCES += \
     $$PWD/ExpressionUnderCursor.cpp \
     $$PWD/TokenUnderCursor.cpp \
     $$PWD/BackwardsScanner.cpp \
+    $$PWD/MatchingText.cpp \
     $$PWD/OverviewModel.cpp
 }
 
diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp
index a90c2fbfad4926d08d5a5c75bbad2d3bade2f20c..ee8f965497d9cc78321eaee44e914273f33411c3 100644
--- a/src/plugins/cppeditor/cppeditor.cpp
+++ b/src/plugins/cppeditor/cppeditor.cpp
@@ -52,6 +52,7 @@
 #include <cplusplus/SimpleLexer.h>
 #include <cplusplus/TokenUnderCursor.h>
 #include <cplusplus/TypeOfExpression.h>
+#include <cplusplus/MatchingText.h>
 #include <cpptools/cppmodelmanagerinterface.h>
 
 #include <coreplugin/icore.h>
@@ -1374,7 +1375,11 @@ int CPPEditor::paragraphSeparatorAboutToBeInserted(QTextCursor &cursor)
 
     if (braceDepth > 0) { // we do have an extra brace, let's close it
         int pos = cursor.position();
-        cursor.insertText(QLatin1String("}"));
+
+        MatchingText matchingText;
+        const QString textToInsert = matchingText.insertParagraphSeparator(cursor);
+
+        cursor.insertText(textToInsert);
         cursor.setPosition(pos);
         const TabSettings &ts = tabSettings();
         if (ts.m_autoIndent) {