diff --git a/src/libs/qmljs/qmljshighlighter.cpp b/src/libs/qmljs/qmljshighlighter.cpp
index 81dbf34415c27f7a8da45081e0c7c237fa53d353..81c01d2b3308f9f9f4db98890d1f5c35aaabc7ec 100644
--- a/src/libs/qmljs/qmljshighlighter.cpp
+++ b/src/libs/qmljs/qmljshighlighter.cpp
@@ -50,12 +50,17 @@ QScriptHighlighter::QScriptHighlighter(bool duiEnabled, QTextDocument *parent):
     rc[PreProcessorFormat].setForeground(Qt::darkBlue);
     rc[VisualWhitespace].setForeground(Qt::lightGray); // for debug: rc[VisualWhitespace].setBackground(Qt::red);
     setFormats(rc);
-
-    m_scanner.setKeywords(keywords());
 }
 
 bool QScriptHighlighter::isDuiEnabled() const
-{ return m_duiEnabled; }
+{
+    return m_duiEnabled;
+}
+
+QTextCharFormat QScriptHighlighter::labelTextCharFormat() const
+{
+    return m_formats[LabelFormat];
+}
 
 static bool checkStartOfBinding(const Token &token)
 {
@@ -85,18 +90,6 @@ void QScriptHighlighter::highlightBlock(const QString &text)
                 setFormat(token.offset, token.length, m_formats[KeywordFormat]);
                 break;
 
-            case Token::String:
-                highlightWhitespace(token, text, StringFormat);
-                break;
-
-            case Token::Comment:
-                highlightWhitespace(token, text, CommentFormat);
-                break;
-
-            case Token::Number:
-                highlightWhitespace(token, text, NumberFormat);
-                break;
-
             case Token::LeftParenthesis:
                 onOpeningParenthesis('(', token.offset);
                 break;
@@ -122,6 +115,16 @@ void QScriptHighlighter::highlightBlock(const QString &text)
                 break;
 
             case Token::Identifier: {
+                if (maybeQmlKeyword(text.midRef(token.offset, token.length))) {
+                    // check the previous token
+                    if (index == 0 || tokens.at(index - 1).isNot(Token::Dot)) {
+                        if (index + 1 == tokens.size() || tokens.at(index + 1).isNot(Token::Colon)) {
+                            setFormat(token.offset, token.length, m_formats[KeywordFormat]);
+                            break;
+                        }
+                    }
+                }
+
                 if (index + 1 < tokens.size()) {
                     if (tokens.at(index + 1).is(Token::LeftBrace) && text.at(token.offset).isUpper()) {
                         setFormat(token.offset, token.length, m_formats[TypeFormat]);
@@ -195,8 +198,8 @@ void QScriptHighlighter::highlightBlock(const QString &text)
     if (! tokens.isEmpty())
         firstNonSpace = tokens.first().offset;
 
-    setCurrentBlockState(m_scanner.endState());
-    onBlockEnd(m_scanner.endState(), firstNonSpace);
+    setCurrentBlockState(m_scanner.state());
+    onBlockEnd(m_scanner.state(), firstNonSpace);
 }
 
 void QScriptHighlighter::setFormats(const QVector<QTextCharFormat> &s)
@@ -205,76 +208,6 @@ void QScriptHighlighter::setFormats(const QVector<QTextCharFormat> &s)
     qCopy(s.constBegin(), s.constEnd(), m_formats);
 }
 
-QSet<QString> QScriptHighlighter::keywords()
-{
-    QSet<QString> keywords;
-
-    keywords << QLatin1String("Infinity");
-    keywords << QLatin1String("NaN");
-    keywords << QLatin1String("abstract");
-    keywords << QLatin1String("boolean");
-    keywords << QLatin1String("break");
-    keywords << QLatin1String("byte");
-    keywords << QLatin1String("case");
-    keywords << QLatin1String("catch");
-    keywords << QLatin1String("char");
-    keywords << QLatin1String("class");
-    keywords << QLatin1String("const");
-    keywords << QLatin1String("constructor");
-    keywords << QLatin1String("continue");
-    keywords << QLatin1String("debugger");
-    keywords << QLatin1String("default");
-    keywords << QLatin1String("delete");
-    keywords << QLatin1String("do");
-    keywords << QLatin1String("double");
-    keywords << QLatin1String("else");
-    keywords << QLatin1String("enum");
-    keywords << QLatin1String("export");
-    keywords << QLatin1String("extends");
-    keywords << QLatin1String("false");
-    keywords << QLatin1String("final");
-    keywords << QLatin1String("finally");
-    keywords << QLatin1String("float");
-    keywords << QLatin1String("for");
-    keywords << QLatin1String("function");
-    keywords << QLatin1String("goto");
-    keywords << QLatin1String("if");
-    keywords << QLatin1String("implements");
-    keywords << QLatin1String("import");
-    keywords << QLatin1String("in");
-    keywords << QLatin1String("instanceof");
-    keywords << QLatin1String("int");
-    keywords << QLatin1String("interface");
-    keywords << QLatin1String("long");
-    keywords << QLatin1String("native");
-    keywords << QLatin1String("new");
-    keywords << QLatin1String("package");
-    keywords << QLatin1String("private");
-    keywords << QLatin1String("protected");
-    keywords << QLatin1String("public");
-    keywords << QLatin1String("return");
-    keywords << QLatin1String("short");
-    keywords << QLatin1String("static");
-    keywords << QLatin1String("super");
-    keywords << QLatin1String("switch");
-    keywords << QLatin1String("synchronized");
-    keywords << QLatin1String("this");
-    keywords << QLatin1String("throw");
-    keywords << QLatin1String("throws");
-    keywords << QLatin1String("transient");
-    keywords << QLatin1String("true");
-    keywords << QLatin1String("try");
-    keywords << QLatin1String("typeof");
-    keywords << QLatin1String("undefined");
-    keywords << QLatin1String("var");
-    keywords << QLatin1String("void");
-    keywords << QLatin1String("volatile");
-    keywords << QLatin1String("while");
-    keywords << QLatin1String("with");
-
-    return keywords;
-}
-
 int QScriptHighlighter::onBlockStart()
 {
     return currentBlockState();
@@ -292,22 +225,23 @@ void QScriptHighlighter::onClosingParenthesis(QChar, int)
 {
 }
 
-void QScriptHighlighter::highlightWhitespace(const Token &token, const QString &text, int nonWhitespaceFormat)
+bool QScriptHighlighter::maybeQmlKeyword(const QStringRef &text) const
 {
-    const QTextCharFormat normalFormat = m_formats[nonWhitespaceFormat];
-    const QTextCharFormat visualSpaceFormat = m_formats[VisualWhitespace];
-
-    const int end = token.end();
-    int index = token.offset;
-
-    while (index != end) {
-        const bool isSpace = text.at(index).isSpace();
-        const int start = index;
-
-        do { ++index; }
-        while (index != end && text.at(index).isSpace() == isSpace);
+    if (text.isEmpty())
+        return false;
 
-        const int tokenLength = index - start;
-        setFormat(start, tokenLength, isSpace ? visualSpaceFormat : normalFormat);
+    const QChar ch = text.at(0);
+    if (ch == QLatin1Char('p') && text == QLatin1String("property")) {
+        return true;
+    } else if (ch == QLatin1Char('a') && text == QLatin1String("alias")) {
+        return true;
+    } else if (ch == QLatin1Char('s') && text == QLatin1String("signal")) {
+        return true;
+    } else if (ch == QLatin1Char('p') && text == QLatin1String("property")) {
+        return true;
+    } else if (ch == QLatin1Char('r') && text == QLatin1String("readonly")) {
+        return true;
+    } else {
+        return false;
     }
 }
diff --git a/src/libs/qmljs/qmljshighlighter.h b/src/libs/qmljs/qmljshighlighter.h
index d289d91a5b6d9020d8c8c4fb64822bff29bd7790..e2e3e65ee1c6481c8441f16e97a15e3b45780be3 100644
--- a/src/libs/qmljs/qmljshighlighter.h
+++ b/src/libs/qmljs/qmljshighlighter.h
@@ -55,10 +55,7 @@ public:
     // MS VC 6 compatible, still.
     void setFormats(const QVector<QTextCharFormat> &s);
 
-    QTextCharFormat labelTextCharFormat() const
-    { return m_formats[LabelFormat]; }
-
-    QSet<QString> keywords();
+    QTextCharFormat labelTextCharFormat() const;
 
 protected:
     virtual int onBlockStart();
@@ -69,14 +66,14 @@ protected:
     virtual void onOpeningParenthesis(QChar parenthesis, int pos);
     virtual void onClosingParenthesis(QChar parenthesis, int pos);
 
-    virtual void highlightWhitespace(const Token &token, const QString &text, int nonWhitespaceFormat);
+    bool maybeQmlKeyword(const QStringRef &text) const;
 
 protected:
     QmlJSScanner m_scanner;
 
 private:
-    bool m_duiEnabled;
     QTextCharFormat m_formats[NumFormats];
+    bool m_duiEnabled;
 };
 
 } // namespace QmlJS
diff --git a/src/libs/qmljs/qmljsscanner.cpp b/src/libs/qmljs/qmljsscanner.cpp
index 72ae34a0bba69e5be7a1537bcccd213e9c8dd9dc..c916f1aa234f236b954322af7b6fea0edb80842e 100644
--- a/src/libs/qmljs/qmljsscanner.cpp
+++ b/src/libs/qmljs/qmljsscanner.cpp
@@ -33,6 +33,49 @@
 
 using namespace QmlJS;
 
+namespace {
+QString js_keywords[] = {
+    QLatin1String("break"),
+    QString::fromLatin1("case"),
+    QString::fromLatin1("catch"),
+    QString::fromLatin1("continue"),
+    QString::fromLatin1("debugger"),
+    QString::fromLatin1("default"),
+    QString::fromLatin1("delete"),
+    QString::fromLatin1("do"),
+    QString::fromLatin1("else"),
+    QString::fromLatin1("finally"),
+    QString::fromLatin1("for"),
+    QString::fromLatin1("function"),
+    QString::fromLatin1("if"),
+    QString::fromLatin1("in"),
+    QString::fromLatin1("instanceof"),
+    QString::fromLatin1("new"),
+    QString::fromLatin1("return"),
+    QString::fromLatin1("switch"),
+    QString::fromLatin1("this"),
+    QString::fromLatin1("throw"),
+    QString::fromLatin1("try"),
+    QString::fromLatin1("typeof"),
+    QString::fromLatin1("var"),
+    QString::fromLatin1("void"),
+    QString::fromLatin1("while"),
+    QString::fromLatin1("with")
+};
+} // end of anonymous namespace
+
+template <typename _Tp, int N>
+const _Tp *begin(const _Tp (&a)[N])
+{
+    return a;
+}
+
+template <typename _Tp, int N>
+const _Tp *end(const _Tp (&a)[N])
+{
+    return a + N;
+}
+
 QmlJSScanner::QmlJSScanner()
     : m_state(0)
 {
@@ -240,7 +283,15 @@ QList<Token> QmlJSScanner::operator()(const QString &text, int startState)
     return tokens;
 }
 
+int QmlJSScanner::state() const
+{
+    return m_state;
+}
+
 bool QmlJSScanner::isKeyword(const QString &text) const
 {
-    return m_keywords.contains(text);
+    if (qBinaryFind(begin(js_keywords), end(js_keywords), text) != end(js_keywords))
+        return true;
+
+    return false;
 }
diff --git a/src/libs/qmljs/qmljsscanner.h b/src/libs/qmljs/qmljsscanner.h
index 9c98714fc69afa1dd860a033073152e4996fe36e..ae2485a52bcd8577cbcb1376c65e86f583048f29 100644
--- a/src/libs/qmljs/qmljsscanner.h
+++ b/src/libs/qmljs/qmljsscanner.h
@@ -80,19 +80,12 @@ public:
     QmlJSScanner();
     virtual ~QmlJSScanner();
 
-    void setKeywords(const QSet<QString> keywords)
-    { m_keywords = keywords; }
-
     QList<Token> operator()(const QString &text, int startState = 0);
+    int state() const;
 
-    int endState() const
-    { return m_state; }
-
-private:
     bool isKeyword(const QString &text) const;
 
 private:
-    QSet<QString> m_keywords;
     int m_state;
 };
 
diff --git a/src/plugins/qmljseditor/qmlhighlighter.cpp b/src/plugins/qmljseditor/qmlhighlighter.cpp
index 797a3585ecaaf810e11225654969d8a956699748..2c431407a579432d0449efd40f580aff5e842d60 100644
--- a/src/plugins/qmljseditor/qmlhighlighter.cpp
+++ b/src/plugins/qmljseditor/qmlhighlighter.cpp
@@ -39,13 +39,6 @@ QmlHighlighter::QmlHighlighter(QTextDocument *parent) :
 {
     m_currentBlockParentheses.reserve(20);
     m_braceDepth = 0;
-
-    QSet<QString> qmlKeywords(keywords());
-    qmlKeywords << QLatin1String("alias");
-    qmlKeywords << QLatin1String("property");
-    qmlKeywords << QLatin1String("signal");
-    qmlKeywords << QLatin1String("readonly");
-    m_scanner.setKeywords(qmlKeywords);
 }
 
 int QmlHighlighter::onBlockStart()