diff --git a/src/libs/cplusplus/TypeOfExpression.cpp b/src/libs/cplusplus/TypeOfExpression.cpp
index 84d443f3bc29ce7c13b505dcd07250b75c84933b..8be7be2572de0ca8aaffc2817c27b7e689c4ac3c 100644
--- a/src/libs/cplusplus/TypeOfExpression.cpp
+++ b/src/libs/cplusplus/TypeOfExpression.cpp
@@ -138,7 +138,7 @@ QString TypeOfExpression::preprocessedExpression(const QString &expression,
     processEnvironment(documents, thisDocument,
                        &env, &processed);
     const QByteArray code = expression.toUtf8();
-    Preprocessor preproc(0, env);
+    Preprocessor preproc(0, &env);
     const QByteArray preprocessedCode = preproc("<expression>", code);
     return QString::fromUtf8(preprocessedCode.constData(), preprocessedCode.size());
 }
diff --git a/src/libs/cplusplus/pp-engine.cpp b/src/libs/cplusplus/pp-engine.cpp
index dfe4a487a2a5a749d713b53fd03213637ab49391..1f3750b1c2bea362e0037ce654f3743d64edc7e5 100644
--- a/src/libs/cplusplus/pp-engine.cpp
+++ b/src/libs/cplusplus/pp-engine.cpp
@@ -55,8 +55,84 @@
 #include <QtDebug>
 #include <algorithm>
 
+namespace CPlusPlus {
+
+struct Value
+{
+    enum Kind {
+        Kind_Long,
+        Kind_ULong,
+    };
+
+    Kind kind;
+
+    union {
+        long l;
+        unsigned long ul;
+    };
+
+
+    Value()
+        : kind(Kind_Long), l(0)
+    { }
+
+    inline bool is_ulong () const
+    { return kind == Kind_ULong; }
+
+    inline void set_ulong (unsigned long v)
+    {
+        ul = v;
+        kind = Kind_ULong;
+    }
+
+    inline void set_long (long v)
+    {
+        l = v;
+        kind = Kind_Long;
+    }
+
+    inline bool is_zero () const
+    { return l == 0; }
+
+#define PP_DEFINE_BIN_OP(name, op) \
+    inline Value operator op(const Value &other) const \
+    { \
+        Value v = *this; \
+        if (v.is_ulong () || other.is_ulong ()) \
+            v.set_ulong (v.ul op other.ul); \
+        else \
+            v.set_long (v.l op other.l); \
+        return v; \
+    }
+
+    PP_DEFINE_BIN_OP(op_add, +)
+    PP_DEFINE_BIN_OP(op_sub, -)
+    PP_DEFINE_BIN_OP(op_mult, *)
+    PP_DEFINE_BIN_OP(op_div, /)
+    PP_DEFINE_BIN_OP(op_mod, %)
+    PP_DEFINE_BIN_OP(op_lhs, <<)
+    PP_DEFINE_BIN_OP(op_rhs, >>)
+    PP_DEFINE_BIN_OP(op_lt, <)
+    PP_DEFINE_BIN_OP(op_gt, >)
+    PP_DEFINE_BIN_OP(op_le, <=)
+    PP_DEFINE_BIN_OP(op_ge, >=)
+    PP_DEFINE_BIN_OP(op_eq, ==)
+    PP_DEFINE_BIN_OP(op_ne, !=)
+    PP_DEFINE_BIN_OP(op_bit_and, &)
+    PP_DEFINE_BIN_OP(op_bit_or, |)
+    PP_DEFINE_BIN_OP(op_bit_xor, ^)
+    PP_DEFINE_BIN_OP(op_and, &&)
+    PP_DEFINE_BIN_OP(op_or, ||)
+
+#undef PP_DEFINE_BIN_OP
+};
+
+} // end of namespace CPlusPlus
+
+
 using namespace CPlusPlus;
 
+
 namespace {
 
 class RangeLexer
@@ -449,7 +525,7 @@ private:
 } // end of anonymous namespace
 
 
-Preprocessor::Preprocessor(Client *client, Environment &env)
+Preprocessor::Preprocessor(Client *client, Environment *env)
     : client(client),
       env(env),
       _expand(env),
@@ -528,23 +604,23 @@ Preprocessor::State Preprocessor::createStateFromSource(const QByteArray &source
 
 void Preprocessor::processNewline()
 {
-    if (env.currentLine == _dot->lineno)
+    if (env->currentLine == _dot->lineno)
         return;
 
-    if (env.currentLine > _dot->lineno) {
+    if (env->currentLine > _dot->lineno) {
         _result->append("\n# ");
         _result->append(QByteArray::number(_dot->lineno));
         _result->append(' ');
         _result->append('"');
-        _result->append(env.currentFile);
+        _result->append(env->currentFile);
         _result->append('"');
         _result->append('\n');
     } else {
-        for (unsigned i = env.currentLine; i < _dot->lineno; ++i)
+        for (unsigned i = env->currentLine; i < _dot->lineno; ++i)
             _result->append('\n');
     }
 
-    env.currentLine = _dot->lineno;
+    env->currentLine = _dot->lineno;
 }
 
 void Preprocessor::processSkippingBlocks(bool skippingBlocks,
@@ -579,11 +655,11 @@ void Preprocessor::preprocess(const QByteArray &fileName, const QByteArray &sour
 
     pushState(createStateFromSource(source));
 
-    const QByteArray previousFileName = env.currentFile;
-    env.currentFile = fileName;
+    const QByteArray previousFileName = env->currentFile;
+    env->currentFile = fileName;
 
-    const unsigned previousCurrentLine = env.currentLine;
-    env.currentLine = 0;
+    const unsigned previousCurrentLine = env->currentLine;
+    env->currentLine = 0;
 
     while (true) {
         processNewline();
@@ -628,7 +704,8 @@ void Preprocessor::preprocess(const QByteArray &fileName, const QByteArray &sour
                 ++_dot; // skip T_IDENTIFIER
 
                 const QByteArray spell = tokenSpell(*identifierToken);
-                if (env.isBuiltinMacro(spell)) {
+
+                if (env->isBuiltinMacro(spell)) {
                     const Macro trivial;
 
                     if (client)
@@ -643,7 +720,7 @@ void Preprocessor::preprocess(const QByteArray &fileName, const QByteArray &sour
                     continue;
                 }
 
-                Macro *m = env.resolve(spell);
+                Macro *m = env->resolve(spell);
 
                 if (! m)
                     _result->append(spell);
@@ -675,7 +752,7 @@ void Preprocessor::preprocess(const QByteArray &fileName, const QByteArray &sour
                             if (_dot->is(T_IDENTIFIER)) {
                                 const QByteArray id = tokenSpell(*_dot);
 
-                                if (Macro *macro = env.resolve(id)) {
+                                if (Macro *macro = env->resolve(id)) {
                                     if (macro->isFunctionLike())
                                         m = macro;
                                 }
@@ -690,6 +767,8 @@ void Preprocessor::preprocess(const QByteArray &fileName, const QByteArray &sour
                         }
                     }
 
+                    // `m' is function-like macro.
+
                     // collect the actual arguments
                     if (_dot->isNot(T_LPAREN)) {
                         // ### warnng expected T_LPAREN
@@ -709,6 +788,7 @@ void Preprocessor::preprocess(const QByteArray &fileName, const QByteArray &sour
 
                         ++_dot;
                     }
+
                     if (_dot->isNot(T_RPAREN)) {
                         // ### warning expected T_RPAREN
 
@@ -738,8 +818,8 @@ void Preprocessor::preprocess(const QByteArray &fileName, const QByteArray &sour
 
     popState();
 
-    env.currentFile = previousFileName;
-    env.currentLine = previousCurrentLine;
+    env->currentFile = previousFileName;
+    env->currentLine = previousCurrentLine;
     _result = previousResult;
 }
 
@@ -899,8 +979,8 @@ void Preprocessor::processDefine(TokenIterator firstToken, TokenIterator lastTok
     }
 
     Macro macro;
-    macro.setFileName(env.currentFile);
-    macro.setLine(env.currentLine);
+    macro.setFileName(env->currentFile);
+    macro.setLine(env->currentLine);
     macro.setName(tokenText(*tk));
     ++tk; // skip T_IDENTIFIER
 
@@ -961,7 +1041,7 @@ void Preprocessor::processDefine(TokenIterator firstToken, TokenIterator lastTok
         macro.setDefinition(definition.trimmed());
     }
 
-    env.bind(macro);
+    env->bind(macro);
 
     if (client)
         client->macroAdded(macro);
@@ -1063,7 +1143,7 @@ void Preprocessor::processIfdef(bool checkUndefined,
     if (testIfLevel()) {
         if (tk->is(T_IDENTIFIER)) {
             const QByteArray macroName = tokenSpell(*tk);
-            bool value = env.resolve(macroName) != 0 || env.isBuiltinMacro(macroName);
+            bool value = env->resolve(macroName) != 0 || env->isBuiltinMacro(macroName);
 
             if (checkUndefined)
                 value = ! value;
@@ -1083,7 +1163,7 @@ void Preprocessor::processUndef(TokenIterator firstToken, TokenIterator lastToke
 
     if (tk->is(T_IDENTIFIER)) {
         const QByteArray macroName = tokenText(*tk);
-        const Macro *macro = env.remove(macroName);
+        const Macro *macro = env->remove(macroName);
 
         if (client && macro)
             client->macroAdded(*macro);
@@ -1162,7 +1242,7 @@ int Preprocessor::skipping() const
 Value Preprocessor::evalExpression(TokenIterator firstToken, TokenIterator lastToken,
                                    const QByteArray &source) const
 {
-    ExpressionEvaluator eval(&env);
+    ExpressionEvaluator eval(env);
     const Value result = eval(firstToken, lastToken, source);
     return result;
 }
diff --git a/src/libs/cplusplus/pp-engine.h b/src/libs/cplusplus/pp-engine.h
index 1b51c88d34771769acd6425393e08d10005f32e6..cd5129a9096de4c738c9a5719e22514c9d665c9a 100644
--- a/src/libs/cplusplus/pp-engine.h
+++ b/src/libs/cplusplus/pp-engine.h
@@ -60,80 +60,12 @@ namespace CPlusPlus {
 
 namespace CPlusPlus {
 
-struct Value
-{
-    enum Kind {
-        Kind_Long,
-        Kind_ULong,
-    };
-
-    Kind kind;
-
-    union {
-        long l;
-        unsigned long ul;
-    };
-
-
-    Value()
-        : kind(Kind_Long), l(0)
-    { }
-
-    inline bool is_ulong () const
-    { return kind == Kind_ULong; }
-
-    inline void set_ulong (unsigned long v)
-    {
-        ul = v;
-        kind = Kind_ULong;
-    }
-
-    inline void set_long (long v)
-    {
-        l = v;
-        kind = Kind_Long;
-    }
-
-    inline bool is_zero () const
-    { return l == 0; }
-
-#define PP_DEFINE_BIN_OP(name, op) \
-    inline Value operator op(const Value &other) const \
-    { \
-        Value v = *this; \
-        if (v.is_ulong () || other.is_ulong ()) \
-            v.set_ulong (v.ul op other.ul); \
-        else \
-            v.set_long (v.l op other.l); \
-        return v; \
-    }
-
-    PP_DEFINE_BIN_OP(op_add, +)
-    PP_DEFINE_BIN_OP(op_sub, -)
-    PP_DEFINE_BIN_OP(op_mult, *)
-    PP_DEFINE_BIN_OP(op_div, /)
-    PP_DEFINE_BIN_OP(op_mod, %)
-    PP_DEFINE_BIN_OP(op_lhs, <<)
-    PP_DEFINE_BIN_OP(op_rhs, >>)
-    PP_DEFINE_BIN_OP(op_lt, <)
-    PP_DEFINE_BIN_OP(op_gt, >)
-    PP_DEFINE_BIN_OP(op_le, <=)
-    PP_DEFINE_BIN_OP(op_ge, >=)
-    PP_DEFINE_BIN_OP(op_eq, ==)
-    PP_DEFINE_BIN_OP(op_ne, !=)
-    PP_DEFINE_BIN_OP(op_bit_and, &)
-    PP_DEFINE_BIN_OP(op_bit_or, |)
-    PP_DEFINE_BIN_OP(op_bit_xor, ^)
-    PP_DEFINE_BIN_OP(op_and, &&)
-    PP_DEFINE_BIN_OP(op_or, ||)
-
-#undef PP_DEFINE_BIN_OP
-};
+struct Value;
 
 class CPLUSPLUS_EXPORT Preprocessor
 {
 public:
-    Preprocessor(Client *client, Environment &env);
+    Preprocessor(Client *client, Environment *env);
 
     QByteArray operator()(const QByteArray &filename,
                           const QByteArray &source);
@@ -218,7 +150,7 @@ private:
 
 private:
     Client *client;
-    Environment &env;
+    Environment *env;
     MacroExpander _expand;
 
     bool _skipping[MAX_LEVEL]; // ### move in state
diff --git a/src/libs/cplusplus/pp-macro-expander.cpp b/src/libs/cplusplus/pp-macro-expander.cpp
index 0502aef4a4d9847afdd9f570be61ca053d701987..a9f4ced4010efa714fff2c14862190e9a75c16a5 100644
--- a/src/libs/cplusplus/pp-macro-expander.cpp
+++ b/src/libs/cplusplus/pp-macro-expander.cpp
@@ -32,6 +32,24 @@
 #include "pp-macro-expander.h"
 #include <QDateTime>
 
+namespace CPlusPlus {
+
+
+
+struct pp_frame
+{
+    Macro *expanding_macro;
+    const QVector<QByteArray> actuals;
+
+    pp_frame(Macro *expanding_macro, const QVector<QByteArray> &actuals)
+        : expanding_macro (expanding_macro),
+          actuals (actuals)
+    { }
+};
+
+
+} // end of namespace CPlusPlus
+
 using namespace CPlusPlus;
 
 inline static bool comment_p (const char *__first, const char *__last)
@@ -48,7 +66,7 @@ inline static bool comment_p (const char *__first, const char *__last)
     return (*__first == '/' || *__first == '*');
 }
 
-MacroExpander::MacroExpander (Environment &env, pp_frame *frame)
+MacroExpander::MacroExpander(Environment *env, pp_frame *frame)
     : env(env), frame(frame),
       lines(0), generated_lines(0)
 { }
@@ -87,10 +105,10 @@ const char *MacroExpander::expand(const char *__first, const char *__last,
         if (*__first == '\n')
         {
             __result->append("\n# ");
-            __result->append(QByteArray::number(env.currentLine));
+            __result->append(QByteArray::number(env->currentLine));
             __result->append(' ');
             __result->append('"');
-            __result->append(env.currentFile);
+            __result->append(env->currentFile);
             __result->append('"');
             __result->append('\n');
             ++lines;
@@ -214,20 +232,20 @@ const char *MacroExpander::expand(const char *__first, const char *__last,
                 continue;
             }
 
-            Macro *macro = env.resolve (fast_name);
-            if (! macro || macro->isHidden() || env.hideNext)
+            Macro *macro = env->resolve (fast_name);
+            if (! macro || macro->isHidden() || env->hideNext)
             {
                 if (fast_name.size () == 7 && fast_name [0] == 'd' && fast_name == "defined")
-                    env.hideNext = true;
+                    env->hideNext = true;
                 else
-                    env.hideNext = false;
+                    env->hideNext = false;
 
                 if (fast_name.size () == 8 && fast_name [0] == '_' && fast_name [1] == '_')
                 {
                     if (fast_name == "__LINE__")
                     {
                         char buf [16];
-                        const size_t count = qsnprintf (buf, 16, "%d", env.currentLine + lines);
+                        const size_t count = qsnprintf (buf, 16, "%d", env->currentLine + lines);
                         __result->append(buf, count);
                         continue;
                     }
@@ -235,7 +253,7 @@ const char *MacroExpander::expand(const char *__first, const char *__last,
                     else if (fast_name == "__FILE__")
                     {
                         __result->append('"');
-                        __result->append(env.currentFile);
+                        __result->append(env->currentFile);
                         __result->append('"');
                         continue;
                     }
@@ -287,7 +305,7 @@ const char *MacroExpander::expand(const char *__first, const char *__last,
                         if (__end_id == __tmp_end)
                         {
                             const QByteArray __id (__begin_id, __end_id - __begin_id);
-                            m = env.resolve (__id);
+                            m = env->resolve (__id);
                         }
 
                         if (! m)
diff --git a/src/libs/cplusplus/pp-macro-expander.h b/src/libs/cplusplus/pp-macro-expander.h
index 25d22aef7b19ddcc20c34f9f194036aed831c6f6..c1c9f24d712e17f702b0a1db95ec385320f70d1e 100644
--- a/src/libs/cplusplus/pp-macro-expander.h
+++ b/src/libs/cplusplus/pp-macro-expander.h
@@ -49,56 +49,53 @@
 #ifndef PP_MACRO_EXPANDER_H
 #define PP_MACRO_EXPANDER_H
 
+#include "pp-scanner.h"
+#include <QVector>
+#include <QByteArray>
+
 namespace CPlusPlus {
 
-    struct pp_frame
-    {
-        Macro *expanding_macro;
-        const QVector<QByteArray> actuals;
-
-        pp_frame (Macro *expanding_macro, const QVector<QByteArray> &actuals)
-            : expanding_macro (expanding_macro),
-              actuals (actuals)
-        { }
-    };
-
-    class MacroExpander
-    {
-        Environment &env;
-        pp_frame *frame;
-
-        pp_skip_number skip_number;
-        pp_skip_identifier skip_identifier;
-        pp_skip_string_literal skip_string_literal;
-        pp_skip_char_literal skip_char_literal;
-        pp_skip_argument skip_argument;
-        pp_skip_comment_or_divop skip_comment_or_divop;
-        pp_skip_blanks skip_blanks;
-        pp_skip_whitespaces skip_whitespaces;
-
-        const QByteArray *resolve_formal (const QByteArray &name);
-
-    public:
-        MacroExpander (Environment &env, pp_frame *frame = 0);
-
-        const char *operator () (const char *first, const char *last,
-                                 QByteArray *result);
-
-        const char *operator () (const QByteArray &source,
-                                 QByteArray *result)
-        { return operator()(source.constBegin(), source.constEnd(), result); }
-
-        const char *expand(const char *first, const char *last,
-                           QByteArray *result);
-
-        const char *skip_argument_variadics (const QVector<QByteArray> &actuals,
-                                             Macro *macro,
-                                             const char *first, const char *last);
-
-    public: // attributes
-        int lines;
-        int generated_lines;
-    };
+class Environment;
+
+struct pp_frame;
+
+class MacroExpander
+{
+    Environment *env;
+    pp_frame *frame;
+
+    pp_skip_number skip_number;
+    pp_skip_identifier skip_identifier;
+    pp_skip_string_literal skip_string_literal;
+    pp_skip_char_literal skip_char_literal;
+    pp_skip_argument skip_argument;
+    pp_skip_comment_or_divop skip_comment_or_divop;
+    pp_skip_blanks skip_blanks;
+    pp_skip_whitespaces skip_whitespaces;
+
+    const QByteArray *resolve_formal(const QByteArray &name);
+
+public:
+    MacroExpander(Environment *env, pp_frame *frame = 0);
+
+    const char *operator()(const char *first, const char *last,
+                             QByteArray *result);
+
+    const char *operator()(const QByteArray &source,
+                             QByteArray *result)
+    { return operator()(source.constBegin(), source.constEnd(), result); }
+
+    const char *expand(const char *first, const char *last,
+                       QByteArray *result);
+
+    const char *skip_argument_variadics(const QVector<QByteArray> &actuals,
+                                         Macro *macro,
+                                         const char *first, const char *last);
+
+public: // attributes
+    int lines;
+    int generated_lines;
+};
 
 } // namespace CPlusPlus
 
diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp
index 6dc59f0d4d2cf920a8020cc4e7c3f46f594da878..b4db1925358de746572fec4e1ff75b409cf7b9c5 100644
--- a/src/plugins/cpptools/cppmodelmanager.cpp
+++ b/src/plugins/cpptools/cppmodelmanager.cpp
@@ -220,7 +220,7 @@ private:
 CppPreprocessor::CppPreprocessor(QPointer<CppModelManager> modelManager)
     : snapshot(modelManager->snapshot()),
       m_modelManager(modelManager),
-      preprocess(this, env)
+      preprocess(this, &env)
 { }
 
 void CppPreprocessor::setWorkingCopy(const QMap<QString, QByteArray> &workingCopy)