diff --git a/src/libs/clangbackendipc/clangbackendipc_global.h b/src/libs/clangbackendipc/clangbackendipc_global.h
index 544a5b15ac11c56b59065af32480f0033b6f60a5..c9851069b58e43282a0ee73e312f47f3e699442a 100644
--- a/src/libs/clangbackendipc/clangbackendipc_global.h
+++ b/src/libs/clangbackendipc/clangbackendipc_global.h
@@ -53,5 +53,28 @@ enum class DiagnosticSeverity // one to one mapping of the clang enum numbers
     Error = 3,
     Fatal = 4
 };
+
+enum class HighlightingType
+{
+    Invalid,
+    Keyword,
+    StringLiteral,
+    NumberLiteral,
+    Comment,
+    Function,
+    VirtualFunction,
+    Type,
+    LocalVariable,
+    Field,
+    GlobalVariable,
+    Enumeration,
+    Operator,
+    Preprocessor,
+    PreprocessorDefinition,
+    PreprocessorExpansion,
+    Label,
+    OutputArgument
+};
+
 }
 #endif // CLANGBACKENDIPC_GLOBAL_H
diff --git a/src/libs/sqlite/utf8string.cpp b/src/libs/sqlite/utf8string.cpp
index b4492a9d198404ad447f02c70d56649d6b2f05b8..c8cbaea22302f1b17074daa665e23247d414bf56 100644
--- a/src/libs/sqlite/utf8string.cpp
+++ b/src/libs/sqlite/utf8string.cpp
@@ -158,6 +158,11 @@ bool Utf8String::endsWith(const Utf8String &text) const
     return byteArray.endsWith(text.byteArray);
 }
 
+bool Utf8String::isNull() const
+{
+    return byteArray.isNull();
+}
+
 bool Utf8String::isEmpty() const
 {
     return byteArray.isEmpty();
diff --git a/src/libs/sqlite/utf8string.h b/src/libs/sqlite/utf8string.h
index 52c6f46758bc89953b1bccbc3c7d9ba72e4cf775..c6adfc9371626337fd97d6e85266f673bcec889c 100644
--- a/src/libs/sqlite/utf8string.h
+++ b/src/libs/sqlite/utf8string.h
@@ -86,6 +86,7 @@ public:
     bool startsWith(const char *text) const;
     bool startsWith(char character) const;
     bool endsWith(const Utf8String &text) const;
+    bool isNull() const;
     bool isEmpty() const;
     bool hasContent() const;
 
diff --git a/src/tools/clangbackend/ipcsource/clangbackendclangipc-source.pri b/src/tools/clangbackend/ipcsource/clangbackendclangipc-source.pri
index 73aa363a95908410d5754e8f165fd0487dab6c13..93131082bf9087177c135290e4a310128dfd0617 100644
--- a/src/tools/clangbackend/ipcsource/clangbackendclangipc-source.pri
+++ b/src/tools/clangbackend/ipcsource/clangbackendclangipc-source.pri
@@ -25,7 +25,13 @@ HEADERS += $$PWD/clangipcserver.h \
     $$PWD/diagnosticsetiterator.h \
     $$PWD/clangfilesystemwatcher.h \
     $$PWD/translationunitalreadyexistsexception.h \
-    $$PWD/commandlinearguments.h
+    $$PWD/commandlinearguments.h \
+    $$PWD/cursor.h \
+    $$PWD/type.h \
+    $$PWD/highlightinginformations.h \
+    $$PWD/highlightinginformation.h \
+    $$PWD/highlightinginformationsiterator.h \
+    $$PWD/skippedsourceranges.h
 
 SOURCES += $$PWD/clangipcserver.cpp \
     $$PWD/codecompleter.cpp \
@@ -51,4 +57,9 @@ SOURCES += $$PWD/clangipcserver.cpp \
     $$PWD/fixit.cpp \
     $$PWD/clangfilesystemwatcher.cpp \
     $$PWD/translationunitalreadyexistsexception.cpp \
-    $$PWD/commandlinearguments.cpp
+    $$PWD/commandlinearguments.cpp \
+    $$PWD/cursor.cpp \
+    $$PWD/type.cpp \
+    $$PWD/highlightinginformations.cpp \
+    $$PWD/highlightinginformation.cpp \
+    $$PWD/skippedsourceranges.cpp
diff --git a/src/tools/clangbackend/ipcsource/clangstring.cpp b/src/tools/clangbackend/ipcsource/clangstring.cpp
index 200e83427066d8b3c344fd0e7330509a65790d74..5decaf15490a9bc4ebbc0f705167a6ab4993d1bb 100644
--- a/src/tools/clangbackend/ipcsource/clangstring.cpp
+++ b/src/tools/clangbackend/ipcsource/clangstring.cpp
@@ -61,6 +61,11 @@ ClangString &ClangString::operator=(ClangString &&other)
     return *this;
 }
 
+const char *ClangString::cString() const
+{
+    return clang_getCString(cxString);
+}
+
 ClangString::ClangString(ClangString &&other)
     : cxString(std::move(other.cxString))
 {
@@ -70,7 +75,7 @@ ClangString::ClangString(ClangString &&other)
 
 ClangString::operator Utf8String() const
 {
-    return Utf8String(clang_getCString(cxString), -1);
+    return Utf8String(cString(), -1);
 }
 
 } // namespace ClangBackEnd
diff --git a/src/tools/clangbackend/ipcsource/clangstring.h b/src/tools/clangbackend/ipcsource/clangstring.h
index f18a61228219a98167f53235281766ba40555a8b..2db7b8ade0c705dc1217b1a9200160c456abf9e9 100644
--- a/src/tools/clangbackend/ipcsource/clangstring.h
+++ b/src/tools/clangbackend/ipcsource/clangstring.h
@@ -51,6 +51,8 @@ public:
 
     operator Utf8String() const;
 
+    const char *cString() const;
+
     bool isNull() const;
 
 private:
diff --git a/src/tools/clangbackend/ipcsource/cursor.cpp b/src/tools/clangbackend/ipcsource/cursor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7ea5009d4df78cd2d331714be1acb566e07115ce
--- /dev/null
+++ b/src/tools/clangbackend/ipcsource/cursor.cpp
@@ -0,0 +1,351 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company.  For licensing terms and
+** conditions see http://www.qt.io/terms-conditions.  For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights.  These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "cursor.h"
+
+#include "clangstring.h"
+#include "sourcelocation.h"
+#include "sourcerange.h"
+
+#include <ostream>
+
+namespace ClangBackEnd {
+
+Cursor::Cursor()
+    : cxCursor(clang_getNullCursor())
+{
+}
+
+Cursor::Cursor(CXCursor cxCursor)
+    : cxCursor(cxCursor)
+{
+}
+
+bool Cursor::isNull() const
+{
+    return clang_Cursor_isNull(cxCursor);
+}
+
+bool Cursor::isValid() const
+{
+    return !clang_isInvalid(kind());
+}
+
+bool Cursor::isTranslationUnit() const
+{
+    return clang_isTranslationUnit(kind());
+}
+
+bool Cursor::isDefinition() const
+{
+    return clang_isCursorDefinition(cxCursor);
+}
+
+bool Cursor::isDynamicCall() const
+{
+    return clang_Cursor_isDynamicCall(cxCursor);
+}
+
+bool Cursor::isVirtualMethod() const
+{
+    return clang_CXXMethod_isVirtual(cxCursor);
+}
+
+bool Cursor::isPureVirtualMethod() const
+{
+    return clang_CXXMethod_isPureVirtual(cxCursor);
+}
+
+bool Cursor::isConstantMethod() const
+{
+    return clang_CXXMethod_isConst(cxCursor);
+}
+
+bool Cursor::isStaticMethod() const
+{
+    return clang_CXXMethod_isStatic(cxCursor);
+}
+
+bool Cursor::isCompoundType() const
+{
+    switch (kind()) {
+        case CXCursor_ClassDecl:
+        case CXCursor_StructDecl:
+        case CXCursor_UnionDecl: return true;
+        default: return false;
+    }
+}
+
+bool Cursor::isDeclaration() const
+{
+    return clang_isDeclaration(kind());
+}
+
+bool Cursor::isLocalVariable() const
+{
+    switch (semanticParent().kind()) {
+        case CXCursor_FunctionDecl:
+        case CXCursor_CXXMethod:
+        case CXCursor_Constructor:
+        case CXCursor_Destructor:
+        case CXCursor_ConversionFunction:
+        case CXCursor_FunctionTemplate:
+        case CXCursor_ObjCInstanceMethodDecl: return true;
+        default:
+            return false;
+    }
+}
+
+bool Cursor::hasFinalFunctionAttribute() const
+{
+    bool hasFinal = false;
+
+    visit([&] (Cursor cursor, Cursor /*parent*/) {
+        if (cursor.kind() == CXCursor_CXXFinalAttr) {
+            hasFinal = true;
+            return CXChildVisit_Break;
+        } else {
+            return CXChildVisit_Recurse;
+        }
+    });
+
+    return hasFinal;
+}
+
+bool Cursor::hasFinalClassAttribute() const
+{
+      bool hasFinal = false;
+
+      visit([&] (Cursor cursor, Cursor /*parent*/) {
+          switch (cursor.kind()) {
+              case CXCursor_CXXFinalAttr:
+                  hasFinal = true;
+                  return CXChildVisit_Break;
+              case CXCursor_CXXMethod:
+                  return CXChildVisit_Break;
+              default:
+                  return CXChildVisit_Recurse;
+          }
+      });
+
+      return hasFinal;
+}
+
+bool Cursor::isUnexposed() const
+{
+    return clang_isUnexposed(kind());
+}
+
+Utf8String Cursor::unifiedSymbolResolution() const
+{
+    return ClangString(clang_getCursorUSR(cxCursor));
+}
+
+Utf8String Cursor::mangling() const
+{
+    return ClangString(clang_Cursor_getMangling(cxCursor));
+}
+
+ClangString Cursor::spelling() const
+{
+    return ClangString(clang_getCursorSpelling(cxCursor));
+}
+
+Utf8String Cursor::displayName() const
+{
+    return ClangString(clang_getCursorDisplayName(cxCursor));
+}
+
+Utf8String Cursor::briefComment() const
+{
+    return ClangString(clang_Cursor_getBriefCommentText(cxCursor));
+}
+
+Utf8String Cursor::rawComment() const
+{
+    return ClangString(clang_Cursor_getRawCommentText(cxCursor));
+}
+
+int Cursor::argumentCount() const
+{
+    return clang_Cursor_getNumArguments(cxCursor);
+}
+
+Type Cursor::type() const
+{
+    return clang_getCursorType(cxCursor);
+}
+
+Type Cursor::nonPointerTupe() const
+{
+    auto typeResult = type();
+
+    if (typeResult.isPointer())
+        typeResult = typeResult.pointeeType();
+
+    return typeResult;
+}
+
+SourceLocation Cursor::sourceLocation() const
+{
+    return clang_getCursorLocation(cxCursor);
+}
+
+SourceRange Cursor::sourceRange() const
+{
+    return clang_getCursorExtent(cxCursor);
+}
+
+SourceRange Cursor::commentRange() const
+{
+    return clang_Cursor_getCommentRange(cxCursor);
+}
+
+Cursor Cursor::definition() const
+{
+    return clang_getCursorDefinition(cxCursor);
+}
+
+Cursor Cursor::canonical() const
+{
+    return clang_getCanonicalCursor(cxCursor);
+}
+
+Cursor Cursor::referenced() const
+{
+    return clang_getCursorReferenced(cxCursor);
+}
+
+Cursor Cursor::semanticParent() const
+{
+    return clang_getCursorSemanticParent(cxCursor);
+}
+
+Cursor Cursor::lexicalParent() const
+{
+    return clang_getCursorLexicalParent(cxCursor);
+}
+
+Cursor Cursor::functionBaseDeclaration() const
+{
+    auto functionBaseCursor = functionBase();
+
+    if (functionBaseCursor.isValid())
+        return functionBaseCursor.nonPointerTupe().canonical().declaration();
+    else
+        return semanticParent().semanticParent();
+}
+
+Cursor Cursor::functionBase() const
+{
+    Cursor functionBaseCursor;
+
+    visit([&] (Cursor cursor, Cursor /*parentCursor*/) {
+        switch (cursor.kind()) {
+            case CXCursor_DeclRefExpr:
+                functionBaseCursor = cursor;                                                       ;
+                return CXChildVisit_Break;
+            default:
+                 return CXChildVisit_Recurse;
+        }
+    });
+
+    return functionBaseCursor;
+}
+
+Cursor Cursor::argument(int index) const
+{
+    return clang_Cursor_getArgument(cxCursor, index);
+}
+namespace {
+void collectOutputArguments(const Cursor &callExpression,
+                            std::vector<Cursor> &outputArguments)
+{
+    auto callExpressionType = callExpression.referenced().type();
+    auto argumentCount = callExpression.argumentCount();
+    outputArguments.reserve(argumentCount);
+
+    for (int argumentIndex = 0; argumentIndex < argumentCount; ++argumentIndex) {
+        auto argument = callExpression.argument(argumentIndex);
+        auto argumentType = callExpressionType.argument(argumentIndex);
+
+        if (!argument.isUnexposed() && argumentType.isOutputParameter())
+            outputArguments.push_back(callExpression.argument(argumentIndex));
+    }
+}
+}
+
+std::vector<Cursor> Cursor::outputArguments() const
+{
+    std::vector<Cursor> outputArguments;
+
+    if (kind() == CXCursor_CallExpr)
+        collectOutputArguments(*this, outputArguments);
+
+    return outputArguments;
+}
+
+CXCursorKind Cursor::kind() const
+{
+    return clang_getCursorKind(cxCursor);
+}
+
+bool operator==(const Cursor &first, const Cursor &second)
+{
+    return clang_equalCursors(first.cxCursor, second.cxCursor);
+}
+
+void PrintTo(CXCursorKind cursorKind, ::std::ostream *os)
+{
+    ClangString cursorKindSpelling(clang_getCursorKindSpelling(cursorKind));
+    *os << cursorKindSpelling.cString();
+}
+
+void PrintTo(const Cursor &cursor, ::std::ostream*os)
+{
+    if (cursor.isValid()) {
+        ClangString cursorKindSpelling(clang_getCursorKindSpelling(cursor.kind()));
+        *os << cursorKindSpelling.cString() << " ";
+
+        auto identifier = cursor.displayName();
+        if (identifier.hasContent()) {
+            *os  << "\""
+                 << identifier.constData()
+                 << "\": ";
+        }
+
+        PrintTo(cursor.sourceLocation(), os);
+    } else {
+        *os << "Invalid cursor!";
+    }
+}
+
+} // namespace ClangBackEnd
+
diff --git a/src/tools/clangbackend/ipcsource/cursor.h b/src/tools/clangbackend/ipcsource/cursor.h
new file mode 100644
index 0000000000000000000000000000000000000000..d4256401e5d419f4a96c502246db0e0860366eee
--- /dev/null
+++ b/src/tools/clangbackend/ipcsource/cursor.h
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company.  For licensing terms and
+** conditions see http://www.qt.io/terms-conditions.  For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights.  These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef CLANGBACKEND_CURSOR_H
+#define CLANGBACKEND_CURSOR_H
+
+#include "type.h"
+
+#include <clang-c/Index.h>
+
+#include <iosfwd>
+
+#include <vector>
+
+class Utf8String;
+
+namespace ClangBackEnd {
+
+class SourceLocation;
+class SourceRange;
+class ClangString;
+
+class Cursor
+{
+    friend class Type;
+    friend bool operator==(const Cursor &first, const Cursor &second);
+public:
+    Cursor();
+    Cursor(CXCursor cxCursor);
+
+    bool isNull() const;
+    bool isValid() const;
+
+    bool isTranslationUnit() const;
+    bool isDefinition() const;
+    bool isDynamicCall() const;
+    bool isVirtualMethod() const;
+    bool isPureVirtualMethod() const;
+    bool isConstantMethod() const;
+    bool isStaticMethod() const;
+    bool isCompoundType() const;
+    bool isDeclaration() const;
+    bool isLocalVariable() const;
+    bool hasFinalFunctionAttribute() const;
+    bool hasFinalClassAttribute() const;
+    bool isUnexposed() const;
+
+    Utf8String unifiedSymbolResolution() const;
+    Utf8String mangling() const;
+    ClangString spelling() const;
+    Utf8String displayName() const;
+    Utf8String briefComment() const;
+    Utf8String rawComment() const;
+    int argumentCount() const;
+
+    Type type() const;
+    Type nonPointerTupe() const;
+
+    SourceLocation sourceLocation() const;
+    SourceRange sourceRange() const;
+    SourceRange commentRange() const;
+
+    Cursor definition() const;
+    Cursor canonical() const;
+    Cursor alias() const;
+    Cursor referenced() const;
+    Cursor semanticParent() const;
+    Cursor lexicalParent() const;
+    Cursor functionBaseDeclaration() const;
+    Cursor functionBase() const;
+    Cursor argument(int index) const;
+    std::vector<Cursor> outputArguments() const;
+
+    CXCursorKind kind() const;
+
+    template <class VisitorCallback>
+    void visit(VisitorCallback visitorCallback) const;
+
+private:
+    CXCursor cxCursor;
+};
+
+template <class VisitorCallback>
+void Cursor::visit(VisitorCallback visitorCallback) const
+{
+    auto visitor = [] (CXCursor cursor, CXCursor parent, CXClientData lambda) -> CXChildVisitResult {
+        auto &visitorCallback = *static_cast<VisitorCallback*>(lambda);
+
+        return visitorCallback(cursor, parent);
+    };
+
+    clang_visitChildren(cxCursor, visitor, &visitorCallback);
+}
+
+bool operator==(const Cursor &first, const Cursor &second);
+
+void PrintTo(CXCursorKind cursorKind, ::std::ostream *os);
+void PrintTo(const Cursor &cursor, ::std::ostream* os);
+} // namespace ClangBackEnd
+
+
+#endif // CLANGBACKEND_CURSOR_H
diff --git a/src/tools/clangbackend/ipcsource/highlightinginformation.cpp b/src/tools/clangbackend/ipcsource/highlightinginformation.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..808a0407d14e930e3ee27b82d8e04f6638a9afa9
--- /dev/null
+++ b/src/tools/clangbackend/ipcsource/highlightinginformation.cpp
@@ -0,0 +1,304 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company.  For licensing terms and
+** conditions see http://www.qt.io/terms-conditions.  For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights.  These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "clangstring.h"
+#include "cursor.h"
+#include "highlightinginformation.h"
+#include "sourcelocation.h"
+#include "sourcerange.h"
+
+#include <cstring>
+#include <ostream>
+
+#include <QDebug>
+
+namespace ClangBackEnd {
+
+HighlightingInformation::HighlightingInformation(const CXCursor &cxCursor,
+                                                 CXToken *cxToken,
+                                                 CXTranslationUnit cxTranslationUnit)
+{
+    const SourceRange sourceRange = clang_getTokenExtent(cxTranslationUnit, *cxToken);
+    const auto start = sourceRange.start();
+    const auto end = sourceRange.end();
+
+    originalCursor = cxCursor;
+    line = start.line();
+    column = start.column();
+    length = end.offset() - start.offset();
+    type = kind(cxToken, originalCursor);
+}
+
+HighlightingInformation::HighlightingInformation(uint line, uint column, uint length, HighlightingType type)
+    : line(line),
+      column(column),
+      length(length),
+      type(type)
+{
+}
+
+bool HighlightingInformation::hasType(HighlightingType type) const
+{
+    return this->type == type;
+}
+
+bool HighlightingInformation::hasFunctionArguments() const
+{
+    return originalCursor.argumentCount() > 0;
+}
+
+QVector<HighlightingInformation> HighlightingInformation::outputFunctionArguments() const
+{
+    QVector<HighlightingInformation> outputFunctionArguments;
+
+    return outputFunctionArguments;
+}
+
+namespace {
+
+bool isFinalFunction(const Cursor &cursor)
+{
+    auto referencedCursor = cursor.referenced();
+    if (referencedCursor.hasFinalFunctionAttribute())
+        return true;
+
+    else return false;
+}
+
+bool isFunctionInFinalClass(const Cursor &cursor)
+{
+    auto functionBase = cursor.functionBaseDeclaration();
+    if (functionBase.isValid() && functionBase.hasFinalClassAttribute())
+        return true;
+
+    return false;
+}
+}
+
+HighlightingType HighlightingInformation::memberReferenceKind(const Cursor &cursor) const
+{
+    if (cursor.isDynamicCall()) {
+        if (isFinalFunction(cursor) || isFunctionInFinalClass(cursor))
+            return HighlightingType::Function;
+        else
+            return HighlightingType::VirtualFunction;
+    }
+
+    return identifierKind(cursor.referenced());
+
+}
+
+HighlightingType HighlightingInformation::referencedTypeKind(const Cursor &cursor) const
+{
+    const Cursor referencedCursor = cursor.referenced();
+
+    switch (referencedCursor.kind()) {
+        case CXCursor_ClassDecl:
+        case CXCursor_StructDecl:
+        case CXCursor_UnionDecl:
+        case CXCursor_TemplateTypeParameter:
+        case CXCursor_TypeAliasDecl:         return HighlightingType::Type;
+        case CXCursor_EnumDecl:              return HighlightingType::Enumeration;
+        default:                             return HighlightingType::Invalid;
+    }
+
+    Q_UNREACHABLE();
+}
+
+HighlightingType HighlightingInformation::variableKind(const Cursor &cursor) const
+{
+    if (cursor.isLocalVariable())
+        return HighlightingType::LocalVariable;
+    else
+        return HighlightingType::GlobalVariable;
+}
+
+bool HighlightingInformation::isVirtualMethodDeclarationOrDefinition(const Cursor &cursor) const
+{
+    return cursor.isVirtualMethod()
+        && (originalCursor.isDeclaration() || originalCursor.isDefinition());
+}
+namespace {
+bool isNotFinalFunction(const Cursor &cursor)
+{
+    return !cursor.hasFinalFunctionAttribute();
+}
+
+}
+bool HighlightingInformation::isRealDynamicCall(const Cursor &cursor) const
+{
+
+    return originalCursor.isDynamicCall() && isNotFinalFunction(cursor);
+}
+
+HighlightingType HighlightingInformation::functionKind(const Cursor &cursor) const
+{
+    if (isRealDynamicCall(cursor) || isVirtualMethodDeclarationOrDefinition(cursor))
+        return HighlightingType::VirtualFunction;
+    else
+        return HighlightingType::Function;
+}
+
+HighlightingType HighlightingInformation::identifierKind(const Cursor &cursor) const
+{
+    switch (cursor.kind()) {
+        case CXCursor_Destructor:
+        case CXCursor_Constructor:
+        case CXCursor_FunctionDecl:
+        case CXCursor_CallExpr:
+        case CXCursor_CXXMethod:                 return functionKind(cursor);
+        case CXCursor_NonTypeTemplateParameter:
+        case CXCursor_ParmDecl:                  return HighlightingType::LocalVariable;
+        case CXCursor_VarDecl:                   return variableKind(cursor);
+        case CXCursor_DeclRefExpr:               return identifierKind(cursor.referenced());
+        case CXCursor_MemberRefExpr:             return memberReferenceKind(cursor);
+        case CXCursor_FieldDecl:
+        case CXCursor_MemberRef:
+        case CXCursor_ObjCIvarDecl:
+        case CXCursor_ObjCPropertyDecl:
+        case CXCursor_ObjCClassMethodDecl:
+        case CXCursor_ObjCInstanceMethodDecl:
+        case CXCursor_ObjCSynthesizeDecl:
+        case CXCursor_ObjCDynamicDecl:           return HighlightingType::Field;
+        case CXCursor_TypeRef:                   return referencedTypeKind(cursor);
+        case CXCursor_ClassDecl:
+        case CXCursor_TemplateTypeParameter:
+        case CXCursor_TemplateTemplateParameter:
+        case CXCursor_UnionDecl:
+        case CXCursor_StructDecl:
+        case CXCursor_TemplateRef:
+        case CXCursor_Namespace:
+        case CXCursor_NamespaceRef:
+        case CXCursor_NamespaceAlias:
+        case CXCursor_TypeAliasDecl:
+        case CXCursor_ClassTemplate:
+        case CXCursor_UnexposedDecl:
+        case CXCursor_CXXStaticCastExpr:
+        case CXCursor_CXXReinterpretCastExpr:
+        case CXCursor_ObjCCategoryDecl:
+        case CXCursor_ObjCCategoryImplDecl:
+        case CXCursor_ObjCImplementationDecl:
+        case CXCursor_ObjCInterfaceDecl:
+        case CXCursor_ObjCProtocolDecl:
+        case CXCursor_ObjCProtocolRef:
+        case CXCursor_ObjCClassRef:
+        case CXCursor_ObjCSuperClassRef:         return HighlightingType::Type;
+        case CXCursor_FunctionTemplate:          return HighlightingType::Function;
+        case CXCursor_EnumConstantDecl:          return HighlightingType::Enumeration;
+        case CXCursor_EnumDecl:                  return referencedTypeKind(cursor);
+        case CXCursor_PreprocessingDirective:    return HighlightingType::Preprocessor;
+        case CXCursor_MacroExpansion:            return HighlightingType::PreprocessorExpansion;
+        case CXCursor_MacroDefinition:           return HighlightingType::PreprocessorDefinition;
+        case CXCursor_InclusionDirective:        return HighlightingType::StringLiteral;
+        case CXCursor_LabelRef:
+        case CXCursor_LabelStmt:                 return HighlightingType::Label;
+        default:                                 return HighlightingType::Invalid;
+    }
+
+    Q_UNREACHABLE();
+}
+
+namespace {
+HighlightingType literalKind(const Cursor &cursor)
+{
+    switch (cursor.kind()) {
+        case CXCursor_CharacterLiteral:
+        case CXCursor_StringLiteral:
+        case CXCursor_ObjCStringLiteral: return HighlightingType::StringLiteral;
+        case CXCursor_IntegerLiteral:
+        case CXCursor_ImaginaryLiteral:
+        case CXCursor_FloatingLiteral:   return HighlightingType::NumberLiteral;
+        default:                         return HighlightingType::Invalid;
+    }
+
+    Q_UNREACHABLE();
+}
+
+
+HighlightingType punctationKind(const Cursor &cursor)
+{
+    switch (cursor.kind()) {
+        case CXCursor_DeclRefExpr: return HighlightingType::Operator;
+        default:                   return HighlightingType::Invalid;
+    }
+}
+
+}
+HighlightingType HighlightingInformation::kind(CXToken *cxToken, const Cursor &cursor) const
+{
+    auto cxTokenKind = clang_getTokenKind(*cxToken);
+
+    switch (cxTokenKind) {
+        case CXToken_Keyword:     return HighlightingType::Keyword;
+        case CXToken_Punctuation: return punctationKind(cursor);
+        case CXToken_Identifier:  return identifierKind(cursor);
+        case CXToken_Comment:     return HighlightingType::Comment;
+        case CXToken_Literal:     return literalKind(cursor);
+    }
+
+    Q_UNREACHABLE();
+}
+
+void PrintTo(const HighlightingInformation& information, ::std::ostream *os)
+{
+    *os << "type: ";
+    PrintTo(information.type, os);
+    *os << " line: " << information.line
+        << " column: " << information.column
+        << " length: " << information.length;
+}
+
+void PrintTo(HighlightingType highlightingType, std::ostream *os)
+{
+    switch (highlightingType) {
+        case HighlightingType::Invalid: *os << "Invalid"; break;
+        case HighlightingType::Comment: *os << "Comment"; break;
+        case HighlightingType::Keyword: *os << "Keyword"; break;
+        case HighlightingType::StringLiteral: *os << "StringLiteral"; break;
+        case HighlightingType::NumberLiteral: *os << "NumberLiteral"; break;
+        case HighlightingType::Function: *os << "Function"; break;
+        case HighlightingType::VirtualFunction: *os << "VirtualFunction"; break;
+        case HighlightingType::Type: *os << "Type"; break;
+        case HighlightingType::LocalVariable: *os << "LocalVariable"; break;
+        case HighlightingType::GlobalVariable: *os << "GlobalVariable"; break;
+        case HighlightingType::Field: *os << "Field"; break;
+        case HighlightingType::Enumeration: *os << "Enumeration"; break;
+        case HighlightingType::Operator: *os << "Operator"; break;
+        case HighlightingType::Preprocessor: *os << "Preprocessor"; break;
+        case HighlightingType::Label: *os << "Label"; break;
+        case HighlightingType::OutputArgument: *os << "OutputArgument"; break;
+        case HighlightingType::PreprocessorDefinition: *os << "PreprocessorDefinition"; break;
+        case HighlightingType::PreprocessorExpansion: *os << "PreprocessorExpansion"; break;
+    }
+}
+
+
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangbackend/ipcsource/highlightinginformation.h b/src/tools/clangbackend/ipcsource/highlightinginformation.h
new file mode 100644
index 0000000000000000000000000000000000000000..ee327b62135ceb1639915e4fe55b8a712ad77f31
--- /dev/null
+++ b/src/tools/clangbackend/ipcsource/highlightinginformation.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company.  For licensing terms and
+** conditions see http://www.qt.io/terms-conditions.  For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights.  These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef CLANGBACKEND_HIGHLIGHTINGINFORMATION_H
+#define CLANGBACKEND_HIGHLIGHTINGINFORMATION_H
+
+#include <clangbackendipc_global.h>
+
+#include "cursor.h"
+
+#include <clang-c/Index.h>
+
+namespace ClangBackEnd {
+
+class HighlightingInformation
+{
+    friend bool operator==(const HighlightingInformation &first, const HighlightingInformation &second);
+    friend void PrintTo(const HighlightingInformation& highlightingInformation, ::std::ostream *os);
+
+public:
+    HighlightingInformation(const CXCursor &cxCursor, CXToken *cxToken, CXTranslationUnit cxTranslationUnit);
+    HighlightingInformation(uint line, uint column, uint length, HighlightingType type);
+
+    bool hasType(HighlightingType type) const;
+    bool hasFunctionArguments() const;
+    QVector<HighlightingInformation> outputFunctionArguments() const;
+
+private:
+    HighlightingType identifierKind(const Cursor &cursor) const;
+    HighlightingType referencedTypeKind(const Cursor &cursor) const;
+    HighlightingType variableKind(const Cursor &cursor) const;
+    bool isVirtualMethodDeclarationOrDefinition(const Cursor &cursor) const;
+    HighlightingType functionKind(const Cursor &cursor) const;
+    HighlightingType memberReferenceKind(const Cursor &cursor) const;
+    HighlightingType kind(CXToken *cxToken, const Cursor &cursor) const;
+    bool isRealDynamicCall(const Cursor &cursor) const;
+
+private:
+    Cursor originalCursor;
+    uint line;
+    uint column;
+    uint length;
+    HighlightingType type;
+};
+
+void PrintTo(const HighlightingInformation& highlightingInformation, ::std::ostream *os);
+void PrintTo(HighlightingType highlightingType, ::std::ostream *os);
+
+inline bool operator==(const HighlightingInformation &first, const HighlightingInformation &second)
+{
+    return first.line == second.line
+        && first.column == second.column
+        && first.length == second.length
+        && first.type == second.type;
+}
+
+} // namespace ClangBackEnd
+
+#endif // CLANGBACKEND_HIGHLIGHTINGINFORMATION_H
diff --git a/src/tools/clangbackend/ipcsource/highlightinginformations.cpp b/src/tools/clangbackend/ipcsource/highlightinginformations.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f7157768fd6868d98bc9558cb4ab6fb2f4fec651
--- /dev/null
+++ b/src/tools/clangbackend/ipcsource/highlightinginformations.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company.  For licensing terms and
+** conditions see http://www.qt.io/terms-conditions.  For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights.  These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "highlightinginformations.h"
+
+namespace ClangBackEnd {
+
+HighlightingInformations::HighlightingInformations(CXTranslationUnit cxTranslationUnit, CXToken *tokens, uint tokensCount)
+    : cxTranslationUnit(cxTranslationUnit),
+      cxToken(tokens),
+      cxTokenCount(tokensCount)
+{
+    cxCursor.resize(tokensCount);
+    clang_annotateTokens(cxTranslationUnit, cxToken, cxTokenCount, cxCursor.data());
+}
+
+HighlightingInformations::~HighlightingInformations()
+{
+    clang_disposeTokens(cxTranslationUnit, cxToken, cxTokenCount);
+}
+
+HighlightingInformations::const_iterator HighlightingInformations::begin() const
+{
+    return const_iterator(cxCursor.cbegin(), cxToken, cxTranslationUnit);
+}
+
+HighlightingInformations::const_iterator HighlightingInformations::end() const
+{
+    return const_iterator(cxCursor.cend(), cxToken + cxTokenCount, cxTranslationUnit);
+}
+
+bool HighlightingInformations::isEmpty() const
+{
+    return cxTokenCount == 0;
+}
+
+bool ClangBackEnd::HighlightingInformations::isNull() const
+{
+    return cxToken == nullptr;
+}
+
+uint HighlightingInformations::size() const
+{
+    return cxTokenCount;
+}
+
+HighlightingInformation HighlightingInformations::operator[](size_t index) const
+{
+    return HighlightingInformation(cxCursor[index], cxToken + index, cxTranslationUnit);
+}
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangbackend/ipcsource/highlightinginformations.h b/src/tools/clangbackend/ipcsource/highlightinginformations.h
new file mode 100644
index 0000000000000000000000000000000000000000..2c7b8ce9bbf12fb7e4ce300c4f2f405559bbf7b4
--- /dev/null
+++ b/src/tools/clangbackend/ipcsource/highlightinginformations.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company.  For licensing terms and
+** conditions see http://www.qt.io/terms-conditions.  For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights.  These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef CLANGBACKEND_HIGHLIGHTINGINFORMATIONS_H
+#define CLANGBACKEND_HIGHLIGHTINGINFORMATIONS_H
+
+#include "highlightinginformationsiterator.h"
+
+#include <clang-c/Index.h>
+
+#include <vector>
+
+namespace ClangBackEnd {
+
+using uint = unsigned int;
+
+class HighlightingInformations
+{
+public:
+    using const_iterator = HighlightingInformationsIterator;
+    using value_type = HighlightingInformation;
+
+public:
+    HighlightingInformations() = default;
+    HighlightingInformations(CXTranslationUnit cxTranslationUnit, CXToken *tokens, uint tokensCount);
+    ~HighlightingInformations();
+
+    bool isEmpty() const;
+    bool isNull() const;
+    uint size() const;
+
+    HighlightingInformation operator[](size_t index) const;
+
+    const_iterator begin() const;
+    const_iterator end() const;
+
+private:
+    CXTranslationUnit cxTranslationUnit = nullptr;
+    CXToken *const cxToken = nullptr;
+    const uint cxTokenCount = 0;
+
+    std::vector<CXCursor> cxCursor;
+};
+
+} // namespace ClangBackEnd
+
+#endif // CLANGBACKEND_HIGHLIGHTINGINFORMATIONS_H
diff --git a/src/tools/clangbackend/ipcsource/highlightinginformationsiterator.h b/src/tools/clangbackend/ipcsource/highlightinginformationsiterator.h
new file mode 100644
index 0000000000000000000000000000000000000000..53f540970e60347cd452b7499de503b496ef9888
--- /dev/null
+++ b/src/tools/clangbackend/ipcsource/highlightinginformationsiterator.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company.  For licensing terms and
+** conditions see http://www.qt.io/terms-conditions.  For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights.  These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef HIGHLIGHTINGINFORMATIONSITERATOR_H
+#define HIGHLIGHTINGINFORMATIONSITERATOR_H
+
+#include "highlightinginformation.h"
+
+#include <iterator>
+#include <vector>
+
+#include <clang-c/Index.h>
+
+namespace ClangBackEnd {
+
+using uint = unsigned int;
+
+class DiagnosticSet;
+class Diagnostic;
+
+class HighlightingInformationsIterator : public std::iterator<std::forward_iterator_tag, HighlightingInformation, uint>
+{
+public:
+    HighlightingInformationsIterator(std::vector<CXCursor>::const_iterator cxCursorIterator,
+                                     CXToken *cxToken,
+                                     CXTranslationUnit cxTranslationUnit)
+        : cxCursorIterator(cxCursorIterator),
+          cxToken(cxToken),
+          cxTranslationUnit(cxTranslationUnit)
+    {}
+
+    HighlightingInformationsIterator(const HighlightingInformationsIterator &other)
+        : cxCursorIterator(other.cxCursorIterator)
+    {}
+
+    HighlightingInformationsIterator& operator++()
+    {
+        ++cxCursorIterator;
+        ++cxToken;
+
+        return *this;
+    }
+
+    HighlightingInformationsIterator operator++(int)
+    {
+        return HighlightingInformationsIterator(cxCursorIterator++, cxToken++, cxTranslationUnit);
+    }
+
+    bool operator==(HighlightingInformationsIterator other) const
+    {
+        return cxCursorIterator == other.cxCursorIterator;
+    }
+
+    bool operator!=(HighlightingInformationsIterator other) const
+    {
+        return cxCursorIterator != other.cxCursorIterator;
+    }
+
+    HighlightingInformation operator*()
+    {
+        return HighlightingInformation(*cxCursorIterator, cxToken, cxTranslationUnit);
+    }
+
+private:
+    std::vector<CXCursor>::const_iterator cxCursorIterator;
+    CXToken *cxToken;
+    CXTranslationUnit cxTranslationUnit;
+};
+
+} // namespace ClangBackEnd
+
+#endif // HIGHLIGHTINGINFORMATIONSITERATOR_H
diff --git a/src/tools/clangbackend/ipcsource/skippedsourceranges.cpp b/src/tools/clangbackend/ipcsource/skippedsourceranges.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2a39131474b72ac13e1acc88f7461815fd7864c0
--- /dev/null
+++ b/src/tools/clangbackend/ipcsource/skippedsourceranges.cpp
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company.  For licensing terms and
+** conditions see http://www.qt.io/terms-conditions.  For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights.  These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+#include "skippedsourceranges.h"
+
+#include "sourcerangecontainer.h"
+
+#include <QVector>
+
+#include <algorithm>
+
+namespace ClangBackEnd {
+
+SkippedSourceRanges::SkippedSourceRanges(CXTranslationUnit cxTranslationUnit, const char *filePath)
+{
+    cxSkippedSourceRanges = clang_getSkippedRanges(cxTranslationUnit,
+                                                   clang_getFile(cxTranslationUnit,
+                                                                 filePath));
+}
+
+SkippedSourceRanges::~SkippedSourceRanges()
+{
+    clang_disposeSourceRangeList(cxSkippedSourceRanges);
+}
+
+SkippedSourceRanges &SkippedSourceRanges::operator=(SkippedSourceRanges &&other)
+{
+    if (this != &other) {
+        cxSkippedSourceRanges = other.cxSkippedSourceRanges;
+        other.cxSkippedSourceRanges = nullptr;
+    }
+
+    return *this;
+}
+
+std::vector<SourceRange> SkippedSourceRanges::sourceRanges() const
+{
+    std::vector<SourceRange> sourceRanges;
+
+    auto sourceRangeCount = cxSkippedSourceRanges->count;
+    sourceRanges.reserve(sourceRangeCount);
+
+    std::copy(cxSkippedSourceRanges->ranges,
+              cxSkippedSourceRanges->ranges + sourceRangeCount,
+              std::back_inserter(sourceRanges));
+
+    return sourceRanges;
+}
+
+QVector<SourceRangeContainer> SkippedSourceRanges::toSourceRangeContainers() const
+{
+    QVector<SourceRangeContainer> sourceRangeContainers;
+
+    auto sourceRanges = this->sourceRanges();
+
+    std::copy(sourceRanges.cbegin(),
+              sourceRanges.cend(),
+              std::back_inserter(sourceRangeContainers));
+
+    return sourceRangeContainers;
+}
+
+ClangBackEnd::SkippedSourceRanges::operator QVector<SourceRangeContainer>() const
+{
+    return toSourceRangeContainers();
+}
+
+SkippedSourceRanges::SkippedSourceRanges(SkippedSourceRanges &&other)
+    : cxSkippedSourceRanges(other.cxSkippedSourceRanges)
+{
+    other.cxSkippedSourceRanges = nullptr;
+}
+
+} // namespace ClangBackEnd
+
diff --git a/src/tools/clangbackend/ipcsource/skippedsourceranges.h b/src/tools/clangbackend/ipcsource/skippedsourceranges.h
new file mode 100644
index 0000000000000000000000000000000000000000..8d38bc50c9eac95e301c5d5e0593cf703993ed41
--- /dev/null
+++ b/src/tools/clangbackend/ipcsource/skippedsourceranges.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company.  For licensing terms and
+** conditions see http://www.qt.io/terms-conditions.  For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights.  These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+#ifndef CLANGBACKEND_SKIPPEDSOURCERANGES_H
+#define CLANGBACKEND_SKIPPEDSOURCERANGES_H
+
+#include "sourcerange.h"
+
+namespace ClangBackEnd {
+
+class SourceRangeContainer;
+
+class SkippedSourceRanges
+{
+public:
+    SkippedSourceRanges(CXTranslationUnit TranslationUnit, const char *filePath);
+    ~SkippedSourceRanges();
+
+    SkippedSourceRanges(const SkippedSourceRanges &) = delete;
+    const SkippedSourceRanges &operator=(const SkippedSourceRanges &) = delete;
+
+    SkippedSourceRanges(SkippedSourceRanges &&);
+    SkippedSourceRanges &operator=(SkippedSourceRanges &&);
+
+    std::vector<SourceRange> sourceRanges() const;
+
+    QVector<SourceRangeContainer> toSourceRangeContainers() const;
+
+    operator QVector<SourceRangeContainer>() const;
+
+private:
+    CXSourceRangeList *cxSkippedSourceRanges;
+};
+
+} // namespace ClangBackEnd
+
+#endif // CLANGBACKEND_SKIPPEDSOURCERANGES_H
diff --git a/src/tools/clangbackend/ipcsource/sourcelocation.cpp b/src/tools/clangbackend/ipcsource/sourcelocation.cpp
index 8a7cd0d8716adf4e30f249891becf74bc56df0ba..e04f44c7d88a8129c9e40ba00dbd0b13ea5c1fd5 100644
--- a/src/tools/clangbackend/ipcsource/sourcelocation.cpp
+++ b/src/tools/clangbackend/ipcsource/sourcelocation.cpp
@@ -31,6 +31,7 @@
 #include "sourcelocation.h"
 
 #include "clangstring.h"
+#include "translationunit.h"
 
 #include <utf8string.h>
 
@@ -39,6 +40,11 @@
 
 namespace ClangBackEnd {
 
+SourceLocation::SourceLocation()
+    : cxSourceLocation(clang_getNullLocation())
+{
+}
+
 const Utf8String &SourceLocation::filePath() const
 {
     return filePath_;
@@ -65,6 +71,7 @@ SourceLocationContainer SourceLocation::toSourceLocationContainer() const
 }
 
 SourceLocation::SourceLocation(CXSourceLocation cxSourceLocation)
+    : cxSourceLocation(cxSourceLocation)
 {
     CXFile cxFile;
 
@@ -77,10 +84,37 @@ SourceLocation::SourceLocation(CXSourceLocation cxSourceLocation)
     filePath_ = ClangString(clang_getFileName(cxFile));
 }
 
+SourceLocation::SourceLocation(CXTranslationUnit cxTranslationUnit,
+                               const Utf8String &filePath,
+                               uint line,
+                               uint column)
+    : cxSourceLocation(clang_getLocation(cxTranslationUnit,
+                                         clang_getFile(cxTranslationUnit,
+                                                       filePath.constData()),
+                                         line,
+                                         column)),
+      filePath_(filePath),
+      line_(line)
+{
+}
+
+bool operator==(const SourceLocation &first, const SourceLocation &second)
+{
+    return clang_equalLocations(first.cxSourceLocation, second.cxSourceLocation);
+}
+
+SourceLocation::operator CXSourceLocation() const
+{
+    return cxSourceLocation;
+}
+
 void PrintTo(const SourceLocation &sourceLocation, std::ostream *os)
 {
-    *os << sourceLocation.filePath().constData()
-        << ", line: " << sourceLocation.line()
+    auto filePath = sourceLocation.filePath();
+    if (filePath.hasContent())
+        *os << filePath.constData()  << ", ";
+
+    *os << "line: " << sourceLocation.line()
         << ", column: "<< sourceLocation.column()
         << ", offset: "<< sourceLocation.offset();
 }
diff --git a/src/tools/clangbackend/ipcsource/sourcelocation.h b/src/tools/clangbackend/ipcsource/sourcelocation.h
index 3ee500623b84f4d8ace06515a1d95f3119f41cc2..83ba6c77c9c8230d5f0d9e6fccd5a9f3a2af716a 100644
--- a/src/tools/clangbackend/ipcsource/sourcelocation.h
+++ b/src/tools/clangbackend/ipcsource/sourcelocation.h
@@ -38,13 +38,19 @@
 namespace ClangBackEnd {
 
 class SourceLocationContainer;
+class TranslationUnit;
 
 class SourceLocation
 {
     friend class Diagnostic;
     friend class SourceRange;
+    friend class TranslationUnit;
+    friend class Cursor;
+    friend bool operator==(const SourceLocation &first, const SourceLocation &second);
 
 public:
+    SourceLocation();
+
     const Utf8String &filePath() const;
     uint line() const;
     uint column() const;
@@ -54,14 +60,23 @@ public:
 
 private:
     SourceLocation(CXSourceLocation cxSourceLocation);
+    SourceLocation(CXTranslationUnit cxTranslationUnit,
+                   const Utf8String &filePath,
+                   uint line,
+                   uint column);
+
+    operator CXSourceLocation() const;
 
 private:
+   CXSourceLocation cxSourceLocation;
    Utf8String filePath_;
-   uint line_;
-   uint column_;
-   uint offset_;
+   uint line_ = 0;
+   uint column_ = 0;
+   uint offset_ = 0;
 };
 
+bool operator==(const SourceLocation &first, const SourceLocation &second);
+
 void PrintTo(const SourceLocation &sourceLocation, ::std::ostream* os);
 
 } // namespace ClangBackEnd
diff --git a/src/tools/clangbackend/ipcsource/sourcerange.cpp b/src/tools/clangbackend/ipcsource/sourcerange.cpp
index 7375988b2bd7237790ab6f3da927cb4d41540582..f069edc9cb152f39ecc2024736d82980765b7de0 100644
--- a/src/tools/clangbackend/ipcsource/sourcerange.cpp
+++ b/src/tools/clangbackend/ipcsource/sourcerange.cpp
@@ -32,6 +32,8 @@
 
 #include <sourcerangecontainer.h>
 
+#include <ostream>
+
 namespace ClangBackEnd {
 
 SourceRange::SourceRange()
@@ -39,6 +41,11 @@ SourceRange::SourceRange()
 {
 }
 
+SourceRange::SourceRange(const SourceLocation &start, const SourceLocation &end)
+    : cxSourceRange(clang_getRange(start, end))
+{
+}
+
 bool SourceRange::isNull() const
 {
     return clang_Range_isNull(cxSourceRange);
@@ -65,10 +72,33 @@ SourceRangeContainer SourceRange::toSourceRangeContainer() const
                                 end().toSourceLocationContainer());
 }
 
+ClangBackEnd::SourceRange::operator SourceRangeContainer() const
+{
+    return toSourceRangeContainer();
+}
+
+ClangBackEnd::SourceRange::operator CXSourceRange() const
+{
+    return cxSourceRange;
+}
+
 SourceRange::SourceRange(CXSourceRange cxSourceRange)
     : cxSourceRange(cxSourceRange)
 {
 }
 
+bool operator==(const SourceRange &first, const SourceRange &second)
+{
+    return clang_equalRanges(first.cxSourceRange, second.cxSourceRange);
+}
+
+void PrintTo(const SourceRange &sourceRange, ::std::ostream* os)
+{
+    *os << "[";
+    PrintTo(sourceRange.start(), os);
+    *os << ", ";
+    PrintTo(sourceRange.end(), os);
+    *os << "]";
+}
 } // namespace ClangBackEnd
 
diff --git a/src/tools/clangbackend/ipcsource/sourcerange.h b/src/tools/clangbackend/ipcsource/sourcerange.h
index 3c80e4e040db381747a8b5b9c2b340426b89ee0f..f9b786cf4aad2b546df11f5a9ebb5afe01f73f26 100644
--- a/src/tools/clangbackend/ipcsource/sourcerange.h
+++ b/src/tools/clangbackend/ipcsource/sourcerange.h
@@ -41,9 +41,14 @@ class SourceRange
 {
     friend class Diagnostic;
     friend class FixIt;
+    friend class Cursor;
+    friend class HighlightingInformation;
+    friend bool operator==(const SourceRange &first, const SourceRange &second);
 
 public:
     SourceRange();
+    SourceRange(CXSourceRange cxSourceRange);
+    SourceRange(const SourceLocation &start, const SourceLocation &end);
 
     bool isNull() const;
     bool isValid() const;
@@ -53,13 +58,15 @@ public:
 
     SourceRangeContainer toSourceRangeContainer() const;
 
-private:
-    SourceRange(CXSourceRange cxSourceRange);
+    operator CXSourceRange() const;
+    operator SourceRangeContainer() const;
 
 private:
     CXSourceRange cxSourceRange;
 };
 
+bool operator==(const SourceRange &first, const SourceRange &second);
+void PrintTo(const SourceRange &sourceRange, ::std::ostream* os);
 } // namespace ClangBackEnd
 
 #endif // CLANGBACKEND_SOURCERANGE_H
diff --git a/src/tools/clangbackend/ipcsource/translationunit.cpp b/src/tools/clangbackend/ipcsource/translationunit.cpp
index 88e917010f6df50ad5eb1cd9b5f91c26915bfcd4..8769f7caef3f9b8cceccb204f33159a0df32330b 100644
--- a/src/tools/clangbackend/ipcsource/translationunit.cpp
+++ b/src/tools/clangbackend/ipcsource/translationunit.cpp
@@ -30,13 +30,17 @@
 
 #include "translationunit.h"
 
+#include "cursor.h"
 #include "clangstring.h"
 #include "codecompleter.h"
 #include "commandlinearguments.h"
 #include "diagnosticcontainer.h"
 #include "diagnosticset.h"
 #include "projectpart.h"
+#include "skippedsourceranges.h"
 #include "sourcelocation.h"
+#include "sourcerange.h"
+#include "highlightinginformations.h"
 #include "translationunitfilenotexitexception.h"
 #include "translationunitisnullexception.h"
 #include "translationunitparseerrorexception.h"
@@ -245,6 +249,53 @@ void TranslationUnit::setDirtyIfDependencyIsMet(const Utf8String &filePath)
     }
 }
 
+SourceLocation TranslationUnit::sourceLocationAt(uint line, uint column) const
+{
+    return SourceLocation(cxTranslationUnit(), filePath(), line, column);
+}
+
+SourceLocation TranslationUnit::sourceLocationAt(const Utf8String &filePath, uint line, uint column) const
+{
+    return SourceLocation(cxTranslationUnit(), filePath, line, column);
+}
+
+SourceRange TranslationUnit::sourceRange(uint fromLine, uint fromColumn, uint toLine, uint toColumn) const
+{
+    return SourceRange(sourceLocationAt(fromLine, fromColumn),
+                       sourceLocationAt(toLine, toColumn));
+}
+
+Cursor TranslationUnit::cursorAt(uint line, uint column) const
+{
+    return clang_getCursor(cxTranslationUnit(), sourceLocationAt(line, column));
+}
+
+Cursor TranslationUnit::cursorAt(const Utf8String &filePath, uint line, uint column) const
+{
+    return clang_getCursor(cxTranslationUnit(), sourceLocationAt(filePath, line, column));
+}
+
+Cursor TranslationUnit::cursor() const
+{
+    return clang_getTranslationUnitCursor(cxTranslationUnit());
+}
+
+HighlightingInformations TranslationUnit::highlightingInformationsInRange(const SourceRange &range) const
+{
+    CXToken *cxTokens = 0;
+    uint cxTokensCount = 0;
+    auto translationUnit = cxTranslationUnit();
+
+    clang_tokenize(translationUnit, range, &cxTokens, &cxTokensCount);
+
+    return HighlightingInformations(translationUnit, cxTokens, cxTokensCount);
+}
+
+SkippedSourceRanges TranslationUnit::skippedSourceRanges() const
+{
+    return SkippedSourceRanges(cxTranslationUnit(), d->filePath.constData());
+}
+
 void TranslationUnit::checkIfNull() const
 {
     if (isNull())
@@ -380,7 +431,8 @@ uint TranslationUnit::defaultOptions()
 {
     return CXTranslationUnit_CacheCompletionResults
          | CXTranslationUnit_PrecompiledPreamble
-         | CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
+         | CXTranslationUnit_IncludeBriefCommentsInCodeCompletion
+         | CXTranslationUnit_DetailedPreprocessingRecord;
 }
 
 uint TranslationUnit::unsavedFilesCount() const
diff --git a/src/tools/clangbackend/ipcsource/translationunit.h b/src/tools/clangbackend/ipcsource/translationunit.h
index e44852e47394d144c73355073b7d5526d51ecba2..fd3831cb3e04148f61d4168ab4d9739d25d338fe 100644
--- a/src/tools/clangbackend/ipcsource/translationunit.h
+++ b/src/tools/clangbackend/ipcsource/translationunit.h
@@ -52,8 +52,13 @@ class ProjectPart;
 class DiagnosticContainer;
 class DiagnosticSet;
 class FileContainer;
+class HighlightingInformations;
 class TranslationUnits;
 class CommandLineArguments;
+class Cursor;
+class SourceLocation;
+class SourceRange;
+class SkippedSourceRanges;
 
 using time_point = std::chrono::steady_clock::time_point;
 
@@ -111,6 +116,19 @@ public:
 
     CommandLineArguments commandLineArguments() const;
 
+    SourceLocation sourceLocationAt(uint line, uint column) const;
+    SourceLocation sourceLocationAt(const Utf8String &filePath, uint line, uint column) const;
+
+    SourceRange sourceRange(uint fromLine, uint fromColumn, uint toLine, uint toColumn) const;
+
+    Cursor cursorAt(uint line, uint column) const;
+    Cursor cursorAt(const Utf8String &filePath, uint line, uint column) const;
+    Cursor cursor() const;
+
+    HighlightingInformations highlightingInformationsInRange(const SourceRange &range) const;
+
+    SkippedSourceRanges skippedSourceRanges() const;
+
 private:
     void checkIfNull() const;
     void checkIfFileExists() const;
diff --git a/src/tools/clangbackend/ipcsource/type.cpp b/src/tools/clangbackend/ipcsource/type.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a1f78e44eb2d6cb0651ab633d3bfbe9b547db452
--- /dev/null
+++ b/src/tools/clangbackend/ipcsource/type.cpp
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company.  For licensing terms and
+** conditions see http://www.qt.io/terms-conditions.  For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights.  These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "type.h"
+
+#include "clangstring.h"
+#include "cursor.h"
+
+#include <utf8string.h>
+
+#include <ostream>
+
+namespace ClangBackEnd {
+
+bool Type::isConstant() const
+{
+    return clang_isConstQualifiedType(cxType);
+}
+
+bool Type::isConstantReference()
+{
+    return isLValueReference() && pointeeType().isConstant();
+}
+
+bool Type::isPointer() const
+{
+    return cxType.kind == CXType_Pointer;
+}
+
+bool Type::isPointerToConstant() const
+{
+    return isPointer() && pointeeType().isConstant();
+}
+
+bool Type::isConstantPointer() const
+{
+    return isPointer() && isConstant();
+}
+
+bool Type::isLValueReference() const
+{
+    return cxType.kind == CXType_LValueReference;
+}
+
+bool Type::isReferencingConstant() const
+{
+    return (isPointer() || isLValueReference()) && pointeeType().isConstant();
+}
+
+bool Type::isOutputParameter() const
+{
+    return (isPointer() || isLValueReference()) && !pointeeType().isConstant();
+}
+
+Utf8String Type::utf8Spelling() const
+{
+    return  ClangString(clang_getTypeSpelling(cxType));
+}
+
+ClangString Type::spelling() const
+{
+    return ClangString(clang_getTypeSpelling(cxType));
+}
+
+int Type::argumentCount() const
+{
+    return clang_getNumArgTypes(cxType);
+}
+
+Type Type::alias() const
+{
+    return clang_getTypedefDeclUnderlyingType(clang_getTypeDeclaration(cxType));
+}
+
+Type Type::canonical() const
+{
+    return clang_getCanonicalType(cxType);
+}
+
+Type Type::classType() const
+{
+    return clang_Type_getClassType(cxType);
+}
+
+Type Type::pointeeType() const
+{
+    return clang_getPointeeType(cxType);
+}
+
+Type Type::argument(int index) const
+{
+    return clang_getArgType(cxType, index);
+}
+
+Cursor Type::declaration() const
+{
+    return clang_getTypeDeclaration(cxType);
+}
+
+CXTypeKind Type::kind() const
+{
+    return cxType.kind;
+}
+
+Type::Type(CXType cxType)
+    : cxType(cxType)
+{
+}
+
+bool operator==(Type first, Type second)
+{
+    return clang_equalTypes(first.cxType, second.cxType);
+}
+
+void PrintTo(CXTypeKind typeKind, ::std::ostream* os)
+{
+    ClangString typeKindSpelling(clang_getTypeKindSpelling(typeKind));
+    *os << typeKindSpelling.cString();
+}
+
+void PrintTo(const Type &type, ::std::ostream* os)
+{
+    ClangString typeKindSpelling(clang_getTypeKindSpelling(type.kind()));
+    *os << typeKindSpelling.cString()
+        << ": \"" << type.spelling().cString() << "\"";
+}
+
+
+} // namespace ClangBackEnd
+
diff --git a/src/tools/clangbackend/ipcsource/type.h b/src/tools/clangbackend/ipcsource/type.h
new file mode 100644
index 0000000000000000000000000000000000000000..099bfa4e3eeb0db3c88b87911e0b1b7afb6b092c
--- /dev/null
+++ b/src/tools/clangbackend/ipcsource/type.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company.  For licensing terms and
+** conditions see http://www.qt.io/terms-conditions.  For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights.  These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef CLANGBACKEND_TYPE_H
+#define CLANGBACKEND_TYPE_H
+
+#include <clang-c/Index.h>
+
+#include <iosfwd>
+
+class Utf8String;
+
+namespace ClangBackEnd {
+
+class Cursor;
+class ClangString;
+
+class Type
+{
+    friend class Cursor;
+    friend bool operator==(Type first, Type second);
+
+public:
+    bool isConstant() const;
+    bool isConstantReference();
+    bool isPointer() const;
+    bool isPointerToConstant() const;
+    bool isConstantPointer() const;
+    bool isLValueReference() const;
+    bool isReferencingConstant() const;
+    bool isOutputParameter() const;
+
+    Utf8String utf8Spelling() const;
+    ClangString spelling() const;
+    int argumentCount() const;
+
+    Type alias() const;
+    Type canonical() const;
+    Type classType() const;
+    Type pointeeType() const;
+    Type argument(int index) const;
+
+    Cursor declaration() const;
+
+    CXTypeKind kind() const;
+
+private:
+    Type(CXType cxType);
+
+private:
+    CXType cxType;
+};
+
+bool operator==(Type first, Type second);
+
+void PrintTo(CXTypeKind typeKind, ::std::ostream* os);
+void PrintTo(const Type &type, ::std::ostream* os);
+} // namespace ClangBackEnd
+
+#endif // CLANGBACKEND_TYPE_H
diff --git a/tests/unit/unittest/clangstringtest.cpp b/tests/unit/unittest/clangstringtest.cpp
index 0467de693dfaf0cc837ed25058a779cb91698418..b7ee1982b92fd623ebad095c0d2b6f8ccc47acf6 100644
--- a/tests/unit/unittest/clangstringtest.cpp
+++ b/tests/unit/unittest/clangstringtest.cpp
@@ -42,6 +42,8 @@
 
 namespace {
 
+using ::testing::StrEq;
+
 using ClangBackEnd::ClangString;
 
 TEST(ClangString, ConvertToUtf8String)
@@ -87,4 +89,11 @@ TEST(ClangString, MoveSelfAssigment)
 
     ASSERT_FALSE(text.isNull());
 }
+
+TEST(ClangString, SpellingAsCString)
+{
+    ClangString text(CXString{"text", 0});
+
+    ASSERT_THAT(text.cString(), StrEq("text"));
+}
 }
diff --git a/tests/unit/unittest/cursortest.cpp b/tests/unit/unittest/cursortest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e0e18c130831a26136ce2b84c5324ab9f3fe5ef9
--- /dev/null
+++ b/tests/unit/unittest/cursortest.cpp
@@ -0,0 +1,819 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company.  For licensing terms and
+** conditions see http://www.qt.io/terms-conditions.  For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights.  These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include <clangstring.h>
+#include <cursor.h>
+#include <projectpart.h>
+#include <projects.h>
+#include <sourcelocation.h>
+#include <sourcerange.h>
+#include <translationunit.h>
+#include <translationunits.h>
+#include <unsavedfiles.h>
+
+#include <gmock/gmock.h>
+#include <gmock/gmock-matchers.h>
+#include <gtest/gtest.h>
+#include "gtest-qt-printing.h"
+
+using ClangBackEnd::Cursor;
+using ClangBackEnd::TranslationUnit;
+using ClangBackEnd::UnsavedFiles;
+using ClangBackEnd::ProjectPart;
+using ClangBackEnd::TranslationUnits;
+using ClangBackEnd::ClangString;
+using ClangBackEnd::SourceRange;
+
+using testing::IsNull;
+using testing::NotNull;
+using testing::Gt;
+using testing::Contains;
+using testing::EndsWith;
+using testing::AllOf;
+using testing::Not;
+using testing::IsEmpty;
+using testing::StrEq;
+
+namespace {
+
+struct Data {
+    ClangBackEnd::ProjectParts projects;
+    ClangBackEnd::UnsavedFiles unsavedFiles;
+    ClangBackEnd::TranslationUnits translationUnits{projects, unsavedFiles};
+    TranslationUnit translationUnit{Utf8StringLiteral(TESTDATA_DIR"/cursor.cpp"),
+                ProjectPart(Utf8StringLiteral("projectPartId"), {Utf8StringLiteral("-std=c++11")}),
+                {},
+                translationUnits};
+};
+
+class Cursor : public ::testing::Test
+{
+public:
+    static void SetUpTestCase();
+    static void TearDownTestCase();
+
+protected:
+    static Data *d;
+    const TranslationUnit &translationUnit = d->translationUnit;
+
+
+};
+
+TEST_F(Cursor, CreateNullCursor)
+{
+    ::Cursor cursor;
+
+    ASSERT_TRUE(cursor.isNull());
+}
+
+TEST_F(Cursor, CompareNullCursors)
+{
+    ::Cursor cursor;
+    ::Cursor cursor2;
+
+    ASSERT_THAT(cursor, cursor2);
+}
+
+TEST_F(Cursor, IsNotValid)
+{
+    ::Cursor cursor;
+
+    ASSERT_FALSE(cursor.isValid());
+}
+
+TEST_F(Cursor, IsValid)
+{
+    auto cursor = translationUnit.cursor();
+
+    ASSERT_TRUE(cursor.isValid());
+}
+
+TEST_F(Cursor, IsTranslationUnit)
+{
+    auto cursor = translationUnit.cursor();
+
+    ASSERT_TRUE(cursor.isTranslationUnit());
+}
+
+TEST_F(Cursor, NullCursorIsNotTranslationUnit)
+{
+    ::Cursor cursor;
+
+    ASSERT_FALSE(cursor.isTranslationUnit());
+}
+
+TEST_F(Cursor, UnifiedSymbolResolution)
+{
+     ::Cursor cursor;
+
+     ASSERT_TRUE(cursor.unifiedSymbolResolution().isEmpty());
+}
+
+TEST_F(Cursor, GetCursorAtLocation)
+{
+    auto cursor = translationUnit.cursorAt(3, 6);
+
+    ASSERT_THAT(cursor.unifiedSymbolResolution(), Utf8StringLiteral("c:@F@function#I#"));
+}
+
+TEST_F(Cursor, GetCursoSourceLocation)
+{
+    auto cursor = translationUnit.cursorAt(3, 6);
+
+    ASSERT_THAT(cursor.sourceLocation(), translationUnit.sourceLocationAt(3, 6));
+}
+
+TEST_F(Cursor, GetCursoSourceRange)
+{
+    auto cursor = translationUnit.cursorAt(3, 6);
+
+    ASSERT_THAT(cursor.sourceRange(), SourceRange(translationUnit.sourceLocationAt(3, 1),
+                                                  translationUnit.sourceLocationAt(6, 2)));
+}
+
+TEST_F(Cursor, Mangling)
+{
+    auto cursor = translationUnit.cursorAt(3, 6);
+
+
+    ASSERT_THAT(cursor.mangling(), Utf8StringLiteral("_Z8functioni"));
+}
+
+TEST_F(Cursor, Spelling)
+{
+    auto cursor = translationUnit.cursorAt(3, 6);
+
+
+    ASSERT_THAT(cursor.spelling().cString(), StrEq("function"));
+}
+
+TEST_F(Cursor, DisplayName)
+{
+    auto cursor = translationUnit.cursorAt(3, 6);
+
+
+    ASSERT_THAT(cursor.displayName(), Utf8StringLiteral("function(int)"));
+}
+
+TEST_F(Cursor, BriefComment)
+{
+    auto cursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 10, 7);
+
+
+    ASSERT_THAT(cursor.briefComment(), Utf8StringLiteral("A brief comment"));
+}
+
+TEST_F(Cursor, RawComment)
+{
+    auto cursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 10, 7);
+
+
+    ASSERT_THAT(cursor.rawComment(), Utf8StringLiteral("/**\n * A brief comment\n */"));
+}
+
+TEST_F(Cursor, CommentRange)
+{
+    auto cursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 10, 7);
+
+
+    ASSERT_THAT(cursor.commentRange(),
+                SourceRange(translationUnit.sourceLocationAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 7, 1),
+                            translationUnit.sourceLocationAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 9, 4)));
+}
+
+TEST_F(Cursor, IsDefinition)
+{
+    auto cursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 10, 7);
+
+    ASSERT_TRUE(cursor.isDefinition());
+}
+
+TEST_F(Cursor, ForwardDeclarationIsNotDefinition)
+{
+    auto cursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 6, 7);
+
+    ASSERT_FALSE(cursor.isDefinition());
+}
+
+TEST_F(Cursor, GetDefinitionOfFowardDeclaration)
+{
+    auto forwardDeclarationcursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 6, 7);
+    auto definitionCursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 10, 7);
+
+    ASSERT_THAT(forwardDeclarationcursor.definition(), definitionCursor);
+}
+
+TEST_F(Cursor, CallToMethodeIsNotDynamic)
+{
+    auto cursor = translationUnit.cursorAt(18, 5);
+
+    ASSERT_FALSE(cursor.isDynamicCall());
+}
+
+TEST_F(Cursor, CallToAbstractVirtualMethodeIsDynamic)
+{
+    auto cursor = translationUnit.cursorAt(19, 5);
+
+    ASSERT_TRUE(cursor.isDynamicCall());
+}
+
+TEST_F(Cursor, CanonicalCursor)
+{
+    auto forwardDeclarationcursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 6, 7);
+    auto definitionCursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 10, 7);
+
+    ASSERT_THAT(definitionCursor.canonical(), forwardDeclarationcursor);
+}
+
+TEST_F(Cursor, ReferencedCursor)
+{
+    auto functionCallCursor = translationUnit.cursorAt(18, 5);
+    auto functionCursor = translationUnit.cursorAt(16, 17);
+
+    ASSERT_THAT(functionCallCursor.referenced(), functionCursor);
+}
+
+TEST_F(Cursor, IsVirtual)
+{
+    auto cursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 15, 17);
+
+    ASSERT_TRUE(cursor.isVirtualMethod());
+}
+
+TEST_F(Cursor, IsNotPureVirtualOnlyVirtual)
+{
+    auto cursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 15, 17);
+
+    ASSERT_FALSE(cursor.isPureVirtualMethod());
+}
+
+TEST_F(Cursor, IsPureVirtual)
+{
+    auto cursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 16, 17);
+
+    ASSERT_TRUE(cursor.isPureVirtualMethod());
+}
+
+TEST_F(Cursor, ConstantMethod)
+{
+    auto cursor = translationUnit.cursorAt(31, 18);
+
+    ASSERT_TRUE(cursor.isConstantMethod());
+}
+
+TEST_F(Cursor, IsStaticMethod)
+{
+    auto cursor = translationUnit.cursorAt(36, 18);
+
+    ASSERT_TRUE(cursor.isStaticMethod());
+}
+
+TEST_F(Cursor, TypeSpelling)
+{
+    auto cursor = translationUnit.cursorAt(43, 5);
+
+    ASSERT_THAT(cursor.type().utf8Spelling(), Utf8StringLiteral("lint"));
+}
+
+TEST_F(Cursor, CanonicalTypeSpelling)
+{
+    auto cursor = translationUnit.cursorAt(43, 5);
+
+    ASSERT_THAT(cursor.type().canonical().utf8Spelling(), Utf8StringLiteral("long long"));
+}
+
+TEST_F(Cursor, CanonicalTypeCStringSpelling)
+{
+    auto cursor = translationUnit.cursorAt(43, 5);
+
+    auto spelling = cursor.type().canonical().spelling();
+
+    ASSERT_THAT(spelling.cString(), StrEq("long long"));
+}
+
+TEST_F(Cursor, CanonicalTypeIsNotType)
+{
+    auto cursor = translationUnit.cursorAt(43, 5);
+
+    ASSERT_THAT(cursor.type().canonical(), Not(cursor.type()));
+}
+
+TEST_F(Cursor, TypeDeclartionIsAlias)
+{
+    auto declarationCursor = translationUnit.cursorAt(41, 5);
+    auto lintCursor = translationUnit.cursorAt(39, 11);
+
+    ASSERT_THAT(declarationCursor.type().declaration().type(), lintCursor.type());
+}
+
+TEST_F(Cursor, TypeIsConstantWithoutAliasLookup)
+{
+    auto cursor = translationUnit.cursorAt(45, 16);
+
+    ASSERT_TRUE(cursor.type().isConstant());
+}
+
+TEST_F(Cursor, ClassIsCompoundType)
+{
+    auto cursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 10, 7);
+
+    ASSERT_TRUE(cursor.isCompoundType());
+}
+
+TEST_F(Cursor, StructIsCompoundType)
+{
+    auto cursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 28, 8);
+
+    ASSERT_TRUE(cursor.isCompoundType());
+}
+
+TEST_F(Cursor, UnionIsCompoundType)
+{
+    auto cursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 33, 7);
+
+    ASSERT_TRUE(cursor.isCompoundType());
+}
+
+TEST_F(Cursor, IsDeclaration)
+{
+    auto cursor = translationUnit.cursorAt(41, 10);
+
+    ASSERT_TRUE(cursor.isDeclaration());
+}
+
+TEST_F(Cursor, SemanticParent)
+{
+    auto cursor = translationUnit.cursorAt(43, 6);
+    auto expectedSemanticParent = translationUnit.cursorAt(36, 18);
+
+    auto semanticParent = cursor.semanticParent();
+
+    ASSERT_THAT(semanticParent, expectedSemanticParent);
+}
+
+TEST_F(Cursor, IsLocalVariableInMethod)
+{
+    auto cursor = translationUnit.cursorAt(20, 9);
+
+    ASSERT_TRUE(cursor.isLocalVariable());
+}
+
+TEST_F(Cursor, IsLocalVariableInStaticFunction)
+{
+    auto cursor = translationUnit.cursorAt(43, 5);
+
+    ASSERT_TRUE(cursor.isLocalVariable());
+}
+
+TEST_F(Cursor, IsLocalVariableInTemplateFunction)
+{
+    auto cursor = translationUnit.cursorAt(52, 7);
+
+    ASSERT_TRUE(cursor.isLocalVariable());
+}
+
+TEST_F(Cursor, IsLocalVariableInConversionOperator)
+{
+    auto cursor = translationUnit.cursorAt(57, 9);
+
+    ASSERT_TRUE(cursor.isLocalVariable());
+}
+
+TEST_F(Cursor, IsLocalVariableInOperator)
+{
+    auto cursor = translationUnit.cursorAt(62, 9);
+
+    ASSERT_TRUE(cursor.isLocalVariable());
+}
+
+TEST_F(Cursor, IsLocalVariableInConstructor)
+{
+    auto cursor = translationUnit.cursorAt(13, 9);
+
+    ASSERT_TRUE(cursor.isLocalVariable());
+}
+
+TEST_F(Cursor, IsLocalVariableInDestructor)
+{
+    auto cursor = translationUnit.cursorAt(69, 9);
+
+    ASSERT_TRUE(cursor.isLocalVariable());
+}
+
+TEST_F(Cursor, FindFunctionCaller)
+{
+    auto functionCursor = translationUnit.cursorAt(92, 24);
+    auto structCursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 28, 8);
+
+    ASSERT_THAT(functionCursor.functionBaseDeclaration(), structCursor);
+}
+
+TEST_F(Cursor, FindFunctionCallerPointer)
+{
+    auto functionCursor = translationUnit.cursorAt(79, 25);
+    auto structCursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 28, 8);
+
+    ASSERT_THAT(functionCursor.functionBaseDeclaration(), structCursor);
+}
+
+TEST_F(Cursor, FindFunctionCallerThis)
+{
+    auto functionCursor = translationUnit.cursorAt(106, 5);
+    auto structCursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 38, 8);
+
+    ASSERT_THAT(functionCursor.functionBaseDeclaration(), structCursor);
+}
+
+TEST_F(Cursor, NonPointerTypeForValue)
+{
+    auto variableCursor = translationUnit.cursorAt(101, 10);
+    auto variablePointerCursor = translationUnit.cursorAt(100, 11);
+
+    ASSERT_THAT(variableCursor.nonPointerTupe(), variablePointerCursor.nonPointerTupe());
+}
+
+TEST_F(Cursor, HasFinalAttributeInFunction)
+{
+    auto cursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 30, 18);
+
+    ASSERT_TRUE(cursor.hasFinalFunctionAttribute());
+}
+
+TEST_F(Cursor, HasNotFinalAttributeInFunction)
+{
+    auto cursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 15, 17);
+
+    ASSERT_FALSE(cursor.hasFinalFunctionAttribute());
+}
+
+TEST_F(Cursor, HasFinalAttributeInClass)
+{
+    auto cursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 28, 8);
+
+    ASSERT_TRUE(cursor.hasFinalClassAttribute());
+}
+
+TEST_F(Cursor, HasNotFinaAttributeInClass)
+{
+    auto cursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 38, 8);
+
+    ASSERT_FALSE(cursor.hasFinalClassAttribute());
+}
+
+TEST_F(Cursor, HasOutputValues)
+{
+    auto callExpressionCursor = translationUnit.cursorAt(117, 19);
+    auto outputArgumentExpectedCursor = translationUnit.cursorAt(117, 20);
+
+    auto outputArguments = callExpressionCursor.outputArguments();
+
+    ASSERT_THAT(outputArguments.size(), 1);
+    ASSERT_THAT(outputArguments[0], outputArgumentExpectedCursor);
+}
+
+TEST_F(Cursor, HasOnlyInputValues)
+{
+    auto callExpressionCursor = translationUnit.cursorAt(118, 18);
+
+    auto outputArguments = callExpressionCursor.outputArguments();
+
+    ASSERT_THAT(outputArguments, IsEmpty());
+}
+
+TEST_F(Cursor, ArgumentCountIsZero)
+{
+    auto cursor = translationUnit.cursorAt(121, 23);
+
+    auto count = cursor.type().argumentCount();
+
+    ASSERT_THAT(count, 0);
+}
+
+TEST_F(Cursor, ArgumentCountIsTwo)
+{
+    auto cursor = translationUnit.cursorAt(122, 22);
+
+    auto count = cursor.type().argumentCount();
+
+    ASSERT_THAT(count, 2);
+}
+
+TEST_F(Cursor, ArgumentOneIsValue)
+{
+    auto callExpressionCursor = translationUnit.cursorAt(122, 22);
+
+    auto argument = callExpressionCursor.type().argument(0);
+
+    ASSERT_FALSE(argument.isConstant());
+    ASSERT_THAT(argument.kind(), CXType_Int);
+}
+
+TEST_F(Cursor, ArgumentTwoIsLValueReference)
+{
+    auto callExpressionCursor = translationUnit.cursorAt(122, 22);
+
+    auto argument = callExpressionCursor.type().argument(1);
+
+    ASSERT_THAT(argument.kind(), CXType_LValueReference);
+}
+
+TEST_F(Cursor, ArgumentTwoIsConstantReference)
+{
+    auto callExpressionCursor = translationUnit.cursorAt(122, 22);
+
+    auto argumentPointee = callExpressionCursor.type().argument(1);
+
+    ASSERT_TRUE(argumentPointee.isConstantReference());
+}
+
+TEST_F(Cursor, CursorArgumentCount)
+{
+    auto cursor = translationUnit.cursorAt(117, 19);
+
+    ASSERT_THAT(cursor.kind(), CXCursor_CallExpr);
+    ASSERT_THAT(cursor.argumentCount(), 4);
+}
+
+TEST_F(Cursor, CursorArgumentInputValue)
+{
+    auto callExpressionCursor = translationUnit.cursorAt(117, 19);
+    auto declarationReferenceExpressionCursor = translationUnit.cursorAt(117, 20);
+
+    ASSERT_THAT(callExpressionCursor.argument(0), declarationReferenceExpressionCursor);
+}
+
+TEST_F(Cursor, IsConstantLValueReference)
+{
+    auto callExpressionCursor = translationUnit.cursorAt(125, 26);
+
+    auto argument = callExpressionCursor.type().argument(0);
+
+    ASSERT_TRUE(argument.isConstantReference());
+}
+
+TEST_F(Cursor, LValueReferenceIsNotConstantLValueReference)
+{
+    auto callExpressionCursor = translationUnit.cursorAt(124, 21);
+
+    auto argument = callExpressionCursor.type().argument(0);
+
+    ASSERT_FALSE(argument.isConstantReference());
+}
+
+TEST_F(Cursor, ValueIsNotConstantLValueReference)
+{
+    auto callExpressionCursor = translationUnit.cursorAt(123, 18);
+
+    auto argument = callExpressionCursor.type().argument(0);
+
+    ASSERT_FALSE(argument.isConstantReference());
+}
+
+TEST_F(Cursor, PointerToConstantNotConstantLValueReference)
+{
+    auto callExpressionCursor = translationUnit.cursorAt(126, 20);
+
+    auto argument = callExpressionCursor.type().argument(0);
+
+    ASSERT_FALSE(argument.isConstantReference());
+}
+
+TEST_F(Cursor, IsLValueReference)
+{
+    auto callExpressionCursor = translationUnit.cursorAt(124, 21);
+
+    auto argument = callExpressionCursor.type().argument(0);
+
+    ASSERT_TRUE(argument.isLValueReference());
+}
+
+TEST_F(Cursor, ConstantLValueReferenceIsLValueReference)
+{
+    auto callExpressionCursor = translationUnit.cursorAt(125, 26);
+
+    auto argument = callExpressionCursor.type().argument(0);
+
+    ASSERT_TRUE(argument.isLValueReference());
+}
+
+TEST_F(Cursor, ValueIsNotLValueReference)
+{
+    auto callExpressionCursor = translationUnit.cursorAt(123, 18);
+
+    auto argument = callExpressionCursor.type().argument(0);
+
+    ASSERT_FALSE(argument.isLValueReference());
+}
+
+TEST_F(Cursor, PointerIsNotLValueReference)
+{
+    auto callExpressionCursor = translationUnit.cursorAt(126, 20);
+
+    auto argument = callExpressionCursor.type().argument(0);
+
+    ASSERT_FALSE(argument.isLValueReference());
+}
+
+TEST_F(Cursor, PointerToConstant)
+{
+    auto callExpressionCursor = translationUnit.cursorAt(126, 20);
+
+    auto argument = callExpressionCursor.type().argument(0);
+
+    ASSERT_TRUE(argument.isPointerToConstant());
+}
+
+TEST_F(Cursor, ValueIsNotPointerToConstant)
+{
+    auto callExpressionCursor = translationUnit.cursorAt(123, 18);
+
+    auto argument = callExpressionCursor.type().argument(0);
+
+    ASSERT_FALSE(argument.isPointerToConstant());
+}
+
+TEST_F(Cursor, PointerNotPointerToConstant)
+{
+    auto callExpressionCursor = translationUnit.cursorAt(127, 13);
+
+    auto argument = callExpressionCursor.type().argument(0);
+
+    ASSERT_FALSE(argument.isPointerToConstant());
+}
+
+TEST_F(Cursor, ConstantLValueReferenceIsNotPointerToConstant)
+{
+    auto callExpressionCursor = translationUnit.cursorAt(125, 26);
+
+    auto argument = callExpressionCursor.type().argument(0);
+
+    ASSERT_FALSE(argument.isPointerToConstant());
+}
+
+TEST_F(Cursor, IsConstantPointer)
+{
+    auto callExpressionCursor = translationUnit.cursorAt(128, 21);
+
+    auto argument = callExpressionCursor.type().argument(0);
+
+    ASSERT_TRUE(argument.isConstantPointer());
+}
+
+TEST_F(Cursor, PointerToConstantIsNotConstantPointer)
+{
+    auto callExpressionCursor = translationUnit.cursorAt(126, 20);
+
+    auto argument = callExpressionCursor.type().argument(0);
+
+    ASSERT_FALSE(argument.isConstantPointer());
+}
+
+TEST_F(Cursor, ConstValueIsNotConstantPointer)
+{
+    auto callExpressionCursor = translationUnit.cursorAt(129, 23);
+
+    auto argument = callExpressionCursor.type().argument(0);
+
+    ASSERT_FALSE(argument.isConstantPointer());
+}
+
+TEST_F(Cursor, PointerToConstantIsReferencingConstant)
+{
+    auto callExpressionCursor = translationUnit.cursorAt(126, 20);
+
+    auto argument = callExpressionCursor.type().argument(0);
+
+    ASSERT_TRUE(argument.isReferencingConstant());
+}
+
+TEST_F(Cursor, ConstantReferenceIsReferencingConstant)
+{
+    auto callExpressionCursor = translationUnit.cursorAt(125, 26);
+
+    auto argument = callExpressionCursor.type().argument(0);
+
+    ASSERT_TRUE(argument.isReferencingConstant());
+}
+
+TEST_F(Cursor, LValueReferenceIsNotReferencingConstant)
+{
+    auto callExpressionCursor = translationUnit.cursorAt(124, 21);
+
+    auto argument = callExpressionCursor.type().argument(0);
+
+    ASSERT_FALSE(argument.isReferencingConstant());
+}
+
+TEST_F(Cursor, ValueIsNotReferencingConstant)
+{
+    auto callExpressionCursor = translationUnit.cursorAt(123, 18);
+
+    auto argument = callExpressionCursor.type().argument(0);
+
+    ASSERT_FALSE(argument.isReferencingConstant());
+}
+
+TEST_F(Cursor, PointerIsNotRefencingConstant)
+{
+    auto callExpressionCursor = translationUnit.cursorAt(127, 13);
+
+    auto argument = callExpressionCursor.type().argument(0);
+
+    ASSERT_FALSE(argument.isReferencingConstant());
+}
+
+TEST_F(Cursor, PointerIsOutputParameter)
+{
+    auto callExpressionCursor = translationUnit.cursorAt(127, 13);
+
+    auto argument = callExpressionCursor.type().argument(0);
+
+    ASSERT_TRUE(argument.isOutputParameter());
+}
+
+TEST_F(Cursor, ConstantReferenceIsNotOutputParameter)
+{
+    auto callExpressionCursor = translationUnit.cursorAt(125, 26);
+
+    auto argument = callExpressionCursor.type().argument(0);
+
+    ASSERT_FALSE(argument.isOutputParameter());
+}
+
+TEST_F(Cursor, PointerToConstantIsNotOutputParameter)
+{
+    auto callExpressionCursor = translationUnit.cursorAt(126, 20);
+
+    auto argument = callExpressionCursor.type().argument(0);
+
+    ASSERT_FALSE(argument.isOutputParameter()) << argument.isConstant() << argument.pointeeType().isConstant();
+}
+
+TEST_F(Cursor, ConstantPointerIsNotOutputParameter)
+{
+    auto callExpressionCursor = translationUnit.cursorAt(128, 21);
+
+    auto argument = callExpressionCursor.type().argument(0);
+
+    ASSERT_TRUE(argument.isOutputParameter());
+}
+
+TEST_F(Cursor, ReferenceIsOutputParameter)
+{
+    auto callExpressionCursor = translationUnit.cursorAt(124, 21);
+
+    auto argument = callExpressionCursor.type().argument(0);
+
+    ASSERT_TRUE(argument.isOutputParameter());
+}
+
+TEST_F(Cursor, ConstReferenceIsNotOutputParameter)
+{
+    auto callExpressionCursor = translationUnit.cursorAt(125, 26);
+
+    auto argument = callExpressionCursor.type().argument(0);
+
+    ASSERT_FALSE(argument.isOutputParameter());
+}
+
+Data *Cursor::d;
+
+void Cursor::SetUpTestCase()
+{
+    d = new Data;
+}
+
+void Cursor::TearDownTestCase()
+{
+    delete d;
+    d = nullptr;
+}
+
+}
diff --git a/tests/unit/unittest/data/cursor.cpp b/tests/unit/unittest/data/cursor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a492867dd6bd51a2732db6bfd5d2b30cb42e4c83
--- /dev/null
+++ b/tests/unit/unittest/data/cursor.cpp
@@ -0,0 +1,129 @@
+#include "cursor.h"
+
+void function(int x)
+{
+
+}
+
+namespace Namespace
+{
+SuperClass::SuperClass(int x) noexcept
+  : y(x)
+{
+    int LocalVariable;
+}
+
+int SuperClass::Method()
+{
+    Method();
+    AbstractVirtualMethod(y);
+    int LocalVariable;
+    return y;
+}
+
+int SuperClass::VirtualMethod(int z)
+{
+    AbstractVirtualMethod(z);
+
+    return y;
+}
+
+bool SuperClass::ConstMethod() const
+{
+    return y;
+}
+
+void SuperClass::StaticMethod()
+{
+    using longint = long long int;
+    using lint = longint;
+
+    lint foo;
+
+    foo = 30;
+
+    const lint bar = 20;
+}
+}
+
+template <class T>
+void TemplateFunction(T LocalVariableParameter)
+{
+    T LocalVariable;
+}
+
+Namespace::SuperClass::operator int() const
+{
+    int LocalVariable;
+}
+
+int Namespace::SuperClass::operator ++() const
+{
+    int LocalVariable;
+
+    return LocalVariable;
+}
+
+Namespace::SuperClass::~SuperClass()
+{
+    int LocalVariable;
+}
+
+void Struct::FinalVirtualMethod()
+{
+
+}
+
+void f1(Struct *FindFunctionCaller)
+{
+    FindFunctionCaller->FinalVirtualMethod();
+}
+
+void f2(){
+    Struct *s = new Struct;
+
+    f1(s);
+}
+
+void f3()
+{
+    auto FindFunctionCaller = Struct();
+
+    FindFunctionCaller.FinalVirtualMethod();
+}
+
+
+void f4()
+{
+    Struct s;
+
+    auto *sPointer = &s;
+    auto sValue = s;
+}
+
+void NonFinalStruct::function()
+{
+    FinalVirtualMethod();
+}
+
+void OutputFunction(int &out, int in = 1, const int &in2=2, int *out2=nullptr);
+void InputFunction(const int &value);
+
+void f5()
+{
+    int OutputValue;
+    int InputValue = 20;
+
+    OutputFunction(OutputValue);
+    InputFunction(InputValue);
+}
+
+void ArgumentCountZero();
+void ArgumentCountTwo(int one, const int &two);
+void IntegerValue(int);
+void LValueReference(int &);
+void ConstLValueReference(const int &);
+void PointerToConst(const int *);
+void Pointer(int *);
+void ConstantPointer(int *const);
+void ConstIntegerValue(const int);
diff --git a/tests/unit/unittest/data/cursor.h b/tests/unit/unittest/data/cursor.h
new file mode 100644
index 0000000000000000000000000000000000000000..3e9e9a2bfb993b8fc1625d30a05e0ebd50ff4865
--- /dev/null
+++ b/tests/unit/unittest/data/cursor.h
@@ -0,0 +1,42 @@
+
+
+
+namespace Namespace
+{
+class SuperClass;
+/**
+ * A brief comment
+ */
+class SuperClass
+{
+    SuperClass() = default;
+    SuperClass(int x) noexcept;
+    int Method();
+    virtual int VirtualMethod(int z);
+    virtual int AbstractVirtualMethod(int z) = 0;
+    bool ConstMethod() const;
+    static void StaticMethod();
+    operator int() const;
+    int operator ++() const;
+    ~SuperClass();
+
+private:
+    int y;
+};
+}
+
+struct Struct final
+{
+    virtual void FinalVirtualMethod() final;
+};
+
+union Union
+{
+
+};
+
+struct NonFinalStruct
+{
+    virtual void FinalVirtualMethod() final;
+    void function();
+};
diff --git a/tests/unit/unittest/data/highlightinginformations.cpp b/tests/unit/unittest/data/highlightinginformations.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d651fd65e1c19bb48bd9a391e5fd7eb117d3fe85
--- /dev/null
+++ b/tests/unit/unittest/data/highlightinginformations.cpp
@@ -0,0 +1,385 @@
+auto *Variable       = "Variable";
+auto *u8Variable     = u8"Variable";
+auto *rawVariable    = R"(Variable)";
+auto Character       = 'c';
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+auto integer         = 1;
+auto numFloat        = 1.2f;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+int function(int x)
+{
+    return x;
+}
+
+struct Foo
+{
+    void memberFunction() {}
+};
+
+int functionDeclaration(int x);
+
+struct Foo2
+{
+    void memberFunction();
+};
+
+void f()
+{
+    function(1);
+}
+
+struct ConversionFunction {
+    operator Foo();
+    operator int();
+};
+
+void TypeReference()
+{
+    Foo foo;
+}
+
+void LocalVariableDeclaration()
+{
+    Foo foo;
+
+    foo.memberFunction();
+}
+
+void LocalVariableFunctionArgument(Foo &foo)
+{
+    foo.memberFunction();
+}
+
+struct Foo3 {
+    int ClassMember;
+
+    void ClassMemberReference()
+    {
+        ClassMember++;
+    }
+};
+
+struct Foo4
+{
+    void MemberFunctionReference();
+
+    void function()
+    {
+        MemberFunctionReference();
+    }
+};
+
+struct Foo5
+{
+    void StaticMethod();
+
+    void function()
+    {
+        Foo5::StaticMethod();
+    }
+};
+
+enum Enumeration
+{
+    Enumerator
+};
+
+void f2()
+{
+    Enumeration enumeration;
+
+    enumeration = Enumerator;
+}
+
+class ForwardReference;
+
+class Class
+{ public:
+    Class();
+    ~Class();
+};
+
+ForwardReference *f3()
+{
+    Class ConstructorReference;
+
+    return 0;
+}
+
+union Union
+{
+
+};
+
+Union UnionDeclarationReference;
+
+
+
+
+
+
+
+
+
+namespace NameSpace {
+struct StructInNameSpace {};
+}
+
+namespace NameSpaceAlias = NameSpace;
+
+NameSpace::StructInNameSpace foo6;
+
+class BaseClass {
+public:
+    virtual void VirtualFunction();
+    virtual void FinalVirtualFunction();
+};
+
+
+void f8()
+{
+    BaseClass NonVirtualFunctionCall;
+    NonVirtualFunctionCall.VirtualFunction();
+
+    BaseClass *NonVirtualFunctionCallPointer = new BaseClass();
+    NonVirtualFunctionCallPointer->VirtualFunction();
+}
+
+class DerivedClass : public BaseClass
+{public:
+    void VirtualFunction() override;
+    void FinalVirtualFunction() final;
+};
+
+void f8(BaseClass *VirtualFunctionCallPointer)
+{
+    VirtualFunctionCallPointer->VirtualFunction();
+}
+
+class FinalClass final : public DerivedClass
+{
+    void FinalClassThisCall();
+};
+
+void f8(DerivedClass *FinalVirtualFunctionCallPointer)
+{
+    FinalVirtualFunctionCallPointer->FinalVirtualFunction();
+}
+
+void f9(BaseClass *NonFinalVirtualFunctionCallPointer)
+{
+    NonFinalVirtualFunctionCallPointer->FinalVirtualFunction();
+}
+
+void f10(FinalClass *ClassFinalVirtualFunctionCallPointer)
+{
+    ClassFinalVirtualFunctionCallPointer->VirtualFunction();
+}
+
+class Operator {
+public:
+    Operator operator+=(const Operator &first);
+};
+
+Operator operator+(const Operator &first, const Operator &second);
+
+void f10()
+{
+    auto PlusOperator = Operator() + Operator();
+    Operator PlusAssignOperator;
+    PlusAssignOperator += Operator();
+}
+
+/* Comment */
+
+#define PreprocessorDefinition Class
+#define MacroDefinition(a,b) ((a)>(b)?(a):(b))
+
+void f11()
+{
+    MacroDefinition(2, 4);
+}
+
+#include "highlightinginformations.h"
+
+void f12() {
+GOTO_LABEL:
+
+    goto GOTO_LABEL;
+}
+
+template <class T>
+void TemplateFunction(T v)
+{
+    T XXXXX = v;
+}
+void TemplateReference()
+{
+    TemplateFunction(1);
+//    std::vector<int> TemplateIntance;
+}
+
+
+
+
+template <class T>
+class TemplateFoo {};
+
+
+template <class TemplateTypeParameter = Foo, int NonTypeTemplateParameter = 1, template <class> class TemplateTemplateParameter = TemplateFoo>
+void TemplateFunction(TemplateTypeParameter TemplateParameter)
+{
+    TemplateTypeParameter TemplateTypeParameterReference;
+    auto NonTypeTemplateParameterReference = NonTypeTemplateParameter;
+    TemplateTemplateParameter<TemplateTypeParameter> TemplateTemplateParameterReference;
+}
+
+
+
+void FinalClass::FinalClassThisCall()
+{
+    VirtualFunction();
+}
+
+
+void OutputParameter(int &one, const int &two, int *three=0);
+
+void f12()
+{
+    int One;
+    OutputParameter(One, 2);
+}
+
+#include <highlightinginformations.h>
+
+#define FOREACH(variable, container) \
+    variable; \
+    auto x = container;
+
+#define foreach2 FOREACH
+
+#include <initializer_list>
+
+void f13()
+{
+    auto container = 1;
+    foreach2(int index, container);
+}
+
+class SecondArgumentInMacroExpansionIsField {
+    int container = 1;
+
+    void f()
+    {
+        foreach2(int index, container);
+    }
+};
+
+typedef unsigned uint32;
+
+enum EnumerationType : uint32
+{
+    Other = 0,
+};
+
+
+struct TypeInCast {
+    void function();
+};
+
+void f14()
+{
+    static_cast<void (TypeInCast::*)()>(&TypeInCast::function);
+    reinterpret_cast<void (TypeInCast::*)()>(&TypeInCast::function);
+}
+
+using IntegerAlias = int;
+using SecondIntegerAlias = IntegerAlias;
+using IntegerTypedef = int;
+using Function = void (*)();
+
+
+
+void f15()
+{
+    IntegerAlias integerAlias;
+    SecondIntegerAlias secondIntegerAlias;
+    IntegerTypedef integerTypedef;
+    Function();
+}
+
+class FriendFoo
+{
+public:
+    friend class FooFriend;
+    friend bool operator==(const FriendFoo &first, const FriendFoo &second);
+};
+
+class FieldInitialization
+{
+public:
+    FieldInitialization() :
+        member(0)
+    {}
+
+    int member;
+};
+
+template<class Type>
+void TemplateFunctionCall(Type type)
+{
+    type + type;
+}
+
+void f16()
+{
+    TemplateFunctionCall(1);
+}
+
+
+template <typename T>
+class TemplatedType
+{
+    T value = T();
+};
+
+void f17()
+{
+    TemplatedType<int> TemplatedTypeDeclaration;
+}
diff --git a/tests/unit/unittest/data/highlightinginformations.h b/tests/unit/unittest/data/highlightinginformations.h
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/tests/unit/unittest/data/skippedsourceranges.cpp b/tests/unit/unittest/data/skippedsourceranges.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..775393fcedcb2dac890cb76b9327ab8146b418dd
--- /dev/null
+++ b/tests/unit/unittest/data/skippedsourceranges.cpp
@@ -0,0 +1,19 @@
+#if 0
+
+void f();
+
+#endif
+
+#ifndef BLAH
+class Class
+{
+
+};
+#endif
+
+#ifdef BLAH
+class Class
+{
+
+};
+#endif
diff --git a/tests/unit/unittest/highlightinginformationstest.cpp b/tests/unit/unittest/highlightinginformationstest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c09f12cc1704ac381e8f6440014a428bf9fd6255
--- /dev/null
+++ b/tests/unit/unittest/highlightinginformationstest.cpp
@@ -0,0 +1,902 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company.  For licensing terms and
+** conditions see http://www.qt.io/terms-conditions.  For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights.  These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include <cursor.h>
+#include <clangbackendipc_global.h>
+#include <clangstring.h>
+#include <projectpart.h>
+#include <projects.h>
+#include <sourcelocation.h>
+#include <sourcerange.h>
+#include <highlightinginformation.h>
+#include <highlightinginformations.h>
+#include <translationunit.h>
+#include <translationunits.h>
+#include <unsavedfiles.h>
+
+#include <gmock/gmock.h>
+#include <gmock/gmock-matchers.h>
+#include <gtest/gtest.h>
+#include "gtest-qt-printing.h"
+
+using ClangBackEnd::Cursor;
+using ClangBackEnd::HighlightingInformation;
+using ClangBackEnd::HighlightingInformations;
+using ClangBackEnd::HighlightingType;
+using ClangBackEnd::TranslationUnit;
+using ClangBackEnd::UnsavedFiles;
+using ClangBackEnd::ProjectPart;
+using ClangBackEnd::TranslationUnits;
+using ClangBackEnd::ClangString;
+using ClangBackEnd::SourceRange;
+
+using testing::PrintToString;
+using testing::IsNull;
+using testing::NotNull;
+using testing::Gt;
+using testing::Contains;
+using testing::EndsWith;
+using testing::AllOf;
+using testing::Not;
+using testing::IsEmpty;
+using testing::SizeIs;
+
+namespace {
+
+MATCHER_P4(IsHighlightingInformation, line, column, length, type,
+           std::string(negation ? "isn't " : "is ")
+           + PrintToString(HighlightingInformation(line, column, length, type))
+           )
+{
+    const HighlightingInformation expected(line, column, length, type);
+
+    return arg == expected;
+}
+
+MATCHER_P(HasType, type,
+          std::string(negation ? "isn't " : "is ")
+          + PrintToString(type)
+          )
+{
+    return arg.hasType(type);
+}
+
+struct Data {
+    ClangBackEnd::ProjectParts projects;
+    ClangBackEnd::UnsavedFiles unsavedFiles;
+    ClangBackEnd::TranslationUnits translationUnits{projects, unsavedFiles};
+    TranslationUnit translationUnit{Utf8StringLiteral(TESTDATA_DIR"/highlightinginformations.cpp"),
+                ProjectPart(Utf8StringLiteral("projectPartId"), {Utf8StringLiteral("-std=c++14")}),
+                {},
+                translationUnits};
+};
+
+class HighlightingInformations : public ::testing::Test
+{
+public:
+    static void SetUpTestCase();
+    static void TearDownTestCase();
+
+    SourceRange sourceRange(uint line, uint columnEnd) const;
+
+protected:
+    static Data *d;
+    const TranslationUnit &translationUnit = d->translationUnit;
+};
+
+TEST_F(HighlightingInformations, CreateNullInformations)
+{
+    ::HighlightingInformations infos;
+
+    ASSERT_TRUE(infos.isNull());
+}
+
+TEST_F(HighlightingInformations, NullInformationsAreEmpty)
+{
+    ::HighlightingInformations infos;
+
+    ASSERT_TRUE(infos.isEmpty());
+}
+
+TEST_F(HighlightingInformations, IsNotNull)
+{
+    const auto aRange = translationUnit.sourceRange(3, 1, 5, 1);
+
+    const auto infos = translationUnit.highlightingInformationsInRange(aRange);
+
+    ASSERT_FALSE(infos.isNull());
+}
+
+TEST_F(HighlightingInformations, IteratorBeginEnd)
+{
+    const auto aRange = translationUnit.sourceRange(3, 1, 5, 1);
+    const auto infos = translationUnit.highlightingInformationsInRange(aRange);
+
+    const auto endIterator = std::next(infos.begin(), infos.size());
+
+    ASSERT_THAT(infos.end(), endIterator);
+}
+
+TEST_F(HighlightingInformations, Size)
+{
+    const auto range = translationUnit.sourceRange(5, 5, 5, 10);
+
+    const auto infos = translationUnit.highlightingInformationsInRange(range);
+
+    ASSERT_THAT(infos.size(), 1);
+}
+
+TEST_F(HighlightingInformations, DISABLED_Keyword)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(5, 12));
+
+    ASSERT_THAT(infos[0], IsHighlightingInformation(5u, 5u, 6u, HighlightingType::Keyword));
+}
+
+TEST_F(HighlightingInformations, StringLiteral)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(1, 29));
+
+    ASSERT_THAT(infos[4], IsHighlightingInformation(1u, 24u, 10u, HighlightingType::StringLiteral));
+}
+
+TEST_F(HighlightingInformations, Utf8StringLiteral)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(2, 33));
+
+    ASSERT_THAT(infos[4], IsHighlightingInformation(2u, 24u, 12u, HighlightingType::StringLiteral));
+}
+
+TEST_F(HighlightingInformations, RawStringLiteral)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(3, 34));
+
+    ASSERT_THAT(infos[4], IsHighlightingInformation(3u, 24u, 13u, HighlightingType::StringLiteral));
+}
+
+TEST_F(HighlightingInformations, CharacterLiteral)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(4, 28));
+
+    ASSERT_THAT(infos[3], IsHighlightingInformation(4u, 24u, 3u, HighlightingType::StringLiteral));
+}
+
+TEST_F(HighlightingInformations, IntegerLiteral)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(23, 26));
+
+    ASSERT_THAT(infos[3], IsHighlightingInformation(23u, 24u, 1u, HighlightingType::NumberLiteral));
+}
+
+TEST_F(HighlightingInformations, FloatLiteral)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(24, 29));
+
+    ASSERT_THAT(infos[3], IsHighlightingInformation(24u, 24u, 4u, HighlightingType::NumberLiteral));
+}
+
+TEST_F(HighlightingInformations, FunctionDefinition)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(45, 20));
+
+    ASSERT_THAT(infos[1], IsHighlightingInformation(45u, 5u, 8u, HighlightingType::Function));
+}
+
+TEST_F(HighlightingInformations, MemberFunctionDefinition)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(52, 29));
+
+    ASSERT_THAT(infos[1], IsHighlightingInformation(52u, 10u, 14u, HighlightingType::Function));
+}
+
+TEST_F(HighlightingInformations, FunctionDeclaration)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(55, 32));
+
+    ASSERT_THAT(infos[1], IsHighlightingInformation(55u, 5u, 19u, HighlightingType::Function));
+}
+
+TEST_F(HighlightingInformations, MemberFunctionDeclaration)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(59, 27));
+
+    ASSERT_THAT(infos[1], IsHighlightingInformation(59u, 10u, 14u, HighlightingType::Function));
+}
+
+TEST_F(HighlightingInformations, MemberFunctionReference)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(104, 35));
+
+    ASSERT_THAT(infos[0], IsHighlightingInformation(104u, 9u, 23u, HighlightingType::Function));
+}
+
+TEST_F(HighlightingInformations, FunctionCall)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(64, 16));
+
+    ASSERT_THAT(infos[0], IsHighlightingInformation(64u, 5u, 8u, HighlightingType::Function));
+}
+
+TEST_F(HighlightingInformations, TypeConversionFunction)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(68, 20));
+
+    ASSERT_THAT(infos[1], IsHighlightingInformation(68u, 14u, 3u, HighlightingType::Type));
+}
+
+TEST_F(HighlightingInformations, InbuiltTypeConversionFunction)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(69, 20));
+
+    ASSERT_THAT(infos[1], IsHighlightingInformation(69u, 14u, 3u, HighlightingType::Keyword));
+}
+
+TEST_F(HighlightingInformations, TypeReference)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(74, 13));
+
+    ASSERT_THAT(infos[0], IsHighlightingInformation(74u, 5u, 3u, HighlightingType::Type));
+}
+
+TEST_F(HighlightingInformations, LocalVariable)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(79, 13));
+
+    ASSERT_THAT(infos[1], IsHighlightingInformation(79u, 9u, 3u, HighlightingType::LocalVariable));
+}
+
+TEST_F(HighlightingInformations, LocalVariableDeclaration)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(79, 13));
+
+    ASSERT_THAT(infos[1], IsHighlightingInformation(79u, 9u, 3u, HighlightingType::LocalVariable));
+}
+
+TEST_F(HighlightingInformations, LocalVariableReference)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(81, 26));
+
+    ASSERT_THAT(infos[0], IsHighlightingInformation(81u, 5u, 3u, HighlightingType::LocalVariable));
+}
+
+TEST_F(HighlightingInformations, LocalVariableFunctionArgumentDeclaration)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(84, 45));
+
+    ASSERT_THAT(infos[5], IsHighlightingInformation(84u, 41u, 3u, HighlightingType::LocalVariable));
+}
+
+TEST_F(HighlightingInformations, LocalVariableFunctionArgumentReference)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(86, 26));
+
+    ASSERT_THAT(infos[0], IsHighlightingInformation(86u, 5u, 3u, HighlightingType::LocalVariable));
+}
+
+TEST_F(HighlightingInformations, ClassVariableDeclaration)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(90, 21));
+
+    ASSERT_THAT(infos[1], IsHighlightingInformation(90u, 9u, 11u, HighlightingType::Field));
+}
+
+TEST_F(HighlightingInformations, ClassVariableReference)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(94, 23));
+
+    ASSERT_THAT(infos[0], IsHighlightingInformation(94u, 9u, 11u, HighlightingType::Field));
+}
+
+TEST_F(HighlightingInformations, StaticMethodDeclaration)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(110, 25));
+
+    ASSERT_THAT(infos[1], IsHighlightingInformation(110u, 10u, 12u, HighlightingType::Function));
+}
+
+TEST_F(HighlightingInformations, StaticMethodReference)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(114, 30));
+
+    ASSERT_THAT(infos[2], IsHighlightingInformation(114u, 15u, 12u, HighlightingType::Function));
+}
+
+TEST_F(HighlightingInformations, Enumeration)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(118, 17));
+
+    ASSERT_THAT(infos[1], HasType(HighlightingType::Enumeration));
+}
+
+TEST_F(HighlightingInformations, Enumerator)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(120, 15));
+
+    ASSERT_THAT(infos[0], HasType(HighlightingType::Enumeration));
+}
+
+TEST_F(HighlightingInformations, EnumerationReferenceDeclarationType)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(125, 28));
+
+    ASSERT_THAT(infos[0], HasType(HighlightingType::Enumeration));
+}
+
+TEST_F(HighlightingInformations, EnumerationReferenceDeclarationVariable)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(125, 28));
+
+    ASSERT_THAT(infos[1], HasType(HighlightingType::LocalVariable));
+}
+
+TEST_F(HighlightingInformations, EnumerationReference)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(127, 30));
+
+    ASSERT_THAT(infos[0], HasType(HighlightingType::LocalVariable));
+}
+
+TEST_F(HighlightingInformations, EnumeratorReference)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(127, 30));
+
+    ASSERT_THAT(infos[2], HasType(HighlightingType::Enumeration));
+}
+
+TEST_F(HighlightingInformations, ClassForwardDeclaration)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(130, 12));
+
+    ASSERT_THAT(infos[1], HasType(HighlightingType::Type));
+}
+
+TEST_F(HighlightingInformations, ConstructorDeclaration)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(134, 13));
+
+    ASSERT_THAT(infos[0], HasType(HighlightingType::Function));
+}
+
+TEST_F(HighlightingInformations, DestructorDeclaration)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(135, 15));
+
+    ASSERT_THAT(infos[1], HasType(HighlightingType::Function));
+}
+
+TEST_F(HighlightingInformations, ClassForwardDeclarationReference)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(138, 23));
+
+    ASSERT_THAT(infos[0], HasType(HighlightingType::Type));
+}
+
+TEST_F(HighlightingInformations, ClassTypeReference)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(140, 32));
+
+    ASSERT_THAT(infos[0], HasType(HighlightingType::Type));
+}
+
+TEST_F(HighlightingInformations, ConstructorReferenceVariable)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(140, 32));
+
+    ASSERT_THAT(infos[1], HasType(HighlightingType::LocalVariable));
+}
+
+TEST_F(HighlightingInformations, UnionDeclaration)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(145, 12));
+
+    ASSERT_THAT(infos[1], HasType(HighlightingType::Type));
+}
+
+TEST_F(HighlightingInformations, UnionDeclarationReference)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(150, 33));
+
+    ASSERT_THAT(infos[0], HasType(HighlightingType::Type));
+}
+
+TEST_F(HighlightingInformations, GlobalVariable)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(150, 33));
+
+    ASSERT_THAT(infos[1], HasType(HighlightingType::GlobalVariable));
+}
+
+TEST_F(HighlightingInformations, StructDeclaration)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(50, 11));
+
+    ASSERT_THAT(infos[1], HasType(HighlightingType::Type));
+}
+
+TEST_F(HighlightingInformations, NameSpace)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(160, 22));
+
+    ASSERT_THAT(infos[1], HasType(HighlightingType::Type));
+}
+
+TEST_F(HighlightingInformations, NameSpaceAlias)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(164, 38));
+
+    ASSERT_THAT(infos[1], HasType(HighlightingType::Type));
+}
+
+TEST_F(HighlightingInformations, NameSpaceReference)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(166, 35));
+
+    ASSERT_THAT(infos[0], HasType(HighlightingType::Type));
+}
+
+TEST_F(HighlightingInformations, VirtualFunction)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(170, 35));
+
+    ASSERT_THAT(infos[2], HasType(HighlightingType::VirtualFunction));
+}
+
+TEST_F(HighlightingInformations, DISABLED_NonVirtualFunctionCall)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(177, 46));
+
+    ASSERT_THAT(infos[2], HasType(HighlightingType::Function));
+}
+
+TEST_F(HighlightingInformations, DISABLED_NonVirtualFunctionCallPointer)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(180, 54));
+
+    ASSERT_THAT(infos[2], HasType(HighlightingType::Function));
+}
+
+TEST_F(HighlightingInformations, VirtualFunctionCallPointer)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(192, 51));
+
+    ASSERT_THAT(infos[2], HasType(HighlightingType::VirtualFunction));
+}
+
+TEST_F(HighlightingInformations, FinalVirtualFunctionCallPointer)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(202, 61));
+
+    ASSERT_THAT(infos[2], HasType(HighlightingType::Function));
+}
+
+TEST_F(HighlightingInformations, NonFinalVirtualFunctionCallPointer)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(207, 61));
+
+    ASSERT_THAT(infos[2], HasType(HighlightingType::VirtualFunction));
+}
+
+TEST_F(HighlightingInformations, PlusOperator)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(224, 49));
+
+    ASSERT_THAT(infos[6], HasType(HighlightingType::Operator));
+}
+
+TEST_F(HighlightingInformations, PlusAssignOperator)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(226, 24));
+
+    ASSERT_THAT(infos[1], HasType(HighlightingType::Operator));
+}
+
+TEST_F(HighlightingInformations, Comment)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(229, 14));
+
+    ASSERT_THAT(infos[0], HasType(HighlightingType::Comment));
+}
+
+TEST_F(HighlightingInformations, PreprocessingDirective)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(231, 37));
+
+    ASSERT_THAT(infos[1], HasType(HighlightingType::Preprocessor));
+}
+
+TEST_F(HighlightingInformations, PreprocessorMacroDefinition)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(231, 37));
+
+    ASSERT_THAT(infos[2], HasType(HighlightingType::PreprocessorDefinition));
+}
+
+TEST_F(HighlightingInformations, PreprocessorFunctionMacroDefinition)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(232, 47));
+
+    ASSERT_THAT(infos[2], HasType(HighlightingType::PreprocessorDefinition));
+}
+
+TEST_F(HighlightingInformations, PreprocessorMacroExpansion)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(236, 27));
+
+    ASSERT_THAT(infos[0], HasType(HighlightingType::PreprocessorExpansion));
+}
+
+TEST_F(HighlightingInformations, PreprocessorMacroExpansionArgument)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(236, 27));
+
+    ASSERT_THAT(infos[2], HasType(HighlightingType::NumberLiteral));
+}
+
+TEST_F(HighlightingInformations, PreprocessorInclusionDirective)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(239, 18));
+
+    ASSERT_THAT(infos[1], HasType(HighlightingType::StringLiteral));
+}
+
+TEST_F(HighlightingInformations, GotoLabelStatement)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(242, 12));
+
+    ASSERT_THAT(infos[0], HasType(HighlightingType::Label));
+}
+
+TEST_F(HighlightingInformations, GotoLabelStatementReference)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(244, 21));
+
+    ASSERT_THAT(infos[1], HasType(HighlightingType::Label));
+}
+
+TEST_F(HighlightingInformations, TemplateReference)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(254, 25));
+
+    ASSERT_THAT(infos[0], HasType(HighlightingType::Function));
+}
+
+TEST_F(HighlightingInformations, TemplateTypeParameter)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(265, 135));
+
+    ASSERT_THAT(infos[3], HasType(HighlightingType::Type));
+}
+
+TEST_F(HighlightingInformations, TemplateDefaultParameter)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(265, 135));
+
+    ASSERT_THAT(infos[5], HasType(HighlightingType::Type));
+}
+
+TEST_F(HighlightingInformations, NonTypeTemplateParameter)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(265, 135));
+
+    ASSERT_THAT(infos[8], HasType(HighlightingType::LocalVariable));
+}
+
+TEST_F(HighlightingInformations, NonTypeTemplateParameterDefaultArgument)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(265, 135));
+
+    ASSERT_THAT(infos[10], HasType(HighlightingType::NumberLiteral));
+}
+
+TEST_F(HighlightingInformations, TemplateTemplateParameter)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(265, 135));
+
+    ASSERT_THAT(infos[17], HasType(HighlightingType::Type));
+}
+
+TEST_F(HighlightingInformations, TemplateTemplateParameterDefaultArgument)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(265, 135));
+
+    ASSERT_THAT(infos[19], HasType(HighlightingType::Type));
+}
+
+TEST_F(HighlightingInformations, TemplateFunctionDeclaration)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(266, 63));
+
+    ASSERT_THAT(infos[1], HasType(HighlightingType::Function));
+}
+
+TEST_F(HighlightingInformations, TemplateTypeParameterReference)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(268, 58));
+
+    ASSERT_THAT(infos[0], HasType(HighlightingType::Type));
+}
+
+TEST_F(HighlightingInformations, TemplateTypeParameterDeclarationReference)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(268, 58));
+
+    ASSERT_THAT(infos[1], HasType(HighlightingType::LocalVariable));
+}
+
+TEST_F(HighlightingInformations, NonTypeTemplateParameterReference)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(269, 71));
+
+    ASSERT_THAT(infos[3], HasType(HighlightingType::LocalVariable));
+}
+
+TEST_F(HighlightingInformations, NonTypeTemplateParameterReferenceReference)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(269, 71));
+
+    ASSERT_THAT(infos[1], HasType(HighlightingType::LocalVariable));
+}
+
+TEST_F(HighlightingInformations, TemplateTemplateParameterReference)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(270, 89));
+
+    ASSERT_THAT(infos[0], HasType(HighlightingType::Type));
+}
+
+TEST_F(HighlightingInformations, TemplateTemplateContainerParameterReference)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(270, 89));
+
+    ASSERT_THAT(infos[2], HasType(HighlightingType::Type));
+}
+
+TEST_F(HighlightingInformations, TemplateTemplateParameterReferenceVariable)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(270, 89));
+
+    ASSERT_THAT(infos[4], HasType(HighlightingType::LocalVariable));
+}
+
+TEST_F(HighlightingInformations, ClassFinalVirtualFunctionCallPointer)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(212, 61));
+
+    ASSERT_THAT(infos[2], HasType(HighlightingType::Function));
+}
+
+TEST_F(HighlightingInformations, ClassFinalVirtualFunctionCall)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(277, 23));
+
+    ASSERT_THAT(infos[0], HasType(HighlightingType::Function));
+}
+
+TEST_F(HighlightingInformations, HasFunctionArguments)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(286, 29));
+
+    ASSERT_TRUE(infos[1].hasFunctionArguments());
+}
+
+TEST_F(HighlightingInformations, NoOutputFunctionArguments)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(285, 13));
+
+    auto outputFunctionArguments = infos[1].outputFunctionArguments();
+
+    ASSERT_THAT(outputFunctionArguments, IsEmpty());
+}
+
+TEST_F(HighlightingInformations, DISABLED_OneOutputFunctionArguments)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(285, 13));
+
+    auto outputFunctionArguments = infos[1].outputFunctionArguments();
+
+    ASSERT_THAT(outputFunctionArguments, SizeIs(1));
+}
+
+TEST_F(HighlightingInformations, PreprocessorInclusionDirectiveWithAngleBrackets )
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(289, 38));
+
+    ASSERT_THAT(infos[3], HasType(HighlightingType::StringLiteral));
+}
+
+TEST_F(HighlightingInformations, ArgumentInMacroExpansionIsKeyword)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(302, 36));
+
+    ASSERT_THAT(infos[2], HasType(HighlightingType::Keyword));
+}
+
+TEST_F(HighlightingInformations, DISABLED_FirstArgumentInMacroExpansionIsLocalVariable)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(302, 36));
+
+    ASSERT_THAT(infos[3], HasType(HighlightingType::Invalid));
+}
+
+TEST_F(HighlightingInformations, DISABLED_SecondArgumentInMacroExpansionIsLocalVariable)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(302, 36));
+
+    ASSERT_THAT(infos[5], HasType(HighlightingType::Invalid));
+}
+
+TEST_F(HighlightingInformations, DISABLED_SecondArgumentInMacroExpansionIsField)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(310, 40));
+
+    ASSERT_THAT(infos[5], HasType(HighlightingType::Invalid));
+}
+
+
+TEST_F(HighlightingInformations, DISABLED_EnumerationType)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(316, 30));
+
+    ASSERT_THAT(infos[3], HasType(HighlightingType::Type));
+}
+
+TEST_F(HighlightingInformations, TypeInStaticCast)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(328, 64));
+
+    ASSERT_THAT(infos[4], HasType(HighlightingType::Type));
+}
+
+TEST_F(HighlightingInformations, StaticCastIsKeyword)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(328, 64));
+
+    ASSERT_THAT(infos[0], HasType(HighlightingType::Keyword));
+}
+
+TEST_F(HighlightingInformations, StaticCastPunctationIsInvalid)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(328, 64));
+
+    ASSERT_THAT(infos[1], HasType(HighlightingType::Invalid));
+    ASSERT_THAT(infos[3], HasType(HighlightingType::Invalid));
+    ASSERT_THAT(infos[5], HasType(HighlightingType::Invalid));
+}
+
+TEST_F(HighlightingInformations, TypeInReinterpretCast)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(329, 69));
+
+    ASSERT_THAT(infos[4], HasType(HighlightingType::Type));
+}
+
+TEST_F(HighlightingInformations, IntegerAliasDeclaration)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(333, 41));
+
+    ASSERT_THAT(infos[1], HasType(HighlightingType::Type));
+}
+
+TEST_F(HighlightingInformations, IntegerAlias)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(341, 31));
+
+    ASSERT_THAT(infos[0], HasType(HighlightingType::Type));
+}
+
+TEST_F(HighlightingInformations, SecondIntegerAlias)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(342, 43));
+
+    ASSERT_THAT(infos[0], HasType(HighlightingType::Type));
+}
+
+TEST_F(HighlightingInformations, IntegerTypedef)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(343, 35));
+
+    ASSERT_THAT(infos[0], HasType(HighlightingType::Type));
+}
+
+TEST_F(HighlightingInformations, FunctionAlias)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(344, 16));
+
+    ASSERT_THAT(infos[0], HasType(HighlightingType::Type));
+}
+
+TEST_F(HighlightingInformations, FriendTypeDeclaration)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(350, 28));
+
+    ASSERT_THAT(infos[2], HasType(HighlightingType::Type));
+}
+
+TEST_F(HighlightingInformations, FriendArgumentTypeDeclaration)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(351, 65));
+
+    ASSERT_THAT(infos[6], HasType(HighlightingType::Type));
+}
+
+TEST_F(HighlightingInformations, DISABLED_FriendArgumentDeclaration)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(351, 65));
+
+    ASSERT_THAT(infos[8], HasType(HighlightingType::Invalid));
+}
+
+TEST_F(HighlightingInformations, FieldInitialization)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(358, 18));
+
+    ASSERT_THAT(infos[0], HasType(HighlightingType::Field));
+}
+
+TEST_F(HighlightingInformations, TemplateFunctionCall)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(372, 29));
+
+    ASSERT_THAT(infos[0], HasType(HighlightingType::Function));
+}
+
+TEST_F(HighlightingInformations, TemplatedType)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(377, 21));
+
+    ASSERT_THAT(infos[1], HasType(HighlightingType::Type));
+}
+
+TEST_F(HighlightingInformations, TemplatedTypeDeclaration)
+{
+    const auto infos = translationUnit.highlightingInformationsInRange(sourceRange(384, 49));
+
+    ASSERT_THAT(infos[0], HasType(HighlightingType::Type));
+}
+
+Data *HighlightingInformations::d;
+
+void HighlightingInformations::SetUpTestCase()
+{
+    d = new Data;
+}
+
+void HighlightingInformations::TearDownTestCase()
+{
+    delete d;
+    d = nullptr;
+}
+
+ClangBackEnd::SourceRange HighlightingInformations::sourceRange(uint line, uint columnEnd) const
+{
+    return translationUnit.sourceRange(line, 1, line, columnEnd);
+}
+
+}
diff --git a/tests/unit/unittest/skippedsourcerangestest.cpp b/tests/unit/unittest/skippedsourcerangestest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b37b8726909b671de4f623a6f0bdaad3c4497f02
--- /dev/null
+++ b/tests/unit/unittest/skippedsourcerangestest.cpp
@@ -0,0 +1,159 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company.  For licensing terms and
+** conditions see http://www.qt.io/terms-conditions.  For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights.  These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include <cursor.h>
+#include <clangstring.h>
+#include <projectpart.h>
+#include <projects.h>
+#include <skippedsourceranges.h>
+#include <sourcelocation.h>
+#include <sourcerange.h>
+#include <translationunit.h>
+#include <translationunits.h>
+#include <unsavedfiles.h>
+
+#include <sourcerangecontainer.h>
+
+#include <QVector>
+
+#include <gmock/gmock.h>
+#include <gmock/gmock-matchers.h>
+#include <gtest/gtest.h>
+#include "gtest-qt-printing.h"
+
+using ClangBackEnd::Cursor;
+using ClangBackEnd::TranslationUnit;
+using ClangBackEnd::UnsavedFiles;
+using ClangBackEnd::ProjectPart;
+using ClangBackEnd::TranslationUnits;
+using ClangBackEnd::ClangString;
+using ClangBackEnd::SourceRange;
+using ClangBackEnd::SkippedSourceRanges;
+
+using testing::IsNull;
+using testing::NotNull;
+using testing::Gt;
+using testing::Contains;
+using testing::EndsWith;
+using testing::AllOf;
+using testing::Not;
+using testing::IsEmpty;
+using testing::SizeIs;
+using testing::PrintToString;
+
+namespace {
+
+MATCHER_P4(IsSourceLocation, filePath, line, column, offset,
+           std::string(negation ? "isn't" : "is")
+           + " source location with file path "+ PrintToString(filePath)
+           + ", line " + PrintToString(line)
+           + ", column " + PrintToString(column)
+           + " and offset " + PrintToString(offset)
+           )
+{
+    if (!arg.filePath().endsWith(filePath)
+     || arg.line() != line
+     || arg.column() != column
+     || arg.offset() != offset) {
+        return false;
+    }
+
+    return true;
+}
+
+struct Data {
+    ClangBackEnd::ProjectParts projects;
+    ClangBackEnd::UnsavedFiles unsavedFiles;
+    ClangBackEnd::TranslationUnits translationUnits{projects, unsavedFiles};
+    Utf8String filePath = Utf8StringLiteral(TESTDATA_DIR"/skippedsourceranges.cpp");
+    TranslationUnit translationUnit{filePath,
+                ProjectPart(Utf8StringLiteral("projectPartId"),
+                            {Utf8StringLiteral("-std=c++11"),Utf8StringLiteral("-DBLAH")}),
+                {},
+                translationUnits};
+};
+
+class SkippedSourceRanges : public ::testing::Test
+{
+public:
+    static void SetUpTestCase();
+    static void TearDownTestCase();
+
+protected:
+    static Data *d;
+    const TranslationUnit &translationUnit = d->translationUnit;
+    const Utf8String &filePath = d->filePath;
+    const ::SkippedSourceRanges skippedSourceRanges{d->translationUnit.skippedSourceRanges()};
+};
+
+Data *SkippedSourceRanges::d;
+
+TEST_F(SkippedSourceRanges, RangeWithZero)
+{
+    auto ranges = skippedSourceRanges.sourceRanges();
+
+    ASSERT_THAT(ranges, SizeIs(2));
+}
+
+TEST_F(SkippedSourceRanges, RangeOne)
+{
+    auto ranges = skippedSourceRanges.sourceRanges();
+
+    ASSERT_THAT(ranges[0].start(), IsSourceLocation(filePath, 1, 2, 1));
+    ASSERT_THAT(ranges[0].end(), IsSourceLocation(filePath, 5, 7, 24));
+}
+
+TEST_F(SkippedSourceRanges, RangeTwo)
+{
+    auto ranges = skippedSourceRanges.sourceRanges();
+
+    ASSERT_THAT(ranges[1].start(), IsSourceLocation(filePath, 7, 2, 27));
+    ASSERT_THAT(ranges[1].end(), IsSourceLocation(filePath, 12, 7, 63));
+}
+
+TEST_F(SkippedSourceRanges, RangeContainerSize)
+{
+    auto ranges = skippedSourceRanges.toSourceRangeContainers();
+
+    ASSERT_THAT(ranges, SizeIs(2));
+}
+
+void SkippedSourceRanges::SetUpTestCase()
+{
+    d = new Data;
+}
+
+void SkippedSourceRanges::TearDownTestCase()
+{
+    delete d;
+    d = nullptr;
+}
+
+}
diff --git a/tests/unit/unittest/sourcelocationtest.cpp b/tests/unit/unittest/sourcelocationtest.cpp
index 9db922c282be7b4b423c9ba7d022103fc276d63e..9213d9359c3f10ec64c7d777ebb5d4a292da13e5 100644
--- a/tests/unit/unittest/sourcelocationtest.cpp
+++ b/tests/unit/unittest/sourcelocationtest.cpp
@@ -50,13 +50,13 @@ using ClangBackEnd::ProjectPart;
 using ClangBackEnd::SourceLocation;
 using ClangBackEnd::TranslationUnit;
 using ClangBackEnd::UnsavedFiles;
+
 using testing::EndsWith;
+using testing::Not;
 
 namespace {
 
-class SourceLocation : public ::testing::Test
-{
-protected:
+struct Data {
     ProjectPart projectPart{Utf8StringLiteral("projectPartId")};
     ClangBackEnd::ProjectParts projects;
     ClangBackEnd::UnsavedFiles unsavedFiles;
@@ -68,7 +68,18 @@ protected:
     DiagnosticSet diagnosticSet{translationUnit.diagnostics()};
     Diagnostic diagnostic{diagnosticSet.front()};
     ::SourceLocation sourceLocation{diagnostic.location()};
+};
 
+class SourceLocation : public ::testing::Test
+{
+public:
+    static void SetUpTestCase();
+    static void TearDownTestCase();
+
+protected:
+    static Data *d;
+    const ::SourceLocation &sourceLocation = d->sourceLocation;
+    const TranslationUnit &translationUnit = d->translationUnit;
 };
 
 TEST_F(SourceLocation, FilePath)
@@ -91,4 +102,27 @@ TEST_F(SourceLocation, Offset)
     ASSERT_THAT(sourceLocation.offset(), 18);
 }
 
+TEST_F(SourceLocation, Create)
+{
+    ASSERT_THAT(translationUnit.sourceLocationAt(4, 1), sourceLocation);
+}
+
+TEST_F(SourceLocation, NotEqual)
+{
+    ASSERT_THAT(translationUnit.sourceLocationAt(3, 1), Not(sourceLocation));
+}
+
+Data *SourceLocation::d;
+
+void SourceLocation::SetUpTestCase()
+{
+    d = new Data;
+}
+
+void SourceLocation::TearDownTestCase()
+{
+    delete d;
+    d = nullptr;
+}
+
 }
diff --git a/tests/unit/unittest/sourcerangetest.cpp b/tests/unit/unittest/sourcerangetest.cpp
index 771bd49ccff1d1b806137d4b74e3e5d0356ebbf0..b517c42380434220df0d6b1bf5083f5bc550d763 100644
--- a/tests/unit/unittest/sourcerangetest.cpp
+++ b/tests/unit/unittest/sourcerangetest.cpp
@@ -51,7 +51,9 @@ using ClangBackEnd::UnsavedFiles;
 using ClangBackEnd::Diagnostic;
 using ClangBackEnd::SourceRange;
 using ClangBackEnd::TranslationUnits;
+
 using testing::PrintToString;
+using testing::IsEmpty;
 
 namespace {
 
@@ -73,9 +75,7 @@ MATCHER_P4(IsSourceLocation, filePath, line, column, offset,
     return true;
 }
 
-class SourceRange : public ::testing::Test
-{
-protected:
+struct Data {
     ProjectPart projectPart{Utf8StringLiteral("projectPartId"), {Utf8StringLiteral("-pedantic")}};
     ClangBackEnd::ProjectParts projects;
     ClangBackEnd::UnsavedFiles unsavedFiles;
@@ -90,6 +90,20 @@ protected:
     ::SourceRange sourceRange{diagnostic.ranges().front()};
 };
 
+class SourceRange : public ::testing::Test
+{
+public:
+    static void SetUpTestCase();
+    static void TearDownTestCase();
+
+protected:
+    static Data *d;
+    const ::SourceRange &sourceRange = d->sourceRange;
+    const Diagnostic &diagnostic = d->diagnostic;
+    const Diagnostic &diagnosticWithFilteredOutInvalidRange = d->diagnosticWithFilteredOutInvalidRange;
+    const TranslationUnit &translationUnit = d->translationUnit;
+};
+
 TEST_F(SourceRange, IsNull)
 {
     ::SourceRange sourceRange;
@@ -125,9 +139,34 @@ TEST_F(SourceRange, End)
                                                       44u));
 }
 
+TEST_F(SourceRange, Create)
+{
+    ASSERT_THAT(sourceRange, ::SourceRange(sourceRange.start(), sourceRange.end()));
+}
+
+TEST_F(SourceRange, SourceRangeFromTranslationUnit)
+{
+    auto sourceRangeFromTranslationUnit = translationUnit.sourceRange(8u, 5u, 8u, 6u);
+
+    ASSERT_THAT(sourceRangeFromTranslationUnit, sourceRange);
+}
+
 TEST_F(SourceRange, InvalidRangeIsFilteredOut)
 {
-    ASSERT_TRUE(diagnosticWithFilteredOutInvalidRange.ranges().empty());
+    ASSERT_THAT(diagnosticWithFilteredOutInvalidRange.ranges(), IsEmpty());
+}
+
+Data *SourceRange::d;
+
+void SourceRange::SetUpTestCase()
+{
+    d = new Data;
+}
+
+void SourceRange::TearDownTestCase()
+{
+    delete d;
+    d = nullptr;
 }
 
 }
diff --git a/tests/unit/unittest/unittest.pro b/tests/unit/unittest/unittest.pro
index 193f1caa68e0067d3ca7679b917db2d7fc84680e..6fe2d25f2e2561ef94950d28340c0c2a129fe108 100644
--- a/tests/unit/unittest/unittest.pro
+++ b/tests/unit/unittest/unittest.pro
@@ -53,7 +53,10 @@ SOURCES += \
     translationunittest.cpp \
     unsavedfilestest.cpp \
     utf8test.cpp \
-    senddocumenttrackertest.cpp
+    senddocumenttrackertest.cpp \
+    cursortest.cpp \
+    highlightinginformationstest.cpp \
+    skippedsourcerangestest.cpp
 
 HEADERS += \
     gtest-qt-printing.h \