diff --git a/shared/cplusplus/Lexer.cpp b/shared/cplusplus/Lexer.cpp
index fcc17313b4308908b77d49e3ca029f2c4e99f9cc..1f4a0f51751001f0937744391f5632299b824006 100644
--- a/shared/cplusplus/Lexer.cpp
+++ b/shared/cplusplus/Lexer.cpp
@@ -122,11 +122,11 @@ bool Lexer::qtMocRunEnabled() const
 void Lexer::setQtMocRunEnabled(bool onoff)
 { _qtMocRunEnabled = onoff; }
 
-bool Lexer::objcEnabled() const
-{ return _objcEnabled; }
+bool Lexer::objCEnabled() const
+{ return _objCEnabled; }
 
-void Lexer::setObjcEnabled(bool onoff)
-{ _objcEnabled = onoff; }
+void Lexer::setObjCEnabled(bool onoff)
+{ _objCEnabled = onoff; }
 
 bool Lexer::isIncremental() const
 { return _isIncremental; }
@@ -554,7 +554,7 @@ void Lexer::scan_helper(Token *tok)
         break;
 
     default: {
-        if (_objcEnabled) {
+        if (_objCEnabled) {
             if (ch == '@' && _yychar >= 'a' && _yychar <= 'z') {
                 const char *yytext = _currentChar;
 
diff --git a/shared/cplusplus/Lexer.h b/shared/cplusplus/Lexer.h
index 84fa41073635a03157dad0b92d435f67701e8788..b6e361d3da78f7de2ec1563ad7d1284ac96bf391 100644
--- a/shared/cplusplus/Lexer.h
+++ b/shared/cplusplus/Lexer.h
@@ -80,8 +80,8 @@ public:
     bool qtMocRunEnabled() const;
     void setQtMocRunEnabled(bool onoff);
 
-    bool objcEnabled() const;
-    void setObjcEnabled(bool onoff);
+    bool objCEnabled() const;
+    void setObjCEnabled(bool onoff);
 
     void scan(Token *tok);
 
@@ -147,7 +147,7 @@ private:
             unsigned _scanKeywords: 1;
             unsigned _scanAngleStringLiteralTokens: 1;
             unsigned _qtMocRunEnabled: 1;
-            unsigned _objcEnabled: 1;
+            unsigned _objCEnabled: 1;
         };
     };
     unsigned _currentLine;
diff --git a/shared/cplusplus/Parser.cpp b/shared/cplusplus/Parser.cpp
index 67fed9e011867da2eebe56f22c1d205560153396..faa0801250e9e7610aa541d9dfd6f11164672e09 100644
--- a/shared/cplusplus/Parser.cpp
+++ b/shared/cplusplus/Parser.cpp
@@ -68,8 +68,9 @@ Parser::Parser(TranslationUnit *unit)
       _tokenIndex(1),
       _templateArguments(0),
       _qtMocRunEnabled(false),
-      _objcEnabled(false),
-      _inFunctionBody(false)
+      _objCEnabled(false),
+      _inFunctionBody(false),
+      _inObjCImplementationContext(false)
 { }
 
 Parser::~Parser()
@@ -81,6 +82,12 @@ bool Parser::qtMocRunEnabled() const
 void Parser::setQtMocRunEnabled(bool onoff)
 { _qtMocRunEnabled = onoff; }
 
+bool Parser::objCEnabled() const
+{ return _objCEnabled; }
+
+void Parser::setObjCEnabled(bool onoff)
+{ _objCEnabled = onoff; }
+
 bool Parser::switchTemplateArguments(bool templateArguments)
 {
     bool previousTemplateArguments = _templateArguments;
@@ -397,6 +404,9 @@ bool Parser::parseDeclaration(DeclarationAST *&node)
         return parseTemplateDeclaration(node);
 
     // objc++
+    case T_AT_IMPLEMENTATION:
+        return parseObjCClassImplementation(node);
+
     case T_AT_CLASS:
         return parseObjCClassDeclaration(node);
 
@@ -406,8 +416,8 @@ bool Parser::parseDeclaration(DeclarationAST *&node)
     case T_AT_PROTOCOL:
         return parseObjCProtocolDeclaration(node);
 
-//    case T_AT_END:
-//        return parseObjCEndDeclaration(node);
+    case T_AT_END:
+        return parseObjCEndDeclaration(node);
 
     case T_AT_COMPATIBILITY_ALIAS:
         return parseObjCAliasDeclaration(node);
@@ -2540,7 +2550,7 @@ bool Parser::parsePrimaryExpression(ExpressionAST *&node)
         return parseObjCExpression(node);
 
     default: {
-        if (_objcEnabled && LA() == T_LBRACKET)
+        if (_objCEnabled && LA() == T_LBRACKET)
             return parseObjCExpression(node);
 
         unsigned startOfName = cursor();
@@ -3293,6 +3303,33 @@ bool Parser::parseThrowExpression(ExpressionAST *&node)
     return false;
 }
 
+bool Parser::parseObjCClassImplementation(DeclarationAST *&node)
+{
+    if (LA() != T_AT_IMPLEMENTATION)
+        return false;
+
+    unsigned implementation_token = consumeToken();
+    unsigned identifier_token = 0;
+    match(T_IDENTIFIER, &identifier_token);
+
+    if (LA() == T_COLON) {
+        unsigned colon_token = consumeToken();
+        unsigned superclass_name_token = 0;
+        match(T_IDENTIFIER, &superclass_name_token);
+    } else if (LA() == T_LPAREN) {
+        unsigned lparen_token = consumeToken();
+        unsigned category_name_token = 0;
+        if (LA() == T_IDENTIFIER)
+            category_name_token = consumeToken();
+        unsigned rparen_token = 0;
+        match(T_RPAREN, &rparen_token);
+    }
+
+    _inObjCImplementationContext = true;
+    parseObjCMethodDefinitionList();
+    return true;
+}
+
 bool Parser::parseObjCClassDeclaration(DeclarationAST *&node)
 {
     if (LA() != T_AT_CLASS)
@@ -3352,7 +3389,18 @@ bool Parser::parseObjCProtocolDeclaration(DeclarationAST *&)
 
 bool Parser::parseObjCEndDeclaration(DeclarationAST *&)
 {
-    return false;
+    if (LA() != T_AT_END)
+        return false;
+
+    unsigned end_token = consumeToken();
+
+    if (! _inObjCImplementationContext) {
+        _translationUnit->warning(end_token,
+            "@end must appear in an @implementation context");
+    }
+
+    _inObjCImplementationContext = false;
+    return true;
 }
 
 bool Parser::parseObjCAliasDeclaration(DeclarationAST *&)
@@ -3589,4 +3637,179 @@ bool Parser::parseObjCMessageArguments()
     return true;
 }
 
+bool Parser::parseObjCMethodDefinitionList()
+{
+    bool done = false;
+    while (! done) {
+        switch (LA()) {
+        case T_EOF_SYMBOL:
+        case T_AT_END:
+            done = true;
+            break;
+
+        case T_PLUS:
+        case T_MINUS:
+            parseObjCMethodSignature();
+            if (LA() == T_SEMICOLON)
+                consumeToken();
+            break;
+
+        case T_AT_PROPERTY:
+            parseObjCAtProperty();
+            break;
+
+        case T_SEMICOLON:
+            consumeToken();
+            break;
+
+        case T_AT_OPTIONAL:
+            consumeToken();
+            break;
+
+        case T_AT_REQUIRED:
+            consumeToken();
+            break;
+
+        case T_TEMPLATE:
+        case T_NAMESPACE: {
+            DeclarationAST *declaration = 0;
+            parseDeclaration(declaration);
+        }   break;
+
+        default: {
+            unsigned start = cursor();
+            DeclarationAST *declaration = 0;
+            if (LA(1) == T_EXTERN && LA(2) == T_STRING_LITERAL) {
+                parseLinkageSpecification(declaration);
+            } else if (parseBlockDeclaration(declaration)) {
+                // ### accept the declaration.
+            } else {
+                if (cursor() == start) {
+                    _translationUnit->error(cursor(),
+                            "stray `%s' between Objective-C++ methods",
+                            tok().spell());
+                    consumeToken();
+                }
+            }
+        }   break; // default
+
+        } // switch
+    }
+
+    return true;
+}
+
+bool Parser::parseObjCMethodSignature()
+{
+    if (LA() != T_PLUS && LA() != T_MINUS)
+        return false;
+
+    unsigned method_type_token = consumeToken();
+    parseObjCTypeName();
+
+    bool first = true;
+
+    while (lookAtObjCSelector() || LA() == T_COLON) {
+        if (LA() != T_COLON)
+            /*selector_name_token = */ consumeToken();
+
+        SpecifierAST *attributes = 0, **attr = &attributes;
+        while (parseAttributeSpecifier(*attr))
+            attr = &(*attr)->next;
+
+        if (first) {
+            first = false;
+
+            if (LA() != T_COLON)
+                break;
+        }
+
+        unsigned colon_token = 0;
+        match(T_COLON, &colon_token);
+
+        parseObjCTypeName();
+
+        unsigned identifier_token = 0;
+        match(T_IDENTIFIER, &identifier_token);
+
+        while (parseAttributeSpecifier(*attr))
+            attr = &(*attr)->next;
+    }
+
+    // parse the method tail parameters.
+    while (LA() == T_COMMA) {
+        consumeToken();
+
+        if (LA() == T_DOT_DOT_DOT) {
+            consumeToken();
+            break;
+        }
+
+        DeclarationAST *parameter_declaration = 0;
+        parseParameterDeclaration(parameter_declaration);
+    }
+
+    return true;
+}
+
+bool Parser::parseObjCTypeName()
+{
+    if (LA() != T_LPAREN)
+        return false;
+
+    /*unsigned lparen_token = */ consumeToken();
+
+    parseObjCProtocolQualifiers();
+
+    ExpressionAST *type_id = 0;
+    if (LA() != T_RPAREN)
+        parseTypeId(type_id);
+
+    SpecifierAST *attributes = 0, **attr = &attributes;
+    while (parseAttributeSpecifier(*attr))
+        attr = &(*attr)->next;
+
+    unsigned rparen_token = 0;
+    match(T_RPAREN, &rparen_token);
+    return true;
+}
+
+bool Parser::parseObjCAtProperty()
+{
+    if (LA() != T_AT_PROPERTY)
+        return false;
+
+    /*unsigned property_token = */ consumeToken();
+    return true;
+}
+
+bool Parser::parseObjCProtocolQualifiers()
+{
+    return false;
+}
+
+bool Parser::lookAtObjCSelector() const
+{
+    switch (LA()) {
+    case T_IDENTIFIER:
+    case T_OR:
+    case T_AND:
+    case T_NOT:
+    case T_XOR:
+    case T_BITOR:
+    case T_COMPL:
+    case T_OR_EQ:
+    case T_AND_EQ:
+    case T_BITAND:
+    case T_NOT_EQ:
+    case T_XOR_EQ:
+        return true;
+
+    default:
+        if (tok().isKeyword())
+            return true;
+    } // switch
+
+    return false;
+}
 CPLUSPLUS_END_NAMESPACE
diff --git a/shared/cplusplus/Parser.h b/shared/cplusplus/Parser.h
index 8bde1cccc46599e1a75c8d0ca7b717b78c856c54..c943664afe1b6428e511bce4e13f52ee146bb7c0 100644
--- a/shared/cplusplus/Parser.h
+++ b/shared/cplusplus/Parser.h
@@ -70,6 +70,9 @@ public:
     bool qtMocRunEnabled() const;
     void setQtMocRunEnabled(bool onoff);
 
+    bool objCEnabled() const;
+    void setObjCEnabled(bool onoff);
+
     bool parseTranslationUnit(TranslationUnitAST *&node);
 
 public:
@@ -204,6 +207,7 @@ public:
     bool parseWhileStatement(StatementAST *&node);
 
     // ObjC++
+    bool parseObjCClassImplementation(DeclarationAST *&node);
     bool parseObjCClassDeclaration(DeclarationAST *&node);
     bool parseObjCInterfaceDeclaration(DeclarationAST *&node);
     bool parseObjCProtocolDeclaration(DeclarationAST *&node);
@@ -231,6 +235,14 @@ public:
     bool parseObjCMessageReceiver(ExpressionAST *&node);
     bool parseObjCMessageArguments();
 
+    bool parseObjCMethodSignature();
+    bool parseObjCMethodDefinitionList();
+    bool parseObjCAtProperty();
+    bool parseObjCTypeName();
+    bool parseObjCProtocolQualifiers();
+
+    bool lookAtObjCSelector() const;
+
     // Qt MOC run
     bool parseQtMethod(ExpressionAST *&node);
 
@@ -277,8 +289,9 @@ private:
     unsigned _tokenIndex;
     bool _templateArguments: 1;
     bool _qtMocRunEnabled: 1;
-    bool _objcEnabled: 1;
+    bool _objCEnabled: 1;
     bool _inFunctionBody: 1;
+    bool _inObjCImplementationContext: 1;
 
 private:
     Parser(const Parser& source);
diff --git a/shared/cplusplus/TranslationUnit.cpp b/shared/cplusplus/TranslationUnit.cpp
index c64bbf52c15ecf4b7e57aa1b3773ae49b84bde51..caaa9c7d4e709062517f790806e3d73609e21d90 100644
--- a/shared/cplusplus/TranslationUnit.cpp
+++ b/shared/cplusplus/TranslationUnit.cpp
@@ -92,6 +92,12 @@ bool TranslationUnit::qtMocRunEnabled() const
 void TranslationUnit::setQtMocRunEnabled(bool onoff)
 { _qtMocRunEnabled = onoff; }
 
+bool TranslationUnit::objCEnabled() const
+{ return _objCEnabled; }
+
+void TranslationUnit::setObjCEnabled(bool onoff)
+{ _objCEnabled = onoff; }
+
 Control *TranslationUnit::control() const
 { return _control; }
 
@@ -164,6 +170,7 @@ void TranslationUnit::tokenize()
 
     Lexer lex(this);
     lex.setQtMocRunEnabled(_qtMocRunEnabled);
+    lex.setObjCEnabled(_objCEnabled);
 
     std::stack<unsigned> braces;
     _tokens->push_back(Token()); // the first token needs to be invalid!
@@ -228,6 +235,7 @@ bool TranslationUnit::parse(ParseMode mode)
 
     Parser parser(this);
     parser.setQtMocRunEnabled(_qtMocRunEnabled);
+    parser.setObjCEnabled(_objCEnabled);
 
     bool parsed = false;
 
diff --git a/shared/cplusplus/TranslationUnit.h b/shared/cplusplus/TranslationUnit.h
index 9e71b1a8ee6d7c66a27352c5d8aad435a6132f42..ada079ff48447b0171bc2e709f838359ef12ceed 100644
--- a/shared/cplusplus/TranslationUnit.h
+++ b/shared/cplusplus/TranslationUnit.h
@@ -102,6 +102,9 @@ public:
     bool qtMocRunEnabled() const;
     void setQtMocRunEnabled(bool onoff);
 
+    bool objCEnabled() const;
+    void setObjCEnabled(bool onoff);
+
     void warning(unsigned index, const char *fmt, ...);
     void error(unsigned index, const char *fmt, ...);
     void fatal(unsigned index, const char *fmt, ...);
@@ -187,6 +190,7 @@ private:
             unsigned _blockErrors: 1;
             unsigned _skipFunctionBody: 1;
             unsigned _qtMocRunEnabled: 1;
+            unsigned _objCEnabled: 1;
         };
     };
 };
diff --git a/src/libs/cplusplus/SimpleLexer.cpp b/src/libs/cplusplus/SimpleLexer.cpp
index 583f45da3892d8d3121008c88c1741c0380fa0cf..440946cdb38256cc9ff99d46d0f46100cf083d82 100644
--- a/src/libs/cplusplus/SimpleLexer.cpp
+++ b/src/libs/cplusplus/SimpleLexer.cpp
@@ -58,7 +58,7 @@ SimpleLexer::SimpleLexer()
     : _lastState(0),
       _skipComments(false),
       _qtMocRunEnabled(true),
-      _objcEnabled(false)
+      _objCEnabled(false)
 { }
 
 SimpleLexer::~SimpleLexer()
@@ -74,15 +74,14 @@ void SimpleLexer::setQtMocRunEnabled(bool enabled)
     _qtMocRunEnabled = enabled;
 }
 
-
-bool SimpleLexer::objcEnabled() const
+bool SimpleLexer::objCEnabled() const
 {
-    return _objcEnabled;
+    return _objCEnabled;
 }
 
-void SimpleLexer::setObjcEnabled(bool onoff)
+void SimpleLexer::setObjCEnabled(bool onoff)
 {
-    _objcEnabled = onoff;
+    _objCEnabled = onoff;
 }
 
 bool SimpleLexer::skipComments() const
@@ -105,7 +104,7 @@ QList<SimpleToken> SimpleLexer::operator()(const QString &text, int state)
 
     Lexer lex(firstChar, lastChar);
     lex.setQtMocRunEnabled(_qtMocRunEnabled);
-    lex.setObjcEnabled(_objcEnabled);
+    lex.setObjCEnabled(_objCEnabled);
 
     if (! _skipComments)
         lex.setScanCommentTokens(true);
diff --git a/src/libs/cplusplus/SimpleLexer.h b/src/libs/cplusplus/SimpleLexer.h
index fb64a66c0333b71c07ae88006991e2262378ffe2..3f5b736e2dd8d2713e82572c206291ce4df0c733 100644
--- a/src/libs/cplusplus/SimpleLexer.h
+++ b/src/libs/cplusplus/SimpleLexer.h
@@ -91,8 +91,8 @@ public:
     bool qtMocRunEnabled() const;
     void setQtMocRunEnabled(bool enabled);
 
-    bool objcEnabled() const;
-    void setObjcEnabled(bool onoff);
+    bool objCEnabled() const;
+    void setObjCEnabled(bool onoff);
 
     QList<SimpleToken> operator()(const QString &text, int state = 0);
 
@@ -103,7 +103,7 @@ private:
     int _lastState;
     bool _skipComments: 1;
     bool _qtMocRunEnabled: 1;
-    bool _objcEnabled: 1;
+    bool _objCEnabled: 1;
 };
 
 } // end of namespace CPlusPlus