diff --git a/src/libs/cplusplus/CheckUndefinedSymbols.cpp b/src/libs/cplusplus/CheckUndefinedSymbols.cpp
index 3d993533950fa003d9f4dc9c68a2134d0e9ef814..d6d4cc6ee8bc72b2aa4742ec6f2c50514966530a 100644
--- a/src/libs/cplusplus/CheckUndefinedSymbols.cpp
+++ b/src/libs/cplusplus/CheckUndefinedSymbols.cpp
@@ -498,7 +498,7 @@ bool CheckUndefinedSymbols::visit(ObjCClassDeclarationAST *ast)
 
 bool CheckUndefinedSymbols::visit(ObjCProtocolRefsAST *ast)
 {
-    for (ObjCIdentifierListAST *iter = ast->identifier_list; iter; iter = iter->next) {
+    for (NameListAST *iter = ast->identifier_list; iter; iter = iter->next) {
         if (NameAST *nameAST = iter->value) {
             bool resolvedProtocolName = false;
 
diff --git a/src/libs/cplusplus/pp-engine.cpp b/src/libs/cplusplus/pp-engine.cpp
index 04a522824f83b5ef3192236090a5e6e0cdad8ac5..7c9fe50b398f0854f74a4befda86ca3741c109e2 100644
--- a/src/libs/cplusplus/pp-engine.cpp
+++ b/src/libs/cplusplus/pp-engine.cpp
@@ -766,10 +766,11 @@ void Preprocessor::preprocess(const QString &fileName, const QByteArray &source,
                     expandBuiltinMacro(identifierToken, spell);
 
                 else {
-#ifdef ICHECK_BUILD
-                    if(spell != "Q_PROPERTY" && spell != "Q_INVOKABLE" && spell != "Q_ENUMS"
-                        && spell != "Q_FLAGS" && spell != "Q_DECLARE_FLAGS"){
-#endif
+                    if (spell != "Q_PROPERTY" && spell != "Q_INVOKABLE" && spell != "Q_ENUMS"
+                        && spell != "Q_FLAGS" && spell != "Q_DECLARE_FLAGS") {
+
+                        // ### FIXME: shouldn't this be T_Q_PROPERTY & friends?
+
                         if (Macro *m = env->resolve(spell)) {
                             if (! m->isFunctionLike()) {
                                 if (0 == (m = processObjectLikeMacro(identifierToken, spell, m)))
@@ -790,9 +791,7 @@ void Preprocessor::preprocess(const QString &fileName, const QByteArray &source,
                                 }
                             }
                         }
-#ifdef ICHECK_BUILD
                     }
-#endif
                     // it's not a function or object-like macro.
                     out(spell);
                 }
diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp
index a6f5bfb674e006c7ff6f207ad4a400a6086cd6b4..e37a1b34b7f34623e75fca526251997158a429fa 100644
--- a/src/shared/cplusplus/AST.cpp
+++ b/src/shared/cplusplus/AST.cpp
@@ -144,42 +144,42 @@ unsigned AccessDeclarationAST::lastToken() const
     return access_specifier_token + 1;
 }
 
-unsigned QPropertyDeclarationAST::firstToken() const
+unsigned QtPropertyDeclarationAST::firstToken() const
 {
     return property_specifier_token;
 }
 
-unsigned QPropertyDeclarationAST::lastToken() const
+unsigned QtPropertyDeclarationAST::lastToken() const
 {
     return rparen_token;
 }
 
-unsigned QEnumDeclarationAST::firstToken() const
+unsigned QtEnumDeclarationAST::firstToken() const
 {
     return enum_specifier_token;
 }
 
-unsigned QEnumDeclarationAST::lastToken() const
+unsigned QtEnumDeclarationAST::lastToken() const
 {
     return rparen_token;
 }
 
-unsigned QFlagsDeclarationAST::firstToken() const
+unsigned QtFlagsDeclarationAST::firstToken() const
 {
     return this->flags_specifier_token;
 }
 
-unsigned QFlagsDeclarationAST::lastToken() const
+unsigned QtFlagsDeclarationAST::lastToken() const
 {
     return rparen_token;
 }
 
-unsigned QDeclareFlagsDeclarationAST::firstToken() const
+unsigned QtDeclareFlagsDeclarationAST::firstToken() const
 {
     return declareflags_specifier_token;
 }
 
-unsigned QDeclareFlagsDeclarationAST::lastToken() const
+unsigned QtDeclareFlagsDeclarationAST::lastToken() const
 {
     return rparen_token;
 }
diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h
index 1766891cd7ba3bab903329e2732f93cca97176bb..2117c73dcae222cbd485c9df711839d3d4c08656 100644
--- a/src/shared/cplusplus/AST.h
+++ b/src/shared/cplusplus/AST.h
@@ -256,12 +256,12 @@ public:
     virtual PostfixDeclaratorAST *asPostfixDeclarator() { return 0; }
     virtual PostfixExpressionAST *asPostfixExpression() { return 0; }
     virtual PtrOperatorAST *asPtrOperator() { return 0; }
-    virtual QDeclareFlagsDeclarationAST *asQDeclareFlagsDeclaration() { return 0; }
-    virtual QEnumDeclarationAST *asQEnumDeclaration() { return 0; }
-    virtual QFlagsDeclarationAST *asQFlagsDeclaration() { return 0; }
-    virtual QPropertyDeclarationAST *asQPropertyDeclaration() { return 0; }
+    virtual QtDeclareFlagsDeclarationAST *asQtDeclareFlagsDeclaration() { return 0; }
+    virtual QtEnumDeclarationAST *asQtEnumDeclaration() { return 0; }
+    virtual QtFlagsDeclarationAST *asQtFlagsDeclaration() { return 0; }
     virtual QtMemberDeclarationAST *asQtMemberDeclaration() { return 0; }
     virtual QtMethodAST *asQtMethod() { return 0; }
+    virtual QtPropertyDeclarationAST *asQtPropertyDeclaration() { return 0; }
     virtual QualifiedNameAST *asQualifiedName() { return 0; }
     virtual ReferenceAST *asReference() { return 0; }
     virtual ReturnStatementAST *asReturnStatement() { return 0; }
@@ -552,7 +552,7 @@ protected:
     virtual bool match0(AST *, ASTMatcher *);
 };
 
-class CPLUSPLUS_EXPORT QPropertyDeclarationAST: public DeclarationAST
+class CPLUSPLUS_EXPORT QtPropertyDeclarationAST: public DeclarationAST
 {
     /*
     Q_PROPERTY(type name
@@ -569,54 +569,63 @@ class CPLUSPLUS_EXPORT QPropertyDeclarationAST: public DeclarationAST
 public:
     unsigned property_specifier_token;
     unsigned lparen_token;
-    unsigned type_token;
-    unsigned type_name_token;
+    ExpressionAST *type_id;
+    SimpleNameAST *type_name;
     unsigned read_token;
-    unsigned read_function_token;
+    SimpleNameAST *read_function;
     unsigned write_token;
-    unsigned write_function_token;
+    SimpleNameAST *write_function;
     unsigned reset_token;
-    unsigned reset_function_token;
+    SimpleNameAST *reset_function;
     unsigned notify_token;
-    unsigned notify_function_token;
+    SimpleNameAST *notify_function;
+    unsigned designable_token;
+    BoolLiteralAST *designable_value;
+    unsigned scriptable_token;
+    BoolLiteralAST *scriptable_value;
+    unsigned stored_token;
+    BoolLiteralAST *stored_value;
+    unsigned user_token;
+    BoolLiteralAST *user_value;
+    unsigned constant_token;
+    unsigned final_token;
     unsigned rparen_token;
 
 public:
-    virtual QPropertyDeclarationAST *asQPropertyDeclaration() { return this; }
+    virtual QtPropertyDeclarationAST *asQtPropertyDeclaration() { return this; }
 
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
-    virtual QPropertyDeclarationAST *clone(MemoryPool *pool) const;
+    virtual QtPropertyDeclarationAST *clone(MemoryPool *pool) const;
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
     virtual bool match0(AST *, ASTMatcher *);
 };
 
-class CPLUSPLUS_EXPORT QEnumDeclarationAST: public DeclarationAST
+class CPLUSPLUS_EXPORT QtEnumDeclarationAST: public DeclarationAST
 {
-    /*Q_ENUMS(enum1, enum2)*/
 public:
     unsigned enum_specifier_token;
     unsigned lparen_token;
+    NameListAST *enumerator_list;
     unsigned rparen_token;
-    EnumeratorListAST *enumerator_list;
 
 public:
-    virtual QEnumDeclarationAST *asQEnumDeclaration() { return this; }
+    virtual QtEnumDeclarationAST *asQtEnumDeclaration() { return this; }
 
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
-    virtual QEnumDeclarationAST *clone(MemoryPool *pool) const;
+    virtual QtEnumDeclarationAST *clone(MemoryPool *pool) const;
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
     virtual bool match0(AST *, ASTMatcher *);
 };
 
-class CPLUSPLUS_EXPORT QFlagsDeclarationAST: public DeclarationAST
+class CPLUSPLUS_EXPORT QtFlagsDeclarationAST: public DeclarationAST
 {
     /*Q_FLAGS(enum1 enum2 flags1 ...)*/
 public:
@@ -626,19 +635,19 @@ public:
     EnumeratorListAST *enumerator_list;
 
 public:
-    virtual QFlagsDeclarationAST *asQFlagsDeclaration() { return this; }
+    virtual QtFlagsDeclarationAST *asQtFlagsDeclaration() { return this; }
 
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
-    virtual QFlagsDeclarationAST *clone(MemoryPool *pool) const;
+    virtual QtFlagsDeclarationAST *clone(MemoryPool *pool) const;
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
     virtual bool match0(AST *, ASTMatcher *);
 };
 
-class CPLUSPLUS_EXPORT QDeclareFlagsDeclarationAST: public DeclarationAST
+class CPLUSPLUS_EXPORT QtDeclareFlagsDeclarationAST: public DeclarationAST
 {
     /*Q_DECLARE_FLAGS(flag enum)*/
 public:
@@ -649,12 +658,12 @@ public:
     unsigned rparen_token;
 
 public:
-    virtual QDeclareFlagsDeclarationAST *asQDeclareFlagsDeclaration() { return this; }
+    virtual QtDeclareFlagsDeclarationAST *asQtDeclareFlagsDeclaration() { return this; }
 
     virtual unsigned firstToken() const;
     virtual unsigned lastToken() const;
 
-    virtual QDeclareFlagsDeclarationAST *clone(MemoryPool *pool) const;
+    virtual QtDeclareFlagsDeclarationAST *clone(MemoryPool *pool) const;
 
 protected:
     virtual void accept0(ASTVisitor *visitor);
@@ -2568,7 +2577,7 @@ class CPLUSPLUS_EXPORT ObjCClassForwardDeclarationAST: public DeclarationAST
 public:
     SpecifierListAST *attribute_list;
     unsigned class_token;
-    ObjCIdentifierListAST *identifier_list;
+    NameListAST *identifier_list;
     unsigned semicolon_token;
 
 public: // annotations
@@ -2625,7 +2634,7 @@ class CPLUSPLUS_EXPORT ObjCProtocolForwardDeclarationAST: public DeclarationAST
 public:
     SpecifierListAST *attribute_list;
     unsigned protocol_token;
-    ObjCIdentifierListAST *identifier_list;
+    NameListAST *identifier_list;
     unsigned semicolon_token;
 
 public: // annotations
@@ -2674,7 +2683,7 @@ class CPLUSPLUS_EXPORT ObjCProtocolRefsAST: public AST
 {
 public:
     unsigned less_token;
-    ObjCIdentifierListAST *identifier_list;
+    NameListAST *identifier_list;
     unsigned greater_token;
 
 public:
@@ -3064,7 +3073,7 @@ class CPLUSPLUS_EXPORT ObjCDynamicPropertiesDeclarationAST: public DeclarationAS
 {
 public:
     unsigned dynamic_token;
-    ObjCIdentifierListAST *property_identifier_list;
+    NameListAST *property_identifier_list;
     unsigned semicolon_token;
 
 public:
diff --git a/src/shared/cplusplus/ASTClone.cpp b/src/shared/cplusplus/ASTClone.cpp
index b794a8b4b12f9454f1d6735c8b3d9be950791fd5..07e9217b3d3ff275db3d147799a76c390033b4ff 100644
--- a/src/shared/cplusplus/ASTClone.cpp
+++ b/src/shared/cplusplus/ASTClone.cpp
@@ -138,40 +138,60 @@ AccessDeclarationAST *AccessDeclarationAST::clone(MemoryPool *pool) const
     return ast;
 }
 
-QPropertyDeclarationAST *QPropertyDeclarationAST::clone(MemoryPool *pool) const
+QtPropertyDeclarationAST *QtPropertyDeclarationAST::clone(MemoryPool *pool) const
 {
-    QPropertyDeclarationAST *ast = new (pool) QPropertyDeclarationAST;
+    QtPropertyDeclarationAST *ast = new (pool) QtPropertyDeclarationAST;
     ast->property_specifier_token = property_specifier_token;
     ast->lparen_token = lparen_token;
-    ast->type_token = type_token;
-    ast->type_name_token = type_name_token;
+    if (type_id)
+        ast->type_id = type_id->clone(pool);
+    if (type_name)
+        ast->type_name = type_name->clone(pool);
     ast->read_token = read_token;
-    ast->read_function_token = read_function_token;
+    if (read_function)
+        ast->read_function = read_function->clone(pool);
     ast->write_token = write_token;
-    ast->write_function_token = write_function_token;
+    if (write_function)
+        ast->write_function = write_function->clone(pool);
     ast->reset_token = reset_token;
-    ast->reset_function_token = reset_function_token;
+    if (reset_function)
+        ast->reset_function = reset_function->clone(pool);
     ast->notify_token = notify_token;
-    ast->notify_function_token = notify_function_token;
+    if (notify_function)
+        ast->notify_function = notify_function->clone(pool);
+    ast->designable_token = designable_token;
+    if (designable_value)
+        ast->designable_value = designable_value->clone(pool);
+    ast->scriptable_token = scriptable_token;
+    if (scriptable_value)
+        ast->scriptable_value = scriptable_value->clone(pool);
+    ast->stored_token = stored_token;
+    if (stored_value)
+        ast->stored_value = stored_value->clone(pool);
+    ast->user_token = user_token;
+    if (user_value)
+        ast->user_value = user_value->clone(pool);
+    ast->constant_token = constant_token;
+    ast->final_token = final_token;
     ast->rparen_token = rparen_token;
     return ast;
 }
 
-QEnumDeclarationAST *QEnumDeclarationAST::clone(MemoryPool *pool) const
+QtEnumDeclarationAST *QtEnumDeclarationAST::clone(MemoryPool *pool) const
 {
-    QEnumDeclarationAST *ast = new (pool) QEnumDeclarationAST;
+    QtEnumDeclarationAST *ast = new (pool) QtEnumDeclarationAST;
     ast->enum_specifier_token = enum_specifier_token;
     ast->lparen_token = lparen_token;
-    ast->rparen_token = rparen_token;
-    for (EnumeratorListAST *iter = enumerator_list, **ast_iter = &ast->enumerator_list;
+    for (NameListAST *iter = enumerator_list, **ast_iter = &ast->enumerator_list;
          iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
-        *ast_iter = new (pool) EnumeratorListAST((iter->value) ? iter->value->clone(pool) : 0);
+        *ast_iter = new (pool) NameListAST((iter->value) ? iter->value->clone(pool) : 0);
+    ast->rparen_token = rparen_token;
     return ast;
 }
 
-QFlagsDeclarationAST *QFlagsDeclarationAST::clone(MemoryPool *pool) const
+QtFlagsDeclarationAST *QtFlagsDeclarationAST::clone(MemoryPool *pool) const
 {
-    QFlagsDeclarationAST *ast = new (pool) QFlagsDeclarationAST;
+    QtFlagsDeclarationAST *ast = new (pool) QtFlagsDeclarationAST;
     ast->flags_specifier_token = flags_specifier_token;
     ast->lparen_token = lparen_token;
     ast->rparen_token = rparen_token;
@@ -181,9 +201,9 @@ QFlagsDeclarationAST *QFlagsDeclarationAST::clone(MemoryPool *pool) const
     return ast;
 }
 
-QDeclareFlagsDeclarationAST *QDeclareFlagsDeclarationAST::clone(MemoryPool *pool) const
+QtDeclareFlagsDeclarationAST *QtDeclareFlagsDeclarationAST::clone(MemoryPool *pool) const
 {
-    QDeclareFlagsDeclarationAST *ast = new (pool) QDeclareFlagsDeclarationAST;
+    QtDeclareFlagsDeclarationAST *ast = new (pool) QtDeclareFlagsDeclarationAST;
     ast->declareflags_specifier_token = declareflags_specifier_token;
     ast->lparen_token = lparen_token;
     ast->flag_token = flag_token;
@@ -1225,9 +1245,9 @@ ObjCClassForwardDeclarationAST *ObjCClassForwardDeclarationAST::clone(MemoryPool
          iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
         *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
     ast->class_token = class_token;
-    for (ObjCIdentifierListAST *iter = identifier_list, **ast_iter = &ast->identifier_list;
+    for (NameListAST *iter = identifier_list, **ast_iter = &ast->identifier_list;
          iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
-        *ast_iter = new (pool) ObjCIdentifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+        *ast_iter = new (pool) NameListAST((iter->value) ? iter->value->clone(pool) : 0);
     ast->semicolon_token = semicolon_token;
     return ast;
 }
@@ -1267,9 +1287,9 @@ ObjCProtocolForwardDeclarationAST *ObjCProtocolForwardDeclarationAST::clone(Memo
          iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
         *ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
     ast->protocol_token = protocol_token;
-    for (ObjCIdentifierListAST *iter = identifier_list, **ast_iter = &ast->identifier_list;
+    for (NameListAST *iter = identifier_list, **ast_iter = &ast->identifier_list;
          iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
-        *ast_iter = new (pool) ObjCIdentifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+        *ast_iter = new (pool) NameListAST((iter->value) ? iter->value->clone(pool) : 0);
     ast->semicolon_token = semicolon_token;
     return ast;
 }
@@ -1296,9 +1316,9 @@ ObjCProtocolRefsAST *ObjCProtocolRefsAST::clone(MemoryPool *pool) const
 {
     ObjCProtocolRefsAST *ast = new (pool) ObjCProtocolRefsAST;
     ast->less_token = less_token;
-    for (ObjCIdentifierListAST *iter = identifier_list, **ast_iter = &ast->identifier_list;
+    for (NameListAST *iter = identifier_list, **ast_iter = &ast->identifier_list;
          iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
-        *ast_iter = new (pool) ObjCIdentifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+        *ast_iter = new (pool) NameListAST((iter->value) ? iter->value->clone(pool) : 0);
     ast->greater_token = greater_token;
     return ast;
 }
@@ -1501,9 +1521,9 @@ ObjCDynamicPropertiesDeclarationAST *ObjCDynamicPropertiesDeclarationAST::clone(
 {
     ObjCDynamicPropertiesDeclarationAST *ast = new (pool) ObjCDynamicPropertiesDeclarationAST;
     ast->dynamic_token = dynamic_token;
-    for (ObjCIdentifierListAST *iter = property_identifier_list, **ast_iter = &ast->property_identifier_list;
+    for (NameListAST *iter = property_identifier_list, **ast_iter = &ast->property_identifier_list;
          iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
-        *ast_iter = new (pool) ObjCIdentifierListAST((iter->value) ? iter->value->clone(pool) : 0);
+        *ast_iter = new (pool) NameListAST((iter->value) ? iter->value->clone(pool) : 0);
     ast->semicolon_token = semicolon_token;
     return ast;
 }
diff --git a/src/shared/cplusplus/ASTMatch0.cpp b/src/shared/cplusplus/ASTMatch0.cpp
index f1d47aaa8a28d56fd6f764bd44de46eb0aa89092..6a49dba34a952630b62d650fbbc5c5f0748b19f2 100644
--- a/src/shared/cplusplus/ASTMatch0.cpp
+++ b/src/shared/cplusplus/ASTMatch0.cpp
@@ -105,33 +105,33 @@ bool AccessDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
     return false;
 }
 
-bool QPropertyDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
+bool QtPropertyDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
 {
-    if (QPropertyDeclarationAST *_other = pattern->asQPropertyDeclaration())
+    if (QtPropertyDeclarationAST *_other = pattern->asQtPropertyDeclaration())
         return matcher->match(this, _other);
 
     return false;
 }
 
-bool QEnumDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
+bool QtEnumDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
 {
-    if (QEnumDeclarationAST *_other = pattern->asQEnumDeclaration())
+    if (QtEnumDeclarationAST *_other = pattern->asQtEnumDeclaration())
         return matcher->match(this, _other);
 
     return false;
 }
 
-bool QFlagsDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
+bool QtFlagsDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
 {
-    if (QFlagsDeclarationAST *_other = pattern->asQFlagsDeclaration())
+    if (QtFlagsDeclarationAST *_other = pattern->asQtFlagsDeclaration())
         return matcher->match(this, _other);
 
     return false;
 }
 
-bool QDeclareFlagsDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
+bool QtDeclareFlagsDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
 {
-    if (QDeclareFlagsDeclarationAST *_other = pattern->asQDeclareFlagsDeclaration())
+    if (QtDeclareFlagsDeclarationAST *_other = pattern->asQtDeclareFlagsDeclaration())
         return matcher->match(this, _other);
 
     return false;
diff --git a/src/shared/cplusplus/ASTMatcher.cpp b/src/shared/cplusplus/ASTMatcher.cpp
index aa1a0f3ba62f55c68edc2cb2341b4838eeee5163..25b0ef3d2d531969fb06152d21a2f761e9568f2d 100644
--- a/src/shared/cplusplus/ASTMatcher.cpp
+++ b/src/shared/cplusplus/ASTMatcher.cpp
@@ -206,7 +206,7 @@ bool ASTMatcher::match(AccessDeclarationAST *node, AccessDeclarationAST *pattern
     return true;
 }
 
-bool ASTMatcher::match(QPropertyDeclarationAST *node, QPropertyDeclarationAST *pattern)
+bool ASTMatcher::match(QtPropertyDeclarationAST *node, QtPropertyDeclarationAST *pattern)
 {
     (void) node;
     (void) pattern;
@@ -215,32 +215,82 @@ bool ASTMatcher::match(QPropertyDeclarationAST *node, QPropertyDeclarationAST *p
 
     pattern->lparen_token = node->lparen_token;
 
-    pattern->type_token = node->type_token;
+    if (! pattern->type_id)
+        pattern->type_id = node->type_id;
+    else if (! AST::match(node->type_id, pattern->type_id, this))
+        return false;
 
-    pattern->type_name_token = node->type_name_token;
+    if (! pattern->type_name)
+        pattern->type_name = node->type_name;
+    else if (! AST::match(node->type_name, pattern->type_name, this))
+        return false;
 
     pattern->read_token = node->read_token;
 
-    pattern->read_function_token = node->read_function_token;
+    if (! pattern->read_function)
+        pattern->read_function = node->read_function;
+    else if (! AST::match(node->read_function, pattern->read_function, this))
+        return false;
 
     pattern->write_token = node->write_token;
 
-    pattern->write_function_token = node->write_function_token;
+    if (! pattern->write_function)
+        pattern->write_function = node->write_function;
+    else if (! AST::match(node->write_function, pattern->write_function, this))
+        return false;
 
     pattern->reset_token = node->reset_token;
 
-    pattern->reset_function_token = node->reset_function_token;
+    if (! pattern->reset_function)
+        pattern->reset_function = node->reset_function;
+    else if (! AST::match(node->reset_function, pattern->reset_function, this))
+        return false;
 
     pattern->notify_token = node->notify_token;
 
-    pattern->notify_function_token = node->notify_function_token;
+    if (! pattern->notify_function)
+        pattern->notify_function = node->notify_function;
+    else if (! AST::match(node->notify_function, pattern->notify_function, this))
+        return false;
+
+    pattern->designable_token = node->designable_token;
+
+    if (! pattern->designable_value)
+        pattern->designable_value = node->designable_value;
+    else if (! AST::match(node->designable_value, pattern->designable_value, this))
+        return false;
+
+    pattern->scriptable_token = node->scriptable_token;
+
+    if (! pattern->scriptable_value)
+        pattern->scriptable_value = node->scriptable_value;
+    else if (! AST::match(node->scriptable_value, pattern->scriptable_value, this))
+        return false;
+
+    pattern->stored_token = node->stored_token;
+
+    if (! pattern->stored_value)
+        pattern->stored_value = node->stored_value;
+    else if (! AST::match(node->stored_value, pattern->stored_value, this))
+        return false;
+
+    pattern->user_token = node->user_token;
+
+    if (! pattern->user_value)
+        pattern->user_value = node->user_value;
+    else if (! AST::match(node->user_value, pattern->user_value, this))
+        return false;
+
+    pattern->constant_token = node->constant_token;
+
+    pattern->final_token = node->final_token;
 
     pattern->rparen_token = node->rparen_token;
 
     return true;
 }
 
-bool ASTMatcher::match(QEnumDeclarationAST *node, QEnumDeclarationAST *pattern)
+bool ASTMatcher::match(QtEnumDeclarationAST *node, QtEnumDeclarationAST *pattern)
 {
     (void) node;
     (void) pattern;
@@ -249,17 +299,17 @@ bool ASTMatcher::match(QEnumDeclarationAST *node, QEnumDeclarationAST *pattern)
 
     pattern->lparen_token = node->lparen_token;
 
-    pattern->rparen_token = node->rparen_token;
-
     if (! pattern->enumerator_list)
         pattern->enumerator_list = node->enumerator_list;
     else if (! AST::match(node->enumerator_list, pattern->enumerator_list, this))
         return false;
 
+    pattern->rparen_token = node->rparen_token;
+
     return true;
 }
 
-bool ASTMatcher::match(QFlagsDeclarationAST *node, QFlagsDeclarationAST *pattern)
+bool ASTMatcher::match(QtFlagsDeclarationAST *node, QtFlagsDeclarationAST *pattern)
 {
     (void) node;
     (void) pattern;
@@ -278,7 +328,7 @@ bool ASTMatcher::match(QFlagsDeclarationAST *node, QFlagsDeclarationAST *pattern
     return true;
 }
 
-bool ASTMatcher::match(QDeclareFlagsDeclarationAST *node, QDeclareFlagsDeclarationAST *pattern)
+bool ASTMatcher::match(QtDeclareFlagsDeclarationAST *node, QtDeclareFlagsDeclarationAST *pattern)
 {
     (void) node;
     (void) pattern;
diff --git a/src/shared/cplusplus/ASTMatcher.h b/src/shared/cplusplus/ASTMatcher.h
index c8263ab23775e73dae2852d41556b2c78e68fe45..df097eec3016f474529f651044b0c07a26a95f19 100644
--- a/src/shared/cplusplus/ASTMatcher.h
+++ b/src/shared/cplusplus/ASTMatcher.h
@@ -40,10 +40,10 @@ public:
     virtual ~ASTMatcher();
 
     virtual bool match(AccessDeclarationAST *node, AccessDeclarationAST *pattern);
-    virtual bool match(QPropertyDeclarationAST *node, QPropertyDeclarationAST *pattern);
-    virtual bool match(QEnumDeclarationAST *node, QEnumDeclarationAST *pattern);
-    virtual bool match(QFlagsDeclarationAST *node, QFlagsDeclarationAST *pattern);
-    virtual bool match(QDeclareFlagsDeclarationAST *node, QDeclareFlagsDeclarationAST *pattern);
+    virtual bool match(QtPropertyDeclarationAST *node, QtPropertyDeclarationAST *pattern);
+    virtual bool match(QtEnumDeclarationAST *node, QtEnumDeclarationAST *pattern);
+    virtual bool match(QtFlagsDeclarationAST *node, QtFlagsDeclarationAST *pattern);
+    virtual bool match(QtDeclareFlagsDeclarationAST *node, QtDeclareFlagsDeclarationAST *pattern);
     virtual bool match(ArrayAccessAST *node, ArrayAccessAST *pattern);
     virtual bool match(ArrayDeclaratorAST *node, ArrayDeclaratorAST *pattern);
     virtual bool match(ArrayInitializerAST *node, ArrayInitializerAST *pattern);
diff --git a/src/shared/cplusplus/ASTVisit.cpp b/src/shared/cplusplus/ASTVisit.cpp
index 0d7d7fee19fe599b26a11f65e9be40b6f6f28203..68e1d7219fd0fc014b692b0388d642ecdbf954ef 100644
--- a/src/shared/cplusplus/ASTVisit.cpp
+++ b/src/shared/cplusplus/ASTVisit.cpp
@@ -108,14 +108,24 @@ void AccessDeclarationAST::accept0(ASTVisitor *visitor)
     visitor->endVisit(this);
 }
 
-void QPropertyDeclarationAST::accept0(ASTVisitor *visitor)
+void QtPropertyDeclarationAST::accept0(ASTVisitor *visitor)
 {
     if (visitor->visit(this)) {
+        accept(type_id, visitor);
+        accept(type_name, visitor);
+        accept(read_function, visitor);
+        accept(write_function, visitor);
+        accept(reset_function, visitor);
+        accept(notify_function, visitor);
+        accept(designable_value, visitor);
+        accept(scriptable_value, visitor);
+        accept(stored_value, visitor);
+        accept(user_value, visitor);
     }
     visitor->endVisit(this);
 }
 
-void QEnumDeclarationAST::accept0(ASTVisitor *visitor)
+void QtEnumDeclarationAST::accept0(ASTVisitor *visitor)
 {
     if (visitor->visit(this)) {
         accept(enumerator_list, visitor);
@@ -123,7 +133,7 @@ void QEnumDeclarationAST::accept0(ASTVisitor *visitor)
     visitor->endVisit(this);
 }
 
-void QFlagsDeclarationAST::accept0(ASTVisitor *visitor)
+void QtFlagsDeclarationAST::accept0(ASTVisitor *visitor)
 {
     if (visitor->visit(this)) {
         accept(enumerator_list, visitor);
@@ -131,7 +141,7 @@ void QFlagsDeclarationAST::accept0(ASTVisitor *visitor)
     visitor->endVisit(this);
 }
 
-void QDeclareFlagsDeclarationAST::accept0(ASTVisitor *visitor)
+void QtDeclareFlagsDeclarationAST::accept0(ASTVisitor *visitor)
 {
     if (visitor->visit(this)) {
     }
diff --git a/src/shared/cplusplus/ASTVisitor.h b/src/shared/cplusplus/ASTVisitor.h
index 2e10093c5bcd170ef27dc1fa61040bb324f933b0..92cd08f3924e2a148c61cabbe44aa80cbc2d61a1 100644
--- a/src/shared/cplusplus/ASTVisitor.h
+++ b/src/shared/cplusplus/ASTVisitor.h
@@ -103,10 +103,10 @@ public:
     virtual void postVisit(AST *) {}
 
     virtual bool visit(AccessDeclarationAST *) { return true; }
-    virtual bool visit(QPropertyDeclarationAST *) { return true; }
-    virtual bool visit(QEnumDeclarationAST *) { return true; }
-    virtual bool visit(QFlagsDeclarationAST *) { return true; }
-    virtual bool visit(QDeclareFlagsDeclarationAST *) { return true; }
+    virtual bool visit(QtPropertyDeclarationAST *) { return true; }
+    virtual bool visit(QtEnumDeclarationAST *) { return true; }
+    virtual bool visit(QtFlagsDeclarationAST *) { return true; }
+    virtual bool visit(QtDeclareFlagsDeclarationAST *) { return true; }
     virtual bool visit(ArrayAccessAST *) { return true; }
     virtual bool visit(ArrayDeclaratorAST *) { return true; }
     virtual bool visit(ArrayInitializerAST *) { return true; }
@@ -234,10 +234,10 @@ public:
     virtual bool visit(ObjCSynchronizedStatementAST *) { return true; }
 
     virtual void endVisit(AccessDeclarationAST *) { }
-    virtual void endVisit(QPropertyDeclarationAST *) { }
-    virtual void endVisit(QEnumDeclarationAST *) { }
-    virtual void endVisit(QFlagsDeclarationAST *) { }
-    virtual void endVisit(QDeclareFlagsDeclarationAST *) { }
+    virtual void endVisit(QtPropertyDeclarationAST *) { }
+    virtual void endVisit(QtEnumDeclarationAST *) { }
+    virtual void endVisit(QtFlagsDeclarationAST *) { }
+    virtual void endVisit(QtDeclareFlagsDeclarationAST *) { }
     virtual void endVisit(ArrayAccessAST *) { }
     virtual void endVisit(ArrayDeclaratorAST *) { }
     virtual void endVisit(ArrayInitializerAST *) { }
diff --git a/src/shared/cplusplus/ASTfwd.h b/src/shared/cplusplus/ASTfwd.h
index 13a02c0e5cf44f58bf27fbdedc1ff6d870ed61cc..9890143e41e95850399ac7ea02aa343fcc03d361 100644
--- a/src/shared/cplusplus/ASTfwd.h
+++ b/src/shared/cplusplus/ASTfwd.h
@@ -163,12 +163,12 @@ class PostfixAST;
 class PostfixDeclaratorAST;
 class PostfixExpressionAST;
 class PtrOperatorAST;
-class QDeclareFlagsDeclarationAST;
-class QEnumDeclarationAST;
-class QFlagsDeclarationAST;
-class QPropertyDeclarationAST;
+class QtDeclareFlagsDeclarationAST;
+class QtEnumDeclarationAST;
+class QtFlagsDeclarationAST;
 class QtMemberDeclarationAST;
 class QtMethodAST;
+class QtPropertyDeclarationAST;
 class QualifiedNameAST;
 class ReferenceAST;
 class ReturnStatementAST;
@@ -214,7 +214,7 @@ typedef List<CatchClauseAST *> CatchClauseListAST;
 typedef List<PtrOperatorAST *> PtrOperatorListAST;
 typedef List<SpecifierAST *> SpecifierListAST;
 
-typedef List<NameAST *> ObjCIdentifierListAST;
+typedef List<NameAST *> NameListAST;
 typedef List<ObjCMessageArgumentAST *> ObjCMessageArgumentListAST;
 typedef List<ObjCSelectorArgumentAST *> ObjCSelectorArgumentListAST;
 typedef List<ObjCPropertyAttributeAST *> ObjCPropertyAttributeListAST;
diff --git a/src/shared/cplusplus/CheckDeclaration.cpp b/src/shared/cplusplus/CheckDeclaration.cpp
index 54e457aaccc228b06e374adeffd1b307bbeeac81..7a6e07ce971ec5d1ba420281ee7a99a2530cdf23 100644
--- a/src/shared/cplusplus/CheckDeclaration.cpp
+++ b/src/shared/cplusplus/CheckDeclaration.cpp
@@ -556,7 +556,7 @@ bool CheckDeclaration::visit(ObjCProtocolForwardDeclarationAST *ast)
     const unsigned sourceLocation = ast->firstToken();
 
     List<ObjCForwardProtocolDeclaration *> **symbolIter = &ast->symbols;
-    for (ObjCIdentifierListAST *it = ast->identifier_list; it; it = it->next) {
+    for (NameListAST *it = ast->identifier_list; it; it = it->next) {
         unsigned declarationLocation;
         if (it->value)
             declarationLocation = it->value->firstToken();
@@ -592,7 +592,7 @@ bool CheckDeclaration::visit(ObjCProtocolDeclarationAST *ast)
     protocol->setEndOffset(tokenAt(ast->lastToken()).offset);
 
     if (ast->protocol_refs && ast->protocol_refs->identifier_list) {
-        for (ObjCIdentifierListAST *iter = ast->protocol_refs->identifier_list; iter; iter = iter->next) {
+        for (NameListAST *iter = ast->protocol_refs->identifier_list; iter; iter = iter->next) {
             NameAST* name = iter->value;
             const Name *protocolName = semantic()->check(name, _scope);
             ObjCBaseProtocol *baseProtocol = control()->newObjCBaseProtocol(name->firstToken(), protocolName);
@@ -617,7 +617,7 @@ bool CheckDeclaration::visit(ObjCClassForwardDeclarationAST *ast)
     const unsigned sourceLocation = ast->firstToken();
 
     List<ObjCForwardClassDeclaration *> **symbolIter = &ast->symbols;
-    for (ObjCIdentifierListAST *it = ast->identifier_list; it; it = it->next) {
+    for (NameListAST *it = ast->identifier_list; it; it = it->next) {
         unsigned declarationLocation;
         if (it->value)
             declarationLocation = it->value->firstToken();
@@ -667,7 +667,7 @@ bool CheckDeclaration::visit(ObjCClassDeclarationAST *ast)
     }
 
     if (ast->protocol_refs && ast->protocol_refs->identifier_list) {
-        for (ObjCIdentifierListAST *iter = ast->protocol_refs->identifier_list; iter; iter = iter->next) {
+        for (NameListAST *iter = ast->protocol_refs->identifier_list; iter; iter = iter->next) {
             NameAST* name = iter->value;
             const Name *protocolName = semantic()->check(name, _scope);
             ObjCBaseProtocol *baseProtocol = control()->newObjCBaseProtocol(name->firstToken(), protocolName);
diff --git a/src/shared/cplusplus/Keywords.cpp b/src/shared/cplusplus/Keywords.cpp
index 51757eb8c86dcecba0cd7db2fce0e64e89f8cdf9..414221efa630f447ac0e6f39a8a879fe98c4c0d6 100644
--- a/src/shared/cplusplus/Keywords.cpp
+++ b/src/shared/cplusplus/Keywords.cpp
@@ -718,7 +718,6 @@ static inline int classify7(const char *s, bool q) {
           }
         }
       }
-#ifdef ICHECK_BUILD
       else if (s[2] == 'E') {
         if (s[3] == 'N') {
           if (s[4] == 'U') {
@@ -741,7 +740,6 @@ static inline int classify7(const char *s, bool q) {
           }
         }
       }
-#endif
     }
   }
   return T_IDENTIFIER;
@@ -1103,7 +1101,6 @@ static inline int classify10(const char *s, bool) {
       }
     }
   }
-#ifdef ICHECK_BUILD
   else if (s[0] == 'Q') {
     if (s[1] == '_') {
       if (s[2] == 'P') {
@@ -1125,7 +1122,6 @@ static inline int classify10(const char *s, bool) {
       }
     }
   }
-#endif
   return T_IDENTIFIER;
 }
 
@@ -1176,7 +1172,6 @@ static inline int classify11(const char *s, bool) {
       }
     }
   }
-#ifdef ICHECK_BUILD
   else if (s[0] == 'Q') {
     if (s[1] == '_') {
       if (s[2] == 'I') {
@@ -1200,7 +1195,6 @@ static inline int classify11(const char *s, bool) {
       }
     }
   }
-#endif
   return T_IDENTIFIER;
 }
 
@@ -1289,7 +1283,6 @@ static inline int classify13(const char *s, bool) {
   return T_IDENTIFIER;
 }
 
-#ifdef ICHECK_BUILD
 static inline int classify15(const char *s, bool) {
   if (s[0] == 'Q') {
     if (s[1] == '_') {
@@ -1324,7 +1317,6 @@ static inline int classify15(const char *s, bool) {
   }
   return T_IDENTIFIER;
 }
-#endif
 
 static inline int classify16(const char *s, bool) {
   if (s[0] == 'r') {
@@ -1377,9 +1369,7 @@ int Lexer::classify(const char *s, int n, bool q) {
     case 11: return classify11(s, q);
     case 12: return classify12(s, q);
     case 13: return classify13(s, q);
-#ifdef ICHECK_BUILD
     case 15: return classify15(s, q);
-#endif
     case 16: return classify16(s, q);
     default: return T_IDENTIFIER;
   } // switch
diff --git a/src/shared/cplusplus/ObjectiveCAtKeywords.cpp b/src/shared/cplusplus/ObjectiveCAtKeywords.cpp
index 141e798ab728cf34b0785ce811abb7b88c5f4e61..78b0cf94a41f317371f8ef389d3888db53dd2274 100644
--- a/src/shared/cplusplus/ObjectiveCAtKeywords.cpp
+++ b/src/shared/cplusplus/ObjectiveCAtKeywords.cpp
@@ -489,5 +489,3 @@ int Lexer::classifyObjCAtKeyword(const char *s, int n) {
     default: return T_ERROR;
   } // switch
 }
-
-
diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp
index 864ec779ab4ab89d862745d9bba6ac15892b4979..072cecc1037ca844ac136f21d5800a2ff457a496 100644
--- a/src/shared/cplusplus/Parser.cpp
+++ b/src/shared/cplusplus/Parser.cpp
@@ -53,10 +53,8 @@
 #include "AST.h"
 #include "Literals.h"
 #include "ObjectiveCTypeQualifiers.h"
+#include "QtContextKeywords.h"
 #include <cstdio> // for putchar
-#ifdef ICHECK_BUILD
-#  include <QString>
-#endif
 
 #define CPLUSPLUS_NO_DEBUG_RULE
 #define MAX_EXPRESSION_DEPTH 100
@@ -1762,107 +1760,165 @@ bool Parser::parseAccessDeclaration(DeclarationAST *&node)
     return false;
 }
 
-#ifdef ICHECK_BUILD
+/*
+ Q_PROPERTY(type name
+        READ getFunction
+        [WRITE setFunction]
+        [RESET resetFunction]
+        [NOTIFY notifySignal]
+        [DESIGNABLE bool]
+        [SCRIPTABLE bool]
+        [STORED bool]
+        [USER bool]
+        [CONSTANT]
+        [FINAL])
+
+    Note that "type" appears to be any valid type. So these are valid:
+      Q_PROPERTY(const char *zoo READ zoo)
+      Q_PROPERTY(const class Blah *blah READ blah)
+
+    Furthermore, the only restriction on the order of the items in between the
+    parenthesis is that the type is the first parameter and the name comes after
+    the type.
+*/
 bool Parser::parseQPropertyDeclaration(DeclarationAST *&node)
 {
-    /*
-     Q_PROPERTY(type name
-            READ getFunction
-            [WRITE setFunction]
-            [RESET resetFunction]
-            [NOTIFY notifySignal]
-            [DESIGNABLE bool]
-            [SCRIPTABLE bool]
-            [STORED bool]
-            [USER bool]
-            [CONSTANT]
-            [FINAL])*/
-    DEBUG_THIS_RULE();
-    if (LA() == T_Q_PROPERTY) {
-        QPropertyDeclarationAST *ast = new (_pool)QPropertyDeclarationAST;
-        ast->property_specifier_token = consumeToken();
-        if(LA() == T_LPAREN){
-            ast->lparen_token = consumeToken();
-            QString tokenstr;
-            tokenstr = tok().spell();
-            //read the type and the name of the type
-            if(tokenstr !=  "READ" ){
-                ast->type_token = consumeToken();
-                tokenstr = tok().spell();
-            }
-            if(tokenstr !=  "READ" ){
-                ast->type_name_token = consumeToken();
-                tokenstr = tok().spell();
-            }
-            unsigned fctdefinition = 0;
-            unsigned fctname = 0;
-            for(int i = 0; i < 18; i++){
-                if(cursor() < _translationUnit->tokenCount() - 1){
-                    if(LA() == T_RPAREN){
-                        ast->rparen_token = consumeToken();
+    DEBUG_THIS_RULE();
+    if (LA() != T_Q_PROPERTY)
+        return false;
+
+    QtPropertyDeclarationAST *ast = new (_pool)QtPropertyDeclarationAST;
+    ast->property_specifier_token = consumeToken();
+    if (LA() == T_LPAREN) {
+        ast->lparen_token = consumeToken();
+        parseTypeId(ast->type_id);
+        ast->type_name = new (_pool) SimpleNameAST;
+        match(T_IDENTIFIER, &ast->type_name->identifier_token);
+
+        while (true) {
+            if (LA() == T_RPAREN) {
+                ast->rparen_token = consumeToken();
+                node = ast;
+                break;
+            } else if (LA() == T_IDENTIFIER) {
+                switch (peekAtQtContextKeyword()) {
+                case Token_READ:
+                    ast->read_token = consumeToken();
+                    ast->read_function = new (_pool) SimpleNameAST;
+                    match(T_IDENTIFIER, &ast->read_function->identifier_token);
+                    break;
+
+                case Token_WRITE:
+                    ast->write_token = consumeToken();
+                    ast->write_function = new (_pool) SimpleNameAST;
+                    match(T_IDENTIFIER, &ast->write_function->identifier_token);
+                    break;
+
+                case Token_RESET:
+                    ast->reset_token = consumeToken();
+                    ast->reset_function = new (_pool) SimpleNameAST;
+                    match(T_IDENTIFIER, &ast->reset_function->identifier_token);
+                    break;
+
+                case Token_NOTIFY:
+                    ast->notify_token = consumeToken();
+                    ast->notify_function = new (_pool) SimpleNameAST;
+                    match(T_IDENTIFIER, &ast->notify_function->identifier_token);
+                    break;
+
+                case Token_DESIGNABLE:
+                    ast->designable_token = consumeToken();
+                    if (!matchBoolean(ast->designable_value))
                         break;
-                    }
-                    tokenstr = tok().spell();
-                    fctdefinition = consumeToken();
-                    fctname = consumeToken();
-                    if(tokenstr == "READ"){
-                        ast->read_token = fctdefinition;
-                        ast->read_function_token = fctname;
-                    }
-                    else if(tokenstr == "WRITE"){
-                        ast->write_token = fctdefinition;
-                        ast->write_function_token = fctname;
-                    }
-                    else if(tokenstr == "RESET"){
-                        ast->reset_token = fctdefinition;
-                        ast->reset_function_token = fctname;
-                    }
-                    else if(tokenstr == "NOTIFY"){
-                        ast->notify_token = fctdefinition;
-                        ast->notify_function_token = fctname;
-                    }
+                    break;
+
+                case Token_SCRIPTABLE:
+                    ast->scriptable_token = consumeToken();
+                    if (!matchBoolean(ast->scriptable_value))
+                        break;
+                    break;
+
+                case Token_STORED:
+                    ast->stored_token = consumeToken();
+                    if (!matchBoolean(ast->stored_value))
+                        break;
+                    break;
+
+                case Token_USER:
+                    ast->user_token = consumeToken();
+                    if (!matchBoolean(ast->user_value))
+                        break;
+                    break;
+
+                case Token_CONSTANT:
+                    ast->constant_token = consumeToken();
+                    break;
+
+                case Token_FINAL:
+                    ast->final_token = consumeToken();
+                    break;
+
+                default:
+                    _translationUnit->error(cursor(), "expected `)' before `%s'", tok().spell());
+                    return true;
                 }
+            } else {
+                _translationUnit->error(cursor(), "expected `)' before `%s'", tok().spell());
+                break;
             }
         }
-        node = ast;
+    }
+    return true;
+}
+
+bool Parser::matchBoolean(BoolLiteralAST *&node)
+{
+    ExpressionAST *expr = 0;
+    if (parseBoolLiteral(expr)) {
+        node = expr->asBoolLiteral();
         return true;
+    } else {
+        _translationUnit->error(cursor(), "expected `true' or `false' before `%s'", tok().spell());
+        return false;
     }
-    return false;
 }
 
+// q-enums-decl ::= 'Q_ENUMS' '(' q-enums-list? ')'
+// q-enums-list ::= identifier
+// q-enums-list ::= q-enums-list identifier
+//
+// Note: Q_ENUMS is a CPP macro with exactly 1 parameter.
+// Examples of valid uses:
+//   Q_ENUMS()
+//   Q_ENUMS(Priority)
+//   Q_ENUMS(Priority Severity)
+// so, these are not allowed:
+//   Q_ENUMS
+//   Q_ENUMS(Priority, Severity)
 bool Parser::parseQEnumDeclaration(DeclarationAST *&node)
 {
-     /*Q_ENUMS(ConnectionState)*/
     DEBUG_THIS_RULE();
-    if (LA() == T_Q_ENUMS) {
-        QEnumDeclarationAST *ast = new (_pool)QEnumDeclarationAST;
-        ast->enum_specifier_token = consumeToken();
-        EnumeratorListAST** enumerator_list_ptr;
-        enumerator_list_ptr = &ast->enumerator_list;
+    if (LA() != T_Q_ENUMS)
+        return false;
 
-        if(LA() == T_LPAREN){
-            ast->lparen_token = consumeToken();
-            while(LA() != T_EOF_SYMBOL && LA() != T_RPAREN){
-                *enumerator_list_ptr = new (_pool) EnumeratorListAST;
-                EnumeratorAST *pdecl = new (_pool) EnumeratorAST;
-                pdecl->identifier_token = consumeToken();
-                (*enumerator_list_ptr)->value = pdecl;
-                enumerator_list_ptr = &(*enumerator_list_ptr)->next;
-                if (LA() == T_COMMA)
-                    consumeToken();
-            }
-            if(LA() == T_RPAREN)
-                ast->rparen_token = consumeToken();
-        }
-        node = ast;
-        return true;
+    QtEnumDeclarationAST *ast = new (_pool) QtEnumDeclarationAST;
+    ast->enum_specifier_token = consumeToken();
+    match(T_LPAREN, &ast->lparen_token);
+    for (NameListAST **iter = &ast->enumerator_list; LA() == T_IDENTIFIER; iter = &(*iter)->next) {
+        *iter = new (_pool) NameListAST;
+        SimpleNameAST *name = new (_pool) SimpleNameAST;
+        name->identifier_token = consumeToken();
+        (*iter)->value = name;
     }
-    return false;
+    match(T_RPAREN, &ast->rparen_token);
+    node = ast;
+    return true;
 }
 
+#ifdef ICHECK_BUILD
 bool Parser::parseQFlags(DeclarationAST *&node)
 {
-     /*Q_FLAGS(enum1 enum2 flags1)*/
+    /*Q_FLAGS(enum1 enum2 flags1)*/
     DEBUG_THIS_RULE();
     if (LA() == T_Q_FLAGS) {
         QFlagsDeclarationAST *ast = new (_pool)QFlagsDeclarationAST;
@@ -1934,13 +1990,13 @@ bool Parser::parseMemberSpecification(DeclarationAST *&node)
     case T_Q_SLOTS:
         return parseAccessDeclaration(node);
 
-#ifdef ICHECK_BUILD
     case T_Q_PROPERTY:
         return parseQPropertyDeclaration(node);
 
     case T_Q_ENUMS:
         return parseQEnumDeclaration(node);
 
+#ifdef ICHECK_BUILD
     case T_Q_FLAGS:
         return parseQFlags(node);
 
@@ -4496,17 +4552,17 @@ bool Parser::parseObjCClassForwardDeclaration(DeclarationAST *&node)
     unsigned identifier_token = 0;
     match(T_IDENTIFIER, &identifier_token);
 
-    ast->identifier_list = new (_pool) ObjCIdentifierListAST;
+    ast->identifier_list = new (_pool) NameListAST;
     SimpleNameAST *name = new (_pool) SimpleNameAST;
     name->identifier_token = identifier_token;
     ast->identifier_list->value = name;
-    ObjCIdentifierListAST **nextId = &ast->identifier_list->next;
+    NameListAST **nextId = &ast->identifier_list->next;
 
     while (LA() == T_COMMA) {
         consumeToken(); // consume T_COMMA
         match(T_IDENTIFIER, &identifier_token);
 
-        *nextId = new (_pool) ObjCIdentifierListAST;
+        *nextId = new (_pool) NameListAST;
         name = new (_pool) SimpleNameAST;
         name->identifier_token = identifier_token;
         (*nextId)->value = name;
@@ -4646,17 +4702,17 @@ bool Parser::parseObjCProtocol(DeclarationAST *&node,
         ObjCProtocolForwardDeclarationAST *ast = new (_pool) ObjCProtocolForwardDeclarationAST;
         ast->attribute_list = attributes;
         ast->protocol_token = protocol_token;
-        ast->identifier_list = new (_pool) ObjCIdentifierListAST;
+        ast->identifier_list = new (_pool) NameListAST;
         SimpleNameAST *name = new (_pool) SimpleNameAST;
         name->identifier_token = identifier_token;
         ast->identifier_list->value = name;
-        ObjCIdentifierListAST **nextId = &ast->identifier_list->next;
+        NameListAST **nextId = &ast->identifier_list->next;
 
         while (LA() == T_COMMA) {
             consumeToken(); // consume T_COMMA
             match(T_IDENTIFIER, &identifier_token);
 
-            *nextId = new (_pool) ObjCIdentifierListAST;
+            *nextId = new (_pool) NameListAST;
             name = new (_pool) SimpleNameAST;
             name->identifier_token = identifier_token;
             (*nextId)->value = name;
@@ -4810,16 +4866,16 @@ bool Parser::parseObjCMethodDefinitionList(DeclarationListAST *&node)
         case T_AT_DYNAMIC: {
             ObjCDynamicPropertiesDeclarationAST *ast = new (_pool) ObjCDynamicPropertiesDeclarationAST;
             ast->dynamic_token = consumeToken();
-            ast->property_identifier_list = new (_pool) ObjCIdentifierListAST;
+            ast->property_identifier_list = new (_pool) NameListAST;
             SimpleNameAST *name = new (_pool) SimpleNameAST;
             match(T_IDENTIFIER, &name->identifier_token);
             ast->property_identifier_list->value = name;
 
-            ObjCIdentifierListAST *last = ast->property_identifier_list;
+            NameListAST *last = ast->property_identifier_list;
             while (LA() == T_COMMA) {
                 consumeToken(); // consume T_COMMA
 
-                last->next = new (_pool) ObjCIdentifierListAST;
+                last->next = new (_pool) NameListAST;
                 last = last->next;
                 name = new (_pool) SimpleNameAST;
                 match(T_IDENTIFIER, &name->identifier_token);
@@ -4895,17 +4951,17 @@ bool Parser::parseObjCProtocolRefs(ObjCProtocolRefsAST *&node)
 
     unsigned identifier_token = 0;
     match(T_IDENTIFIER, &identifier_token);
-    ast->identifier_list = new (_pool) ObjCIdentifierListAST;
+    ast->identifier_list = new (_pool) NameListAST;
     SimpleNameAST *name = new (_pool) SimpleNameAST;
     name->identifier_token = identifier_token;
     ast->identifier_list->value = name;
-    ObjCIdentifierListAST **nextId = &ast->identifier_list->next;
+    NameListAST **nextId = &ast->identifier_list->next;
 
     while (LA() == T_COMMA) {
         consumeToken(); // consume T_COMMA
         match(T_IDENTIFIER, &identifier_token);
 
-        *nextId = new (_pool) ObjCIdentifierListAST;
+        *nextId = new (_pool) NameListAST;
         name = new (_pool) SimpleNameAST;
         name->identifier_token = identifier_token;
         (*nextId)->value = name;
@@ -5289,4 +5345,12 @@ bool Parser::parseObjCContextKeyword(int kind, unsigned &in_token)
     return true;
 }
 
+int Parser::peekAtQtContextKeyword() const
+{
+    DEBUG_THIS_RULE();
+    if (LA() != T_IDENTIFIER)
+        return false;
 
+    const Identifier *id = tok().identifier;
+    return classifyQtContextKeyword(id->chars(), id->size());
+}
diff --git a/src/shared/cplusplus/Parser.h b/src/shared/cplusplus/Parser.h
index c31b9c1e7fbf586922352db40c8a0077ae8f2636..ae4f338a6f324d3ec68f564528158d66cad4efc5 100644
--- a/src/shared/cplusplus/Parser.h
+++ b/src/shared/cplusplus/Parser.h
@@ -78,9 +78,10 @@ public:
     bool parseAbstractDeclarator(DeclaratorAST *&node);
     bool parseEmptyDeclaration(DeclarationAST *&node);
     bool parseAccessDeclaration(DeclarationAST *&node);
-#ifdef ICHECK_BUILD
     bool parseQPropertyDeclaration(DeclarationAST *&node);
+    bool matchBoolean(BoolLiteralAST *&node);
     bool parseQEnumDeclaration(DeclarationAST *&node);
+#ifdef ICHECK_BUILD
     bool parseQFlags(DeclarationAST *&node);
     bool parseQDeclareFlags(DeclarationAST *&node);
 #endif
@@ -274,6 +275,8 @@ public:
     bool maybeForwardOrClassDeclaration(SpecifierListAST *decl_specifier_seq) const;
     bool isPointerDeclaration(DeclarationStatementAST *ast) const;
 
+    int peekAtQtContextKeyword() const;
+
 private:
     bool switchTemplateArguments(bool templateArguments);
     bool blockErrors(bool block);
diff --git a/src/shared/cplusplus/QtContextKeywords.cpp b/src/shared/cplusplus/QtContextKeywords.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1b1ff8bb8c32add4d163c024cd21975ad8b91f63
--- /dev/null
+++ b/src/shared/cplusplus/QtContextKeywords.cpp
@@ -0,0 +1,199 @@
+/**************************************************************************
+**
+** 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 "QtContextKeywords.h"
+
+using namespace CPlusPlus;
+
+static inline int classify4(const char *s) {
+  if (s[0] == 'R') {
+    if (s[1] == 'E') {
+      if (s[2] == 'A') {
+        if (s[3] == 'D') {
+          return Token_READ;
+        }
+      }
+    }
+  }
+  else if (s[0] == 'U') {
+    if (s[1] == 'S') {
+      if (s[2] == 'E') {
+        if (s[3] == 'R') {
+          return Token_USER;
+        }
+      }
+    }
+  }
+  return Token_not_Qt_context_keyword;
+}
+
+static inline int classify5(const char *s) {
+  if (s[0] == 'F') {
+    if (s[1] == 'I') {
+      if (s[2] == 'N') {
+        if (s[3] == 'A') {
+          if (s[4] == 'L') {
+            return Token_FINAL;
+          }
+        }
+      }
+    }
+  }
+  else if (s[0] == 'R') {
+    if (s[1] == 'E') {
+      if (s[2] == 'S') {
+        if (s[3] == 'E') {
+          if (s[4] == 'T') {
+            return Token_RESET;
+          }
+        }
+      }
+    }
+  }
+  else if (s[0] == 'W') {
+    if (s[1] == 'R') {
+      if (s[2] == 'I') {
+        if (s[3] == 'T') {
+          if (s[4] == 'E') {
+            return Token_WRITE;
+          }
+        }
+      }
+    }
+  }
+  return Token_not_Qt_context_keyword;
+}
+
+static inline int classify6(const char *s) {
+  if (s[0] == 'N') {
+    if (s[1] == 'O') {
+      if (s[2] == 'T') {
+        if (s[3] == 'I') {
+          if (s[4] == 'F') {
+            if (s[5] == 'Y') {
+              return Token_NOTIFY;
+            }
+          }
+        }
+      }
+    }
+  }
+  else if (s[0] == 'S') {
+    if (s[1] == 'T') {
+      if (s[2] == 'O') {
+        if (s[3] == 'R') {
+          if (s[4] == 'E') {
+            if (s[5] == 'D') {
+              return Token_STORED;
+            }
+          }
+        }
+      }
+    }
+  }
+  return Token_not_Qt_context_keyword;
+}
+
+static inline int classify8(const char *s) {
+  if (s[0] == 'C') {
+    if (s[1] == 'O') {
+      if (s[2] == 'N') {
+        if (s[3] == 'S') {
+          if (s[4] == 'T') {
+            if (s[5] == 'A') {
+              if (s[6] == 'N') {
+                if (s[7] == 'T') {
+                  return Token_CONSTANT;
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  return Token_not_Qt_context_keyword;
+}
+
+static inline int classify10(const char *s) {
+  if (s[0] == 'D') {
+    if (s[1] == 'E') {
+      if (s[2] == 'S') {
+        if (s[3] == 'I') {
+          if (s[4] == 'G') {
+            if (s[0] == 'N') {
+              if (s[1] == 'A') {
+                if (s[2] == 'B') {
+                  if (s[3] == 'L') {
+                    if (s[4] == 'E') {
+                      return Token_DESIGNABLE;
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  else if (s[0] == 'S') {
+    if (s[1] == 'C') {
+      if (s[2] == 'R') {
+        if (s[3] == 'I') {
+          if (s[4] == 'P') {
+            if (s[0] == 'T') {
+              if (s[1] == 'A') {
+                if (s[2] == 'B') {
+                  if (s[3] == 'L') {
+                    if (s[4] == 'E') {
+                      return Token_SCRIPTABLE;
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  return Token_not_Qt_context_keyword;
+}
+
+int CPlusPlus::classifyQtContextKeyword(const char *s, int n) {
+  switch (n) {
+    case 4: return classify4(s);
+    case 5: return classify5(s);
+    case 6: return classify6(s);
+    case 8: return classify8(s);
+    case 10: return classify10(s);
+    default: return Token_not_Qt_context_keyword;
+  } // switch
+}
diff --git a/src/shared/cplusplus/QtContextKeywords.h b/src/shared/cplusplus/QtContextKeywords.h
new file mode 100644
index 0000000000000000000000000000000000000000..0633fad301ba6d821e5601bcf04996883c5d052b
--- /dev/null
+++ b/src/shared/cplusplus/QtContextKeywords.h
@@ -0,0 +1,54 @@
+/**************************************************************************
+**
+** 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 QTCONTEXTKEYWORDS_H
+#define QTCONTEXTKEYWORDS_H
+
+#include "CPlusPlusForwardDeclarations.h"
+
+namespace CPlusPlus {
+
+enum {
+    Token_not_Qt_context_keyword = 0,
+    Token_READ,
+    Token_USER,
+    Token_FINAL,
+    Token_RESET,
+    Token_WRITE,
+    Token_NOTIFY,
+    Token_STORED,
+    Token_CONSTANT,
+    Token_DESIGNABLE,
+    Token_SCRIPTABLE
+};
+
+CPLUSPLUS_EXPORT int classifyQtContextKeyword(const char *s, int n);
+} // namespace CPlusPlus;
+
+#endif // QTCONTEXTKEYWORDS_H
diff --git a/src/shared/cplusplus/cplusplus.pri b/src/shared/cplusplus/cplusplus.pri
index 1634115e2301a12ff1c69c8e281609bd30bdded3..e13ff4a278c38143d4848cf8c2a0b4589da6ed6a 100644
--- a/src/shared/cplusplus/cplusplus.pri
+++ b/src/shared/cplusplus/cplusplus.pri
@@ -39,7 +39,8 @@ HEADERS += \
     $$PWD/TranslationUnit.h \
     $$PWD/Type.h \
     $$PWD/TypeVisitor.h \
-    $$PWD/ObjectiveCTypeQualifiers.h
+    $$PWD/ObjectiveCTypeQualifiers.h \
+    $$PWD/QtContextKeywords.h
 
 SOURCES += \
     $$PWD/AST.cpp \
@@ -81,6 +82,5 @@ SOURCES += \
     $$PWD/Token.cpp \
     $$PWD/TranslationUnit.cpp \
     $$PWD/Type.cpp \
-    $$PWD/TypeVisitor.cpp
-
-
+    $$PWD/TypeVisitor.cpp \
+    $$PWD/QtContextKeywords.cpp