diff --git a/src/plugins/cppeditor/cppautocompleter.cpp b/src/plugins/cppeditor/cppautocompleter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9f1088ada6b826633ad87ece9c31ebef170d4c53
--- /dev/null
+++ b/src/plugins/cppeditor/cppautocompleter.cpp
@@ -0,0 +1,138 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 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 "cppautocompleter.h"
+
+#include <Token.h>
+
+#include <cplusplus/SimpleLexer.h>
+#include <cplusplus/MatchingText.h>
+#include <cplusplus/BackwardsScanner.h>
+
+#include <QtCore/QLatin1Char>
+#include <QtGui/QTextCursor>
+
+using namespace CppEditor;
+using namespace Internal;
+using namespace CPlusPlus;
+
+CppAutoCompleter::CppAutoCompleter()
+{}
+
+CppAutoCompleter::~CppAutoCompleter()
+{}
+
+bool CppAutoCompleter::doContextAllowsAutoParentheses(const QTextCursor &cursor,
+                                                      const QString &textToInsert) const
+{
+    QChar ch;
+
+    if (! textToInsert.isEmpty())
+        ch = textToInsert.at(0);
+
+    if (! (MatchingText::shouldInsertMatchingText(cursor)
+           || ch == QLatin1Char('\'')
+           || ch == QLatin1Char('"')))
+        return false;
+    else if (isInComment(cursor))
+        return false;
+
+    return true;
+}
+
+bool CppAutoCompleter::doContextAllowsElectricCharacters(const QTextCursor &cursor) const
+{
+    const Token tk = SimpleLexer::tokenAt(cursor.block().text(), cursor.positionInBlock(),
+                                          BackwardsScanner::previousBlockState(cursor.block()));
+
+    // XXX Duplicated from CPPEditor::isInComment to avoid tokenizing twice
+    if (tk.isComment()) {
+        const unsigned pos = cursor.selectionEnd() - cursor.block().position();
+
+        if (pos == tk.end()) {
+            if (tk.is(T_CPP_COMMENT) || tk.is(T_CPP_DOXY_COMMENT))
+                return false;
+
+            const int state = cursor.block().userState() & 0xFF;
+            if (state > 0)
+                return false;
+        }
+
+        if (pos < tk.end())
+            return false;
+    }
+    else if (tk.is(T_STRING_LITERAL) || tk.is(T_WIDE_STRING_LITERAL)
+        || tk.is(T_CHAR_LITERAL) || tk.is(T_WIDE_CHAR_LITERAL)) {
+
+        const unsigned pos = cursor.selectionEnd() - cursor.block().position();
+        if (pos <= tk.end())
+            return false;
+    }
+
+    return true;
+}
+
+bool CppAutoCompleter::doIsInComment(const QTextCursor &cursor) const
+{
+    const Token tk = SimpleLexer::tokenAt(cursor.block().text(), cursor.positionInBlock(),
+                                          BackwardsScanner::previousBlockState(cursor.block()));
+
+    if (tk.isComment()) {
+        const unsigned pos = cursor.selectionEnd() - cursor.block().position();
+
+        if (pos == tk.end()) {
+            if (tk.is(T_CPP_COMMENT) || tk.is(T_CPP_DOXY_COMMENT))
+                return true;
+
+            const int state = cursor.block().userState() & 0xFF;
+            if (state > 0)
+                return true;
+        }
+
+        if (pos < tk.end())
+            return true;
+    }
+
+    return false;
+}
+
+QString CppAutoCompleter::doInsertMatchingBrace(const QTextCursor &cursor,
+                                                const QString &text,
+                                                QChar la,
+                                                int *skippedChars) const
+{
+    MatchingText m;
+    return m.insertMatchingBrace(cursor, text, la, skippedChars);
+}
+
+QString CppAutoCompleter::doInsertParagraphSeparator(const QTextCursor &cursor) const
+{
+    MatchingText m;
+    return m.insertParagraphSeparator(cursor);
+}
diff --git a/src/plugins/cppeditor/cppautocompleter.h b/src/plugins/cppeditor/cppautocompleter.h
new file mode 100644
index 0000000000000000000000000000000000000000..0a80679a9c5e9c160db6b967edd41d1d29db1412
--- /dev/null
+++ b/src/plugins/cppeditor/cppautocompleter.h
@@ -0,0 +1,59 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 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 CPPAUTOCOMPLETER_H
+#define CPPAUTOCOMPLETER_H
+
+#include <texteditor/autocompleter.h>
+
+namespace CppEditor {
+namespace Internal {
+
+class CppAutoCompleter : public TextEditor::AutoCompleter
+{
+public:
+    CppAutoCompleter();
+    virtual ~CppAutoCompleter();
+
+private:
+    virtual bool doContextAllowsAutoParentheses(const QTextCursor &cursor,
+                                                const QString &textToInsert = QString()) const;
+    virtual bool doContextAllowsElectricCharacters(const QTextCursor &cursor) const;
+    virtual bool doIsInComment(const QTextCursor &cursor) const;
+    virtual QString doInsertMatchingBrace(const QTextCursor &cursor,
+                                          const QString &text,
+                                          QChar la,
+                                          int *skippedChars) const;
+    virtual QString doInsertParagraphSeparator(const QTextCursor &cursor) const;
+};
+
+} // Internal
+} // CppEditor
+
+#endif // CPPAUTOCOMPLETER_H
diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp
index 74798b8b40a4aa7ad44ca75e2459af29f513d138..ab3bc7b23a7716b6ee4b8c11d24b43bc39fd8c8c 100644
--- a/src/plugins/cppeditor/cppeditor.cpp
+++ b/src/plugins/cppeditor/cppeditor.cpp
@@ -36,6 +36,7 @@
 #include "cpplocalsymbols.h"
 #include "cppquickfixcollector.h"
 #include "cppqtstyleindenter.h"
+#include "cppautocompleter.h"
 
 #include <AST.h>
 #include <Control.h>
@@ -416,6 +417,7 @@ CPPEditor::CPPEditor(QWidget *parent)
     setCodeFoldingSupported(true);
     setCodeFoldingVisible(true);
     setIndenter(new CppQtStyleIndenter);
+    setAutoCompleter(new CppAutoCompleter);
     baseTextDocument()->setSyntaxHighlighter(new CppHighlighter);
 
     m_modelManager = CppTools::CppModelManagerInterface::instance();
@@ -1407,90 +1409,6 @@ QModelIndex CPPEditor::outlineModelIndex()
     return m_outlineModelIndex;
 }
 
-QString CPPEditor::insertMatchingBrace(const QTextCursor &tc, const QString &text,
-                                       QChar la, int *skippedChars) const
-{
-    MatchingText m;
-    return m.insertMatchingBrace(tc, text, la, skippedChars);
-}
-
-QString CPPEditor::insertParagraphSeparator(const QTextCursor &tc) const
-{
-    MatchingText m;
-    return m.insertParagraphSeparator(tc);
-}
-
-
-bool CPPEditor::contextAllowsAutoParentheses(const QTextCursor &cursor,
-                                             const QString &textToInsert) const
-{
-    QChar ch;
-
-    if (! textToInsert.isEmpty())
-        ch = textToInsert.at(0);
-
-    if (! (MatchingText::shouldInsertMatchingText(cursor) || ch == QLatin1Char('\'') || ch == QLatin1Char('"')))
-        return false;
-    else if (isInComment(cursor))
-        return false;
-
-    return true;
-}
-
-bool CPPEditor::contextAllowsElectricCharacters(const QTextCursor &cursor) const
-{
-    const Token tk = SimpleLexer::tokenAt(cursor.block().text(), cursor.positionInBlock(), BackwardsScanner::previousBlockState(cursor.block()));
-
-    // XXX Duplicated from CPPEditor::isInComment to avoid tokenizing twice
-    if (tk.isComment()) {
-        const unsigned pos = cursor.selectionEnd() - cursor.block().position();
-
-        if (pos == tk.end()) {
-            if (tk.is(T_CPP_COMMENT) || tk.is(T_CPP_DOXY_COMMENT))
-                return false;
-
-            const int state = cursor.block().userState() & 0xFF;
-            if (state > 0)
-                return false;
-        }
-
-        if (pos < tk.end())
-            return false;
-    }
-    else if (tk.is(T_STRING_LITERAL) || tk.is(T_WIDE_STRING_LITERAL)
-        || tk.is(T_CHAR_LITERAL) || tk.is(T_WIDE_CHAR_LITERAL)) {
-
-        const unsigned pos = cursor.selectionEnd() - cursor.block().position();
-        if (pos <= tk.end())
-            return false;
-    }
-
-    return true;
-}
-
-bool CPPEditor::isInComment(const QTextCursor &cursor) const
-{
-    const Token tk = SimpleLexer::tokenAt(cursor.block().text(), cursor.positionInBlock(), BackwardsScanner::previousBlockState(cursor.block()));
-
-    if (tk.isComment()) {
-        const unsigned pos = cursor.selectionEnd() - cursor.block().position();
-
-        if (pos == tk.end()) {
-            if (tk.is(T_CPP_COMMENT) || tk.is(T_CPP_DOXY_COMMENT))
-                return true;
-
-            const int state = cursor.block().userState() & 0xFF;
-            if (state > 0)
-                return true;
-        }
-
-        if (pos < tk.end())
-            return true;
-    }
-
-    return false;
-}
-
 bool CPPEditor::event(QEvent *e)
 {
     switch (e->type()) {
diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h
index 0989ee6c4155901a7f11b1c591b6d04bc96e2d83..332fc1f0dcee728feda2523fd38343e67b36ed5f 100644
--- a/src/plugins/cppeditor/cppeditor.h
+++ b/src/plugins/cppeditor/cppeditor.h
@@ -207,17 +207,6 @@ protected:
 
     TextEditor::BaseTextEditorEditable *createEditableInterface();
 
-    virtual QString insertMatchingBrace(const QTextCursor &tc, const QString &text,
-                                        QChar la, int *skippedChars) const;
-
-    virtual QString insertParagraphSeparator(const QTextCursor &tc) const;
-
-    virtual bool contextAllowsAutoParentheses(const QTextCursor &cursor,
-                                              const QString &textToInsert = QString()) const;
-    virtual bool contextAllowsElectricCharacters(const QTextCursor &cursor) const;
-
-    virtual bool isInComment(const QTextCursor &cursor) const;
-
     const CPlusPlus::Macro *findCanonicalMacro(const QTextCursor &cursor,
                                                CPlusPlus::Document::Ptr doc) const;
 
diff --git a/src/plugins/cppeditor/cppeditor.pro b/src/plugins/cppeditor/cppeditor.pro
index 0883e69ed25bdef21463220c2cfdf8815d8d8d98..4ade5624bb6f95bd140b96ada0dfb4a42b6aa7ae 100644
--- a/src/plugins/cppeditor/cppeditor.pro
+++ b/src/plugins/cppeditor/cppeditor.pro
@@ -23,7 +23,8 @@ HEADERS += cppplugin.h \
     cpptypehierarchy.h \
     cppelementevaluator.h \
     cppquickfixcollector.h \
-    cppqtstyleindenter.h
+    cppqtstyleindenter.h \
+    cppautocompleter.h
 SOURCES += cppplugin.cpp \
     cppeditor.cpp \
     cpphighlighter.cpp \
@@ -40,6 +41,7 @@ SOURCES += cppplugin.cpp \
     cpptypehierarchy.cpp \
     cppelementevaluator.cpp \
     cppquickfixcollector.cpp \
-    cppqtstyleindenter.cpp
+    cppqtstyleindenter.cpp \
+    cppautocompleter.cpp
 RESOURCES += cppeditor.qrc
 OTHER_FILES += CppEditor.mimetypes.xml
diff --git a/src/plugins/qmljseditor/qmljsautocompleter.cpp b/src/plugins/qmljseditor/qmljsautocompleter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fd9d686d9a7a7ac21c895510343ba864feec0a24
--- /dev/null
+++ b/src/plugins/qmljseditor/qmljsautocompleter.cpp
@@ -0,0 +1,279 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 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 "qmljsautocompleter.h"
+
+#include <qmljs/qmljsscanner.h>
+
+#include <QtCore/QChar>
+#include <QtCore/QLatin1Char>
+#include <QtGui/QTextDocument>
+#include <QtGui/QTextCursor>
+#include <QtGui/QTextBlock>
+
+using namespace QmlJSEditor;
+using namespace Internal;
+using namespace QmlJS;
+
+static int blockStartState(const QTextBlock &block)
+{
+    int state = block.userState();
+
+    if (state == -1)
+        return 0;
+    else
+        return state & 0xff;
+}
+
+static Token tokenUnderCursor(const QTextCursor &cursor)
+{
+    const QString blockText = cursor.block().text();
+    const int blockState = blockStartState(cursor.block());
+
+    Scanner tokenize;
+    const QList<Token> tokens = tokenize(blockText, blockState);
+    const int pos = cursor.positionInBlock();
+
+    int tokenIndex = 0;
+    for (; tokenIndex < tokens.size(); ++tokenIndex) {
+        const Token &token = tokens.at(tokenIndex);
+
+        if (token.is(Token::Comment) || token.is(Token::String)) {
+            if (pos > token.begin() && pos <= token.end())
+                break;
+        } else {
+            if (pos >= token.begin() && pos < token.end())
+                break;
+        }
+    }
+
+    if (tokenIndex != tokens.size())
+        return tokens.at(tokenIndex);
+
+    return Token();
+}
+
+static bool shouldInsertMatchingText(QChar lookAhead)
+{
+    switch (lookAhead.unicode()) {
+    case '{': case '}':
+    case ']': case ')':
+    case ';': case ',':
+    case '"': case '\'':
+        return true;
+
+    default:
+        if (lookAhead.isSpace())
+            return true;
+
+        return false;
+    } // switch
+}
+
+static bool shouldInsertMatchingText(const QTextCursor &tc)
+{
+    QTextDocument *doc = tc.document();
+    return shouldInsertMatchingText(doc->characterAt(tc.selectionEnd()));
+}
+
+static bool shouldInsertNewline(const QTextCursor &tc)
+{
+    QTextDocument *doc = tc.document();
+    int pos = tc.selectionEnd();
+
+    // count the number of empty lines.
+    int newlines = 0;
+    for (int e = doc->characterCount(); pos != e; ++pos) {
+        const QChar ch = doc->characterAt(pos);
+
+        if (! ch.isSpace())
+            break;
+        else if (ch == QChar::ParagraphSeparator)
+            ++newlines;
+    }
+
+    if (newlines <= 1 && doc->characterAt(pos) != QLatin1Char('}'))
+        return true;
+
+    return false;
+}
+
+static bool isCompleteStringLiteral(const QStringRef &text)
+{
+    if (text.length() < 2)
+        return false;
+
+    const QChar quote = text.at(0);
+
+    if (text.at(text.length() - 1) == quote)
+        return text.at(text.length() - 2) != QLatin1Char('\\'); // ### not exactly.
+
+    return false;
+}
+
+AutoCompleter::AutoCompleter()
+{}
+
+AutoCompleter::~AutoCompleter()
+{}
+
+bool AutoCompleter::doContextAllowsAutoParentheses(const QTextCursor &cursor,
+                                                   const QString &textToInsert) const
+{
+    QChar ch;
+
+    if (! textToInsert.isEmpty())
+        ch = textToInsert.at(0);
+
+    switch (ch.unicode()) {
+    case '\'':
+    case '"':
+
+    case '(':
+    case '[':
+    case '{':
+
+    case ')':
+    case ']':
+    case '}':
+
+    case ';':
+        break;
+
+    default:
+        if (ch.isNull())
+            break;
+
+        return false;
+    } // end of switch
+
+    const Token token = tokenUnderCursor(cursor);
+    switch (token.kind) {
+    case Token::Comment:
+        return false;
+
+    case Token::String: {
+        const QString blockText = cursor.block().text();
+        const QStringRef tokenText = blockText.midRef(token.offset, token.length);
+        const QChar quote = tokenText.at(0);
+
+        if (ch != quote || isCompleteStringLiteral(tokenText))
+            break;
+
+        return false;
+    }
+
+    default:
+        break;
+    } // end of switch
+
+    return true;
+}
+
+bool AutoCompleter::doContextAllowsElectricCharacters(const QTextCursor &cursor) const
+{
+    Token token = tokenUnderCursor(cursor);
+    switch (token.kind) {
+    case Token::Comment:
+    case Token::String:
+        return false;
+    default:
+        return true;
+    }
+}
+
+bool AutoCompleter::doIsInComment(const QTextCursor &cursor) const
+{
+    return tokenUnderCursor(cursor).is(Token::Comment);
+}
+
+QString AutoCompleter::doInsertMatchingBrace(const QTextCursor &cursor,
+                                             const QString &text,
+                                             QChar,
+                                             int *skippedChars) const
+{
+    if (text.length() != 1)
+        return QString();
+
+    if (! shouldInsertMatchingText(cursor))
+        return QString();
+
+    const QChar la = cursor.document()->characterAt(cursor.position());
+
+    const QChar ch = text.at(0);
+    switch (ch.unicode()) {
+    case '\'':
+        if (la != ch)
+            return QString(ch);
+        ++*skippedChars;
+        break;
+
+    case '"':
+        if (la != ch)
+            return QString(ch);
+        ++*skippedChars;
+        break;
+
+    case '(':
+        return QString(QLatin1Char(')'));
+
+    case '[':
+        return QString(QLatin1Char(']'));
+
+    case '{':
+        return QString(); // nothing to do.
+
+    case ')':
+    case ']':
+    case '}':
+    case ';':
+        if (la == ch)
+            ++*skippedChars;
+        break;
+
+    default:
+        break;
+    } // end of switch
+
+    return QString();
+}
+
+QString AutoCompleter::doInsertParagraphSeparator(const QTextCursor &cursor) const
+{
+    if (shouldInsertNewline(cursor)) {
+        QTextCursor cursor = cursor;
+        cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
+        if (! cursor.selectedText().trimmed().isEmpty())
+            return QString();
+
+        return QLatin1String("}\n");
+    }
+
+    return QLatin1String("}");
+}
diff --git a/src/plugins/qmljseditor/qmljsautocompleter.h b/src/plugins/qmljseditor/qmljsautocompleter.h
new file mode 100644
index 0000000000000000000000000000000000000000..7e6b2bab03f017f24dd2f49bb37b5a28464beee9
--- /dev/null
+++ b/src/plugins/qmljseditor/qmljsautocompleter.h
@@ -0,0 +1,59 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 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 QMLJSAUTOCOMPLETER_H
+#define QMLJSAUTOCOMPLETER_H
+
+#include <texteditor/autocompleter.h>
+
+namespace QmlJSEditor {
+namespace Internal {
+
+class AutoCompleter : public TextEditor::AutoCompleter
+{
+public:
+    AutoCompleter();
+    virtual ~AutoCompleter();
+
+private:
+    virtual bool doContextAllowsAutoParentheses(const QTextCursor &cursor,
+                                                const QString &textToInsert = QString()) const;
+    virtual bool doContextAllowsElectricCharacters(const QTextCursor &cursor) const;
+    virtual bool doIsInComment(const QTextCursor &cursor) const;
+    virtual QString doInsertMatchingBrace(const QTextCursor &tc,
+                                          const QString &text,
+                                          QChar la,
+                                          int *skippedChars) const;
+    virtual QString doInsertParagraphSeparator(const QTextCursor &tc) const;
+};
+
+} // Internal
+} // QmlJSEditor
+
+#endif // QMLJSAUTOCOMPLETER_H
diff --git a/src/plugins/qmljseditor/qmljseditor.cpp b/src/plugins/qmljseditor/qmljseditor.cpp
index f40858c3edc31182499f8bcc7f0684d9838e350c..c9a3afc3a58f637e0ed731ad56c3a4e33ad4377e 100644
--- a/src/plugins/qmljseditor/qmljseditor.cpp
+++ b/src/plugins/qmljseditor/qmljseditor.cpp
@@ -39,6 +39,7 @@
 #include "qmljsfindreferences.h"
 #include "qmljssemantichighlighter.h"
 #include "qmljsindenter.h"
+#include "qmljsautocompleter.h"
 
 #include <qmljs/qmljsbind.h>
 #include <qmljs/qmljsdocument.h>
@@ -91,39 +92,6 @@ using namespace QmlJS::AST;
 using namespace QmlJSEditor;
 using namespace QmlJSEditor::Internal;
 
-static int blockStartState(const QTextBlock &block)
-{
-    int state = block.userState();
-
-    if (state == -1)
-        return 0;
-    else
-        return state & 0xff;
-}
-
-static bool shouldInsertMatchingText(QChar lookAhead)
-{
-    switch (lookAhead.unicode()) {
-    case '{': case '}':
-    case ']': case ')':
-    case ';': case ',':
-    case '"': case '\'':
-        return true;
-
-    default:
-        if (lookAhead.isSpace())
-            return true;
-
-        return false;
-    } // switch
-}
-
-static bool shouldInsertMatchingText(const QTextCursor &tc)
-{
-    QTextDocument *doc = tc.document();
-    return shouldInsertMatchingText(doc->characterAt(tc.selectionEnd()));
-}
-
 namespace {
 
 class FindIdDeclarations: protected Visitor
@@ -647,6 +615,7 @@ QmlJSTextEditor::QmlJSTextEditor(QWidget *parent) :
     setCodeFoldingSupported(true);
     setCodeFoldingVisible(true);
     setIndenter(new Indenter);
+    setAutoCompleter(new AutoCompleter);
 
     m_updateDocumentTimer = new QTimer(this);
     m_updateDocumentTimer->setInterval(UPDATE_DOCUMENT_DEFAULT_INTERVAL);
@@ -1504,200 +1473,6 @@ void QmlJSTextEditor::unCommentSelection()
     Utils::unCommentSelection(this);
 }
 
-static bool isCompleteStringLiteral(const QStringRef &text)
-{
-    if (text.length() < 2)
-        return false;
-
-    const QChar quote = text.at(0);
-
-    if (text.at(text.length() - 1) == quote)
-        return text.at(text.length() - 2) != QLatin1Char('\\'); // ### not exactly.
-
-    return false;
-}
-
-static Token tokenUnderCursor(const QTextCursor &cursor)
-{
-    const QString blockText = cursor.block().text();
-    const int blockState = blockStartState(cursor.block());
-
-    Scanner tokenize;
-    const QList<Token> tokens = tokenize(blockText, blockState);
-    const int pos = cursor.positionInBlock();
-
-    int tokenIndex = 0;
-    for (; tokenIndex < tokens.size(); ++tokenIndex) {
-        const Token &token = tokens.at(tokenIndex);
-
-        if (token.is(Token::Comment) || token.is(Token::String)) {
-            if (pos > token.begin() && pos <= token.end())
-                break;
-        } else {
-            if (pos >= token.begin() && pos < token.end())
-                break;
-        }
-    }
-
-    if (tokenIndex != tokens.size())
-        return tokens.at(tokenIndex);
-
-    return Token();
-}
-
-bool QmlJSTextEditor::contextAllowsAutoParentheses(const QTextCursor &cursor, const QString &textToInsert) const
-{
-    QChar ch;
-
-    if (! textToInsert.isEmpty())
-        ch = textToInsert.at(0);
-
-    switch (ch.unicode()) {
-    case '\'':
-    case '"':
-
-    case '(':
-    case '[':
-    case '{':
-
-    case ')':
-    case ']':
-    case '}':
-
-    case ';':
-        break;
-
-    default:
-        if (ch.isNull())
-            break;
-
-        return false;
-    } // end of switch
-
-    const Token token = tokenUnderCursor(cursor);
-    switch (token.kind) {
-    case Token::Comment:
-        return false;
-
-    case Token::String: {
-        const QString blockText = cursor.block().text();
-        const QStringRef tokenText = blockText.midRef(token.offset, token.length);
-        const QChar quote = tokenText.at(0);
-
-        if (ch != quote || isCompleteStringLiteral(tokenText))
-            break;
-
-        return false;
-    }
-
-    default:
-        break;
-    } // end of switch
-
-    return true;
-}
-
-bool QmlJSTextEditor::contextAllowsElectricCharacters(const QTextCursor &cursor) const
-{
-    Token token = tokenUnderCursor(cursor);
-    switch (token.kind) {
-    case Token::Comment:
-    case Token::String:
-        return false;
-    default:
-        return true;
-    }
-}
-
-bool QmlJSTextEditor::isInComment(const QTextCursor &cursor) const
-{
-    return tokenUnderCursor(cursor).is(Token::Comment);
-}
-
-QString QmlJSTextEditor::insertMatchingBrace(const QTextCursor &tc, const QString &text, QChar, int *skippedChars) const
-{
-    if (text.length() != 1)
-        return QString();
-
-    if (! shouldInsertMatchingText(tc))
-        return QString();
-
-    const QChar la = characterAt(tc.position());
-
-    const QChar ch = text.at(0);
-    switch (ch.unicode()) {
-    case '\'':
-        if (la != ch)
-            return QString(ch);
-        ++*skippedChars;
-        break;
-
-    case '"':
-        if (la != ch)
-            return QString(ch);
-        ++*skippedChars;
-        break;
-
-    case '(':
-        return QString(QLatin1Char(')'));
-
-    case '[':
-        return QString(QLatin1Char(']'));
-
-    case '{':
-        return QString(); // nothing to do.
-
-    case ')':
-    case ']':
-    case '}':
-    case ';':
-        if (la == ch)
-            ++*skippedChars;
-        break;
-
-    default:
-        break;
-    } // end of switch
-
-    return QString();
-}
-
-static bool shouldInsertNewline(const QTextCursor &tc)
-{
-    QTextDocument *doc = tc.document();
-    int pos = tc.selectionEnd();
-
-    // count the number of empty lines.
-    int newlines = 0;
-    for (int e = doc->characterCount(); pos != e; ++pos) {
-        const QChar ch = doc->characterAt(pos);
-
-        if (! ch.isSpace())
-            break;
-        else if (ch == QChar::ParagraphSeparator)
-            ++newlines;
-    }
-
-    if (newlines <= 1 && doc->characterAt(pos) != QLatin1Char('}'))
-        return true;
-
-    return false;
-}
-
-QString QmlJSTextEditor::insertParagraphSeparator(const QTextCursor &tc) const
-{
-    if (shouldInsertNewline(tc)) {
-        QTextCursor cursor = tc;
-        cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
-        if (! cursor.selectedText().trimmed().isEmpty())
-            return QString();
-
-        return QLatin1String("}\n");
-    }
-
-    return QLatin1String("}");
-}
-
 void QmlJSTextEditor::forceSemanticRehighlight()
 {
     m_semanticHighlighter->rehighlight(currentSource(/* force = */ true));
diff --git a/src/plugins/qmljseditor/qmljseditor.h b/src/plugins/qmljseditor/qmljseditor.h
index ec7151a56aa05f1b7e01a98256763dc54bf9aa19..6392036444fe08f64c14f0f2c09f80dbc61f84e4 100644
--- a/src/plugins/qmljseditor/qmljseditor.h
+++ b/src/plugins/qmljseditor/qmljseditor.h
@@ -202,13 +202,6 @@ protected:
     void createToolBar(Internal::QmlJSEditorEditable *editable);
     TextEditor::BaseTextEditor::Link findLinkAt(const QTextCursor &cursor, bool resolveTarget = true);
 
-    //// brace matching
-    virtual bool contextAllowsAutoParentheses(const QTextCursor &cursor, const QString &textToInsert = QString()) const;
-    virtual bool contextAllowsElectricCharacters(const QTextCursor &cursor) const;
-    virtual bool isInComment(const QTextCursor &cursor) const;
-    virtual QString insertMatchingBrace(const QTextCursor &tc, const QString &text, QChar la, int *skippedChars) const;
-    virtual QString insertParagraphSeparator(const QTextCursor &tc) const;
-
 private:
     bool isClosingBrace(const QList<QmlJS::Token> &tokens) const;
 
diff --git a/src/plugins/qmljseditor/qmljseditor.pro b/src/plugins/qmljseditor/qmljseditor.pro
index 7093b3ec0eb0b6c2fdf1b7c9b446c7dd7a13d341..1d66b2f958c8f4eb109f46f301f376c02eafabfd 100644
--- a/src/plugins/qmljseditor/qmljseditor.pro
+++ b/src/plugins/qmljseditor/qmljseditor.pro
@@ -35,7 +35,8 @@ HEADERS += \
     qmljsfindreferences.h \
     qmljseditoreditable.h \
     qmljssemantichighlighter.h \
-    qmljsindenter.h
+    qmljsindenter.h \
+    qmljsautocompleter.h
 
 SOURCES += \
     qmljscodecompletion.cpp \
@@ -64,7 +65,8 @@ SOURCES += \
     qmljsfindreferences.cpp \
     qmljseditoreditable.cpp \
     qmljssemantichighlighter.cpp \
-    qmljsindenter.cpp
+    qmljsindenter.cpp \
+    qmljsautocompleter.cpp
 
 RESOURCES += qmljseditor.qrc
 OTHER_FILES += QmlJSEditor.mimetypes.xml
diff --git a/src/plugins/texteditor/autocompleter.cpp b/src/plugins/texteditor/autocompleter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..92ce3161a4081bb30796e1ab7347a5c3aba03c3e
--- /dev/null
+++ b/src/plugins/texteditor/autocompleter.cpp
@@ -0,0 +1,106 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 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 "autocompleter.h"
+
+#include <QtGui/QTextCursor>
+
+using namespace TextEditor;
+
+AutoCompleter::AutoCompleter()
+{}
+
+AutoCompleter::~AutoCompleter()
+{}
+
+bool AutoCompleter::contextAllowsAutoParentheses(const QTextCursor &cursor,
+                                                 const QString &textToInsert) const
+{
+    return doContextAllowsAutoParentheses(cursor, textToInsert);
+}
+
+bool AutoCompleter::contextAllowsElectricCharacters(const QTextCursor &cursor) const
+{
+    return doContextAllowsElectricCharacters(cursor);
+}
+
+bool AutoCompleter::isInComment(const QTextCursor &cursor) const
+{
+    return doIsInComment(cursor);
+}
+
+QString AutoCompleter::insertMatchingBrace(const QTextCursor &cursor, const
+                                           QString &text,
+                                           QChar la,
+                                           int *skippedChars) const
+{
+    return doInsertMatchingBrace(cursor, text, la, skippedChars);
+}
+
+QString AutoCompleter::insertParagraphSeparator(const QTextCursor &cursor) const
+{
+    return doInsertParagraphSeparator(cursor);
+}
+
+bool AutoCompleter::doContextAllowsAutoParentheses(const QTextCursor &cursor,
+                                                   const QString &textToInsert) const
+{
+    Q_UNUSED(cursor);
+    Q_UNUSED(textToInsert);
+    return false;
+}
+
+bool AutoCompleter::doContextAllowsElectricCharacters(const QTextCursor &cursor) const
+{
+    return doContextAllowsAutoParentheses(cursor);
+}
+
+bool AutoCompleter::doIsInComment(const QTextCursor &cursor) const
+{
+    Q_UNUSED(cursor);
+    return false;
+}
+
+QString AutoCompleter::doInsertMatchingBrace(const QTextCursor &cursor,
+                                             const QString &text,
+                                             QChar la,
+                                             int *skippedChars) const
+{
+    Q_UNUSED(cursor);
+    Q_UNUSED(text);
+    Q_UNUSED(la);
+    Q_UNUSED(skippedChars);
+    return QString();
+}
+
+QString AutoCompleter::doInsertParagraphSeparator(const QTextCursor &cursor) const
+{
+    Q_UNUSED(cursor);
+    return QString();
+}
diff --git a/src/plugins/texteditor/autocompleter.h b/src/plugins/texteditor/autocompleter.h
new file mode 100644
index 0000000000000000000000000000000000000000..3b49d499a4e8b420be8246499755fa514d5277fc
--- /dev/null
+++ b/src/plugins/texteditor/autocompleter.h
@@ -0,0 +1,78 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 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 AUTOCOMPLETER_H
+#define AUTOCOMPLETER_H
+
+#include "texteditor_global.h"
+
+#include <QtCore/QChar>
+#include <QtCore/QString>
+
+QT_BEGIN_NAMESPACE
+class QTextCursor;
+QT_END_NAMESPACE
+
+namespace TextEditor {
+
+class TEXTEDITOR_EXPORT AutoCompleter
+{
+public:
+    AutoCompleter();
+    virtual ~AutoCompleter();
+
+    bool contextAllowsAutoParentheses(const QTextCursor &cursor,
+                                      const QString &textToInsert = QString()) const;
+    bool contextAllowsElectricCharacters(const QTextCursor &cursor) const;
+
+    // Returns true if the cursor is inside a comment.
+    bool isInComment(const QTextCursor &cursor) const;
+
+    QString insertMatchingBrace(const QTextCursor &cursor, const
+                                QString &text,
+                                QChar la,
+                                int *skippedChars) const;
+    // Returns the text that needs to be inserted
+    QString insertParagraphSeparator(const QTextCursor &cursor) const;
+
+private:
+    virtual bool doContextAllowsAutoParentheses(const QTextCursor &cursor,
+                                                const QString &textToInsert = QString()) const;
+    virtual bool doContextAllowsElectricCharacters(const QTextCursor &cursor) const;
+    virtual bool doIsInComment(const QTextCursor &cursor) const;
+    virtual QString doInsertMatchingBrace(const QTextCursor &cursor,
+                                          const QString &text,
+                                          QChar la,
+                                          int *skippedChars) const;
+    virtual QString doInsertParagraphSeparator(const QTextCursor &cursor) const;
+};
+
+} // TextEditor
+
+#endif // AUTOCOMPLETER_H
diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp
index 7457634afdf4881f104261c0b2455a3a91112474..f2fe088e6c5f37d5d48eef0c4464fe751049120a 100644
--- a/src/plugins/texteditor/basetexteditor.cpp
+++ b/src/plugins/texteditor/basetexteditor.cpp
@@ -43,6 +43,7 @@
 #include "tooltip.h"
 #include "tipcontents.h"
 #include "indenter.h"
+#include "autocompleter.h"
 
 #include <aggregation/aggregate.h>
 #include <coreplugin/actionmanager/actionmanager.h>
@@ -1364,7 +1365,7 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e)
             cursor.insertText(autoText);
             cursor.setPosition(pos);
         }
-        if (!electricChar.isNull() && contextAllowsElectricCharacters(cursor))
+        if (!electricChar.isNull() && d->m_autoCompleter->contextAllowsElectricCharacters(cursor))
             indent(document(), cursor, electricChar);
 
         if (doEditBlock)
@@ -1889,6 +1890,16 @@ void BaseTextEditor::setIndenter(Indenter *indenter)
     d->m_indenter.reset(indenter);
 }
 
+void BaseTextEditor::setAutoCompleter(AutoCompleter *autoCompleter)
+{
+    d->m_autoCompleter.reset(autoCompleter);
+}
+
+AutoCompleter *BaseTextEditor::autoCompleter() const
+{
+    return d->m_autoCompleter.data();
+}
+
 //--------- BaseTextEditorPrivate -----------
 
 BaseTextEditorPrivate::BaseTextEditorPrivate()
@@ -1937,7 +1948,8 @@ BaseTextEditorPrivate::BaseTextEditorPrivate()
     m_requestAutoCompletionRevision(0),
     m_requestAutoCompletionPosition(0),
     m_requestAutoCompletionTimer(0),
-    m_cursorBlockNumber(-1)
+    m_cursorBlockNumber(-1),
+    m_autoCompleter(new AutoCompleter)
 {
 }
 
@@ -4051,41 +4063,6 @@ void BaseTextEditor::countBrackets(QTextCursor cursor, int from, int end, QChar
     }
 }
 
-bool BaseTextEditor::contextAllowsAutoParentheses(const QTextCursor &cursor,
-                                                  const QString &textToInsert) const
-{
-    Q_UNUSED(cursor);
-    Q_UNUSED(textToInsert);
-    return false;
-}
-
-bool BaseTextEditor::contextAllowsElectricCharacters(const QTextCursor &cursor) const
-{
-    return contextAllowsAutoParentheses(cursor);
-}
-
-bool BaseTextEditor::isInComment(const QTextCursor &cursor) const
-{
-    Q_UNUSED(cursor);
-    return false;
-}
-
-QString BaseTextEditor::insertMatchingBrace(const QTextCursor &tc, const QString &text,
-                                            QChar la, int *skippedChars) const
-{
-    Q_UNUSED(tc);
-    Q_UNUSED(text);
-    Q_UNUSED(la);
-    Q_UNUSED(skippedChars);
-    return QString();
-}
-
-QString BaseTextEditor::insertParagraphSeparator(const QTextCursor &tc) const
-{
-    Q_UNUSED(tc);
-    return QString();
-}
-
 QString BaseTextEditor::autoComplete(QTextCursor &cursor, const QString &textToInsert) const
 {
     const bool checkBlockEnd = d->m_allowSkippingOfBlockEnd;
@@ -4094,7 +4071,7 @@ QString BaseTextEditor::autoComplete(QTextCursor &cursor, const QString &textToI
     if (!d->m_autoParenthesesEnabled)
         return QString();
 
-    if (!contextAllowsAutoParentheses(cursor, textToInsert))
+    if (!d->m_autoCompleter->contextAllowsAutoParentheses(cursor, textToInsert))
         return QString();
 
     const QString text = textToInsert;
@@ -4128,7 +4105,7 @@ QString BaseTextEditor::autoComplete(QTextCursor &cursor, const QString &textToI
     }
 
     int skippedChars = 0;
-    const QString autoText = insertMatchingBrace(cursor, text, lookAhead, &skippedChars);
+    const QString autoText = d->m_autoCompleter->insertMatchingBrace(cursor, text, lookAhead, &skippedChars);
 
     if (checkBlockEnd && textToInsert.at(0) == QLatin1Char('}')) {
         if (textToInsert.length() > 1)
@@ -4200,7 +4177,7 @@ bool BaseTextEditor::autoBackspace(QTextCursor &cursor)
             && lookFurtherBehind != QLatin1Char('\\'))
         || (lookBehind == QLatin1Char('\'') && lookAhead == QLatin1Char('\'')
             && lookFurtherBehind != QLatin1Char('\\'))) {
-        if (! isInComment(c)) {
+        if (! d->m_autoCompleter->isInComment(c)) {
             cursor.beginEditBlock();
             cursor.deleteChar();
             cursor.deletePreviousChar();
@@ -4219,7 +4196,7 @@ int BaseTextEditor::paragraphSeparatorAboutToBeInserted(QTextCursor &cursor)
     if (characterAt(cursor.position() - 1) != QLatin1Char('{'))
         return 0;
 
-    if (!contextAllowsAutoParentheses(cursor))
+    if (!d->m_autoCompleter->contextAllowsAutoParentheses(cursor))
         return 0;
 
     // verify that we indeed do have an extra opening brace in the document
@@ -4253,7 +4230,7 @@ int BaseTextEditor::paragraphSeparatorAboutToBeInserted(QTextCursor &cursor)
 
     int pos = cursor.position();
 
-    const QString textToInsert = insertParagraphSeparator(cursor);
+    const QString textToInsert = d->m_autoCompleter->insertParagraphSeparator(cursor);
 
     cursor.insertText(textToInsert);
     cursor.setPosition(pos);
diff --git a/src/plugins/texteditor/basetexteditor.h b/src/plugins/texteditor/basetexteditor.h
index 77caa0ff1c379a26ae373b3307c5c6cc9762c2dd..ba2c4d1d4c4740e2a457affa388844dadb11a94d 100644
--- a/src/plugins/texteditor/basetexteditor.h
+++ b/src/plugins/texteditor/basetexteditor.h
@@ -69,6 +69,7 @@ class CompletionSettings;
 class DisplaySettings;
 class StorageSettings;
 class Indenter;
+class AutoCompleter;
 
 class TEXTEDITOR_EXPORT BaseTextEditorAnimator : public QObject
 {
@@ -225,6 +226,9 @@ public:
 
     void setIndenter(Indenter *indenter);
 
+    void setAutoCompleter(AutoCompleter *autoCompleter);
+    AutoCompleter *autoCompleter() const;
+
 public slots:
     void setDisplayName(const QString &title);
 
@@ -429,17 +433,6 @@ public:
     // Reindent at cursor. Selection will be adjusted according to the indentation change of the first block
     virtual void reindent(QTextDocument *doc, const QTextCursor &cursor);
 
-    virtual bool contextAllowsAutoParentheses(const QTextCursor &cursor, const QString &textToInsert = QString()) const;
-    virtual bool contextAllowsElectricCharacters(const QTextCursor &cursor) const;
-
-    // Returns true if the cursor is inside a comment.
-    virtual bool isInComment(const QTextCursor &cursor) const;
-
-    virtual QString insertMatchingBrace(const QTextCursor &tc, const QString &text, QChar la, int *skippedChars) const;
-
-    // Returns the text that needs to be inserted
-    virtual QString insertParagraphSeparator(const QTextCursor &tc) const;
-
 protected:
     static void countBracket(QChar open, QChar close, QChar c, int *errors, int *stillopen);
 
diff --git a/src/plugins/texteditor/basetexteditor_p.h b/src/plugins/texteditor/basetexteditor_p.h
index bc6a3365eae1ba9f2787951f85e95e299b736218..876e28a6aecf0485808dfaf049d13115472a3b41 100644
--- a/src/plugins/texteditor/basetexteditor_p.h
+++ b/src/plugins/texteditor/basetexteditor_p.h
@@ -294,6 +294,7 @@ public:
     QPointer<BaseTextEditorAnimator> m_animator;
     int m_cursorBlockNumber;
 
+    QScopedPointer<AutoCompleter> m_autoCompleter;
     QScopedPointer<Indenter> m_indenter;
 };
 
diff --git a/src/plugins/texteditor/texteditor.pro b/src/plugins/texteditor/texteditor.pro
index 3b84f9c979ca9befc1651372f2064d20426b6768..43ba19013a8f3833f11973c36e5be6dff710d2ad 100644
--- a/src/plugins/texteditor/texteditor.pro
+++ b/src/plugins/texteditor/texteditor.pro
@@ -70,7 +70,8 @@ SOURCES += texteditorplugin.cpp \
     tooltip/tipfactory.cpp \
     basehoverhandler.cpp \
     helpitem.cpp \
-    snippetsparser.cpp
+    snippetsparser.cpp \
+    autocompleter.cpp
 
 HEADERS += texteditorplugin.h \
     textfilewizard.h \
@@ -144,7 +145,8 @@ HEADERS += texteditorplugin.h \
     tooltip/tipfactory.h \
     basehoverhandler.h \
     helpitem.h \
-    snippetsparser.h
+    snippetsparser.h \
+    autocompleter.h
 
 FORMS += behaviorsettingspage.ui \
     displaysettingspage.ui \