diff --git a/src/plugins/cppeditor/cpphighlighter.cpp b/src/plugins/cppeditor/cpphighlighter.cpp
index c105e2859d00cf8313b82abe3fd84c9cfadf3c21..a413892fb51ac4add6d11e7d4b0b70b068abc890 100644
--- a/src/plugins/cppeditor/cpphighlighter.cpp
+++ b/src/plugins/cppeditor/cpphighlighter.cpp
@@ -239,13 +239,17 @@ void CppHighlighter::highlightBlock(const QString &text)
         int oldState = currentState & 0xff;
         int oldBraceDepth = currentState >> 8;
         if (oldState == tokenize.state() && oldBraceDepth != braceDepth) {
+            BaseTextDocumentLayout::FoldValidator foldValidor;
+            foldValidor.setup(qobject_cast<BaseTextDocumentLayout *>(document()->documentLayout()));
             int delta = braceDepth - oldBraceDepth;
             QTextBlock block = currentBlock().next();
             while (block.isValid() && block.userState() != -1) {
                 BaseTextDocumentLayout::changeBraceDepth(block, delta);
                 BaseTextDocumentLayout::changeFoldingIndent(block, delta);
+                foldValidor.process(block);
                 block = block.next();
             }
+            foldValidor.finalize();
         }
     }
 
diff --git a/src/plugins/texteditor/basetextdocumentlayout.cpp b/src/plugins/texteditor/basetextdocumentlayout.cpp
index f6357e9035d2d06cc278ff69bb4608bde6a7244e..d0d6fe04ba3096b29accf8fe5392be957eb46306 100644
--- a/src/plugins/texteditor/basetextdocumentlayout.cpp
+++ b/src/plugins/texteditor/basetextdocumentlayout.cpp
@@ -575,3 +575,69 @@ QSizeF BaseTextDocumentLayout::documentSize() const
     size.setWidth(qMax((qreal)m_requiredWidth, size.width()));
     return size;
 }
+
+BaseTextDocumentLayout::FoldValidator::FoldValidator()
+    : m_layout(0)
+    , m_requestDocUpdate(false)
+    , m_insideFold(0)
+{}
+
+void BaseTextDocumentLayout::FoldValidator::setup(BaseTextDocumentLayout *layout)
+{
+    m_layout = layout;
+}
+
+void BaseTextDocumentLayout::FoldValidator::reset()
+{
+    m_insideFold = 0;
+    m_requestDocUpdate = false;
+}
+
+void BaseTextDocumentLayout::FoldValidator::process(QTextBlock block)
+{
+    if (!m_layout)
+        return;
+
+    const QTextBlock &previous = block.previous();
+    if (!previous.isValid())
+        return;
+
+    if ((BaseTextDocumentLayout::isFolded(previous)
+            && !BaseTextDocumentLayout::canFold(previous))
+            || (!BaseTextDocumentLayout::isFolded(previous)
+                && BaseTextDocumentLayout::canFold(previous)
+                && !block.isVisible())) {
+        BaseTextDocumentLayout::setFolded(previous, !BaseTextDocumentLayout::isFolded(previous));
+    }
+
+    if (BaseTextDocumentLayout::isFolded(previous) && !m_insideFold)
+        m_insideFold = BaseTextDocumentLayout::foldingIndent(block);
+
+    bool toggleVisibility = false;
+    if (m_insideFold) {
+        if (BaseTextDocumentLayout::foldingIndent(block) >= m_insideFold) {
+            if (block.isVisible())
+                toggleVisibility = true;
+        } else {
+            m_insideFold = 0;
+            if (!block.isVisible())
+                toggleVisibility = true;
+        }
+    } else if (!block.isVisible()) {
+        toggleVisibility = true;
+    }
+
+    if (toggleVisibility) {
+        block.setVisible(!block.isVisible());
+        block.setLineCount(block.isVisible() ? qMax(1, block.layout()->lineCount()) : 0);
+        m_requestDocUpdate = true;
+    }
+}
+
+void BaseTextDocumentLayout::FoldValidator::finalize()
+{
+    if (m_requestDocUpdate && m_layout) {
+        m_layout->requestUpdate();
+        m_layout->emitDocumentSizeChanged();
+    }
+}
diff --git a/src/plugins/texteditor/basetextdocumentlayout.h b/src/plugins/texteditor/basetextdocumentlayout.h
index fb115bc3e4d1b4cf27d2e66d940c5be096931e15..6930e5d0a7869844859f3348825e4d26660f3994 100644
--- a/src/plugins/texteditor/basetextdocumentlayout.h
+++ b/src/plugins/texteditor/basetextdocumentlayout.h
@@ -174,6 +174,22 @@ public:
     static bool isFolded(const QTextBlock &block);
     static void setFolded(const QTextBlock &block, bool folded);
 
+    class TEXTEDITOR_EXPORT FoldValidator
+    {
+    public:
+        FoldValidator();
+
+        void setup(BaseTextDocumentLayout *layout);
+        void reset();
+        void process(QTextBlock block);
+        void finalize();
+
+    private:
+        BaseTextDocumentLayout *m_layout;
+        bool m_requestDocUpdate;
+        int m_insideFold;
+    };
+
     static TextBlockUserData *testUserData(const QTextBlock &block) {
         return static_cast<TextBlockUserData*>(block.userData());
     }
diff --git a/src/plugins/texteditor/syntaxhighlighter.cpp b/src/plugins/texteditor/syntaxhighlighter.cpp
index f10b20378606236106f327738baa28d2fde163a1..876433ea7b267b652023c8301bdd4eae370b9b8b 100644
--- a/src/plugins/texteditor/syntaxhighlighter.cpp
+++ b/src/plugins/texteditor/syntaxhighlighter.cpp
@@ -31,6 +31,7 @@
 
 #include "syntaxhighlighter.h"
 #include "basetextdocument.h"
+#include "basetextdocumentlayout.h"
 
 #include <qtextdocument.h>
 #include <qtextlayout.h>
@@ -76,10 +77,12 @@ public:
     }
 
     void applyFormatChanges(int from, int charsRemoved, int charsAdded);
+
     QVector<QTextCharFormat> formatChanges;
     QTextBlock currentBlock;
     bool rehighlightPending;
     bool inReformatBlocks;
+    BaseTextDocumentLayout::FoldValidator foldValidator;
 };
 
 static bool adjustRange(QTextLayout::FormatRange &range, int from, int charsRemoved, int charsAdded) {
@@ -180,6 +183,8 @@ void SyntaxHighlighterPrivate::_q_reformatBlocks(int from, int charsRemoved, int
 
 void SyntaxHighlighterPrivate::reformatBlocks(int from, int charsRemoved, int charsAdded)
 {
+    foldValidator.reset();
+
     rehighlightPending = false;
 
     QTextBlock block = doc->findBlock(from);
@@ -206,6 +211,8 @@ void SyntaxHighlighterPrivate::reformatBlocks(int from, int charsRemoved, int ch
     }
 
     formatChanges.clear();
+
+    foldValidator.finalize();
 }
 
 void SyntaxHighlighterPrivate::reformatBlock(const QTextBlock &block, int from, int charsRemoved, int charsAdded)
@@ -220,6 +227,8 @@ void SyntaxHighlighterPrivate::reformatBlock(const QTextBlock &block, int from,
     q->highlightBlock(block.text());
     applyFormatChanges(from, charsRemoved, charsAdded);
 
+    foldValidator.process(currentBlock);
+
     currentBlock = QTextBlock();
 }
 
@@ -375,6 +384,7 @@ void SyntaxHighlighter::setDocument(QTextDocument *doc)
                 this, SLOT(_q_reformatBlocks(int,int,int)));
         d->rehighlightPending = true;
         QTimer::singleShot(0, this, SLOT(_q_delayedRehighlight()));
+        d->foldValidator.setup(qobject_cast<BaseTextDocumentLayout *>(doc->documentLayout()));
     }
 }