diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files
index b5c58d172911885e4d4dc045ecf78142ca04dc29..14af54effd232fde07c01434813df8318089adaa 100644
--- a/src/OpenFOAM/Make/files
+++ b/src/OpenFOAM/Make/files
@@ -4,7 +4,9 @@ global/global.Cver
 global/argList/argList.C
 global/clock/clock.C
 global/profiling/profiling.C
+global/profiling/profilingInformation.C
 global/profiling/profilingSysInfo.C
+global/profiling/profilingTrigger.C
 global/etcFiles/etcFiles.C
 
 bools = primitives/bools
diff --git a/src/OpenFOAM/global/profiling/profiling.C b/src/OpenFOAM/global/profiling/profiling.C
index 10c61852ad093c76a5833b32051326887f953956..85204b0092c9db5eb7e20e7d9e3421819ae002a6 100644
--- a/src/OpenFOAM/global/profiling/profiling.C
+++ b/src/OpenFOAM/global/profiling/profiling.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2009-2016 Bernhard Gschaider
-     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016-2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -24,38 +24,53 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "profiling.H"
+#include "profilingInformation.H"
 #include "profilingSysInfo.H"
 #include "cpuInfo.H"
 #include "memInfo.H"
-#include "OSspecific.H"
-#include "IOstreams.H"
-#include "dictionary.H"
 #include "demandDrivenData.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
 Foam::profiling* Foam::profiling::pool_(0);
 
-Foam::label Foam::profiling::Information::nextId_(0);
 
+// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
+
+Foam::profilingInformation* Foam::profiling::find(const string& name)
+{
+    StorageContainer::iterator iter = hash_.find(name);
+    return (iter != hash_.end() ? iter() : 0);
+}
 
-// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
 
-Foam::label Foam::profiling::Information::getNextId()
+Foam::profilingInformation* Foam::profiling::store(profilingInformation *info)
 {
-    return nextId_++;
+    hash_.insert(info->description(), info);
+    return info;
 }
 
 
-void Foam::profiling::Information::raiseID(label maxVal)
+void Foam::profiling::push(profilingInformation *info, clockTime& timer)
 {
-    if (nextId_ < maxVal)
-    {
-        nextId_ = maxVal;
-    }
+    stack_.push(info);
+    timers_.set(info->id(), &timer);
+    info->push();                       // mark as on stack
+}
+
+
+Foam::profilingInformation* Foam::profiling::pop()
+{
+    profilingInformation *info = stack_.pop();
+    timers_.erase(info->id());
+    info->pop();                        // mark as off stack
+
+    return info;
 }
 
 
+// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
+
 bool Foam::profiling::active()
 {
     return pool_;
@@ -98,17 +113,17 @@ void Foam::profiling::initialize
     {
         pool_ = new profiling(ioObj, owner);
 
-        Information *info = pool_->store
+        profilingInformation *info = pool_->store
         (
-            new Information()
+            new profilingInformation()
         );
 
         pool_->push(info, pool_->clockTime_);
         Info<< "profiling initialized" << nl;
     }
 
-    // silently ignore multiple initialization
-    // eg, decomposePar use multiple simultaneous Times
+    // silently ignore multiple initializations
+    // eg, decomposePar uses multiple simultaneous Times
 }
 
 
@@ -123,17 +138,17 @@ void Foam::profiling::initialize
     {
         pool_ = new profiling(dict, ioObj, owner);
 
-        Information *info = pool_->store
+        profilingInformation *info = pool_->store
         (
-            new Information()
+            new profilingInformation()
         );
 
         pool_->push(info, pool_->clockTime_);
         Info<< "profiling initialized" << nl;
     }
 
-    // silently ignore multiple initialization
-    // eg, decomposePar use multiple simultaneous Times
+    // silently ignore multiple initializations
+    // eg, decomposePar uses multiple simultaneous Times
 }
 
 
@@ -147,23 +162,22 @@ void Foam::profiling::stop(const Time& owner)
 }
 
 
-Foam::profiling::Information* Foam::profiling::New
+Foam::profilingInformation* Foam::profiling::New
 (
-    const string& name,
+    const string& descr,
     clockTime& timer
 )
 {
-    Information *info = 0;
+    profilingInformation *info = 0;
 
     if (pool_)
     {
-        info = pool_->find(name);
+        profilingInformation *parent = pool_->stack_.top();
+
+        info = pool_->find(descr);
         if (!info)
         {
-            info = pool_->store
-            (
-                new Information(pool_->stack_.top(), name)
-            );
+            info = pool_->store(new profilingInformation(descr, parent));
         }
 
         pool_->push(info, timer);
@@ -182,11 +196,11 @@ Foam::profiling::Information* Foam::profiling::New
 }
 
 
-void Foam::profiling::unstack(const Information *info)
+void Foam::profiling::unstack(const profilingInformation *info)
 {
     if (pool_ && info)
     {
-        Information *top = pool_->pop();
+        profilingInformation *top = pool_->pop();
 
         if (info->id() != top->id())
         {
@@ -217,7 +231,7 @@ Foam::profiling::profiling
     hash_(),
     stack_(),
     timers_(),
-    sysInfo_(new sysInfo()),
+    sysInfo_(new profilingSysInfo()),
     cpuInfo_(new cpuInfo()),
     memInfo_(new memInfo())
 {}
@@ -239,7 +253,7 @@ Foam::profiling::profiling
     sysInfo_
     (
         dict.lookupOrDefault<Switch>("sysInfo", true)
-      ? new sysInfo() : 0
+      ? new profilingSysInfo() : 0
     ),
     cpuInfo_
     (
@@ -254,50 +268,6 @@ Foam::profiling::profiling
 {}
 
 
-Foam::profiling::Information::Information()
-:
-    id_(getNextId()),
-    description_("application::main"),
-    parent_(this),
-    calls_(0),
-    totalTime_(0),
-    childTime_(0),
-    maxMem_(0),
-    onStack_(false)
-{}
-
-
-Foam::profiling::Information::Information
-(
-    Information *parent,
-    const string& descr
-)
-:
-    id_(getNextId()),
-    description_(descr),
-    parent_(parent),
-    calls_(0),
-    totalTime_(0),
-    childTime_(0),
-    maxMem_(0),
-    onStack_(false)
-{}
-
-
-Foam::profiling::Trigger::Trigger(const char* name)
-:
-    clock_(),
-    ptr_(profiling::New(name, clock_))
-{}
-
-
-Foam::profiling::Trigger::Trigger(const string& name)
-:
-    clock_(),
-    ptr_(profiling::New(name, clock_))
-{}
-
-
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
 
 Foam::profiling::~profiling()
@@ -309,21 +279,11 @@ Foam::profiling::~profiling()
     if (pool_ == this)
     {
         pool_ = 0;
-        Information::nextId_ = 0;
+        profilingInformation::nextId_ = 0;
     }
 }
 
 
-Foam::profiling::Information::~Information()
-{}
-
-
-Foam::profiling::Trigger::~Trigger()
-{
-    stop();
-}
-
-
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 const Foam::Time& Foam::profiling::owner() const
@@ -337,25 +297,6 @@ Foam::label Foam::profiling::size() const
 }
 
 
-Foam::profiling::Information* Foam::profiling::find(const string& name)
-{
-    StorageContainer::iterator iter = hash_.find(name);
-    return (iter != hash_.end() ? iter() : 0);
-}
-
-
-void Foam::profiling::Information::update(const scalar& elapsed)
-{
-    ++calls_;
-    totalTime_ += elapsed;
-
-    if (id_ != parent().id())
-    {
-        parent().childTime_ += elapsed;
-    }
-}
-
-
 bool Foam::profiling::writeData(Ostream& os) const
 {
     os.beginBlock("profiling");
@@ -370,7 +311,7 @@ bool Foam::profiling::writeData(Ostream& os) const
         scalar oldElapsed = 0;
         forAllConstIter(StackContainer, stack_, iter)
         {
-            const Information *info = *iter;
+            const profilingInformation *info = *iter;
             scalar elapsed = timers_[info->id()]->elapsedTime();
 
             if (nTrigger++)
@@ -391,7 +332,7 @@ bool Foam::profiling::writeData(Ostream& os) const
 
         forAllConstIter(StorageContainer, hash_, iter)
         {
-            const Information *info = iter();
+            const profilingInformation *info = iter();
 
             if (!info->onStack())
             {
@@ -458,106 +399,4 @@ bool Foam::profiling::writeObject
 }
 
 
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-Foam::profiling::Information* Foam::profiling::store(Information *info)
-{
-    hash_.insert(info->description(), info);
-    return info;
-}
-
-
-void Foam::profiling::push(Information *info, clockTime& timer)
-{
-    stack_.push(info);
-    timers_.set(info->id(), &timer);
-    info->push();                       // mark as on stack
-}
-
-
-Foam::profiling::Information* Foam::profiling::pop()
-{
-    Information *info = stack_.pop();
-    timers_.erase(info->id());
-    info->pop();                        // mark as off stack
-
-    return info;
-}
-
-
-bool Foam::profiling::Trigger::running() const
-{
-    return ptr_;
-}
-
-
-void Foam::profiling::Trigger::stop()
-{
-    if (ptr_)
-    {
-        ptr_->update(clock_.elapsedTime());
-        profiling::unstack(ptr_);
-        // pointer is managed by pool storage -> thus no delete here
-    }
-    ptr_ = 0;
-}
-
-
-void Foam::profiling::Information::push() const
-{
-    onStack_ = true;
-}
-
-
-void Foam::profiling::Information::pop() const
-{
-    onStack_ = false;
-}
-
-
-Foam::Ostream& Foam::profiling::Information::write
-(
-    Ostream& os,
-    const bool offset,
-    const scalar& elapsedTime,
-    const scalar& childTimes
-) const
-{
-    // write in dictionary format
-
-    os.beginBlock(word("trigger" + Foam::name(id_)));
-
-    os.writeEntry("id",             id_);
-    if (id_ != parent().id())
-    {
-        os.writeEntry("parentId",   parent().id());
-    }
-    os.writeEntry("description",    description());
-    os.writeEntry("calls",          calls()     + (offset ? 1 : 0));
-    os.writeEntry("totalTime",      totalTime() + elapsedTime);
-    os.writeEntry("childTime",      childTime() + childTimes);
-    if (maxMem_)
-    {
-        os.writeEntry("maxMem",     maxMem_);
-    }
-    os.writeEntry("onStack",        Switch(onStack()));
-
-    os.endBlock();
-
-    return os;
-}
-
-
-// * * * * * * * * * * * * * * * Friend Operators  * * * * * * * * * * * * * //
-
-Foam::Ostream& Foam::operator<<
-(
-    Ostream& os,
-    const profiling::Information& info
-)
-{
-    return info.write(os);
-}
-
-
 // ************************************************************************* //
diff --git a/src/OpenFOAM/global/profiling/profiling.H b/src/OpenFOAM/global/profiling/profiling.H
index 504270ae2b01920c74f37551bd104c337db52854..e4d37bf5899e68fcf497d920adfe5dae9feaa91c 100644
--- a/src/OpenFOAM/global/profiling/profiling.H
+++ b/src/OpenFOAM/global/profiling/profiling.H
@@ -52,6 +52,7 @@ SourceFiles
 #ifndef profiling_H
 #define profiling_H
 
+#include "profilingTrigger.H"
 #include "HashPtrTable.H"
 #include "LIFOStack.H"
 #include "Map.H"
@@ -65,9 +66,9 @@ namespace Foam
 
 // Forward declaration of classes
 class Ostream;
-class dictionary;
 class cpuInfo;
 class memInfo;
+class profilingSysInfo;
 
 /*---------------------------------------------------------------------------*\
                           Class profiling Declaration
@@ -79,14 +80,20 @@ class profiling
 {
 public:
 
-    // Forward declarations of components
+    // Public typedefs
 
-        class Information;
-        class Trigger;
-        class sysInfo;
+        typedef profilingInformation Information;
+        typedef profilingTrigger Trigger;
 
 private:
 
+    // Private typedefs
+
+        typedef profilingSysInfo sysInfo;
+        typedef HashPtrTable<Information, string> StorageContainer;
+        typedef LIFOStack<Information*> StackContainer;
+
+
     // Private Static Data Members
 
         //- Only one global pool object is possible
@@ -95,10 +102,6 @@ private:
 
     // Private Data Members
 
-        typedef HashPtrTable<Information, string> StorageContainer;
-        typedef LIFOStack<Information*> StackContainer;
-
-
         //- The owner of the profiling
         const Time& owner_;
 
@@ -137,16 +140,22 @@ protected:
 
     // Friendship
 
+        friend class profilingTrigger;
         friend class Time;
 
 
     // Constructors
 
         //- Construct IO object, everything enabled
-        profiling(const IOobject&, const Time&);
+        profiling(const IOobject& io, const Time& owner);
 
         //- Construct IO object with finer control over behaviour
-        profiling(const dictionary&, const IOobject&, const Time&);
+        profiling
+        (
+            const dictionary& dict,
+            const IOobject& io,
+            const Time& owner
+        );
 
 
     //- Destructor
@@ -155,38 +164,51 @@ protected:
 
     // Protected Member Functions
 
-        //- Find profiling information element or null on failure
-        Information* find(const string& name);
+        //- Find named profiling information element or null on failure
+        profilingInformation* find(const string& name);
 
         //- Add to hashed storage,
         //  returns pointer to newly stored element for chaining
-        Information* store(Information*);
+        profilingInformation* store(profilingInformation* info);
 
         //- Add to stack and set timer lookup (based on Id)
-        void push(Information*, clockTime& timer);
+        void push(profilingInformation* info, clockTime& timer);
 
         //- Remove from stack and remove timer lookup (based on Id).
         //  Returns pointer to profiling information element
-        Information* pop();
+        profilingInformation* pop();
 
 
     // Static control elements
 
         //- Singleton to initialize profiling pool, everything enabled
-        static void initialize(const IOobject&, const Time&);
+        static void initialize
+        (
+            const IOobject& ioObj,
+            const Time& owner
+        );
 
         //- Singleton to initialize profiling pool with finer control
-        static void initialize(const dictionary&, const IOobject&, const Time&);
+        static void initialize
+        (
+            const dictionary& dict,
+            const IOobject& ioObj,
+            const Time& owner
+        );
 
         //- Stop profiling, cleanup pool if possible
-        static void stop(const Time&);
+        static void stop(const Time& owner);
 
         //- Existing or new element on pool, add to stack.
         //  Returns null if profiling has not been initialized
-        static Information* New(const string& name, clockTime& timer);
+        static profilingInformation* New
+        (
+            const string& descr,
+            clockTime& timer
+        );
 
         //- Remove the information from the top of the stack
-        static void unstack(const Information*);
+        static void unstack(const profilingInformation* info);
 
 public:
 
@@ -197,7 +219,7 @@ public:
 
         //- Print profiling information to specified output
         //  Forwards to writeData member of top-level object
-        static bool print(Ostream&);
+        static bool print(Ostream& os);
 
         //- Write profiling information now
         static bool writeNow();
@@ -209,10 +231,10 @@ public:
         const Time& owner() const;
 
         //- The size of the current stack
-        Foam::label size() const;
+        label size() const;
 
         //- writeData member function required by regIOobject
-        virtual bool writeData(Ostream&) const;
+        virtual bool writeData(Ostream& os) const;
 
         //- Write as uncompressed ASCII, using given format
         virtual bool writeObject
@@ -224,274 +246,12 @@ public:
 
 };
 
-
-// Forward declaration of friend functions and operators
-Ostream& operator<<(Ostream& os, const profiling::Information& info);
-
-
-/*---------------------------------------------------------------------------*\
-                   Class profiling::Information Declaration
-\*---------------------------------------------------------------------------*/
-
-class profiling::Information
-{
-    // Private Static Data Members
-
-        //- Counter to generate the ids
-        static label nextId_;
-
-        //- get a new ID and update the counter
-        static label getNextId();
-
-        //- raise the next possible ID (to avoid ID-clashes during reading)
-        static void raiseID(label maxVal);
-
-
-    // Private Data Members
-
-        //- Unique id to identify it
-        const label id_;
-
-        //- What this timer does
-        const string description_;
-
-        //- Pointer to the parent object (or self for top-level)
-        Information* parent_;
-
-        //- Nr of times this was called
-        long calls_;
-
-        //- Total time spent
-        scalar totalTime_;
-
-        //- Time spent in children
-        scalar childTime_;
-
-        //- Max memory usage on call.
-        //  Only valid when the calling profiling has memInfo active.
-        mutable int maxMem_;
-
-        //- Is this information currently on the stack?
-        mutable bool onStack_;
-
-
-    // Private Member Functions
-
-        //- Disallow default bitwise copy construct
-        Information(const Information&) = delete;
-
-        //- Disallow default bitwise assignment
-        void operator=(const Information&) = delete;
-
-
-protected:
-
-    // Friendship
-
-        friend class profiling;
-
-
-    // Constructors
-
-        //- Construct null - only the master-element
-        Information();
-
-
-    // Member Functions
-
-        //- Mark as being on the stack
-        void push() const;
-
-        //- Mark as being off the stack
-        void pop() const;
-
-
-        //- Write the profiling times, optionally with additional values
-        //  Use dictionary format.
-        Ostream& write
-        (
-            Ostream& os,
-            const bool offset = false,
-            const scalar& elapsedTime = 0,
-            const scalar& childTime = 0
-        ) const;
-
-public:
-
-
-    // Constructors
-
-        //- Construct from components
-        Information(Information* parent, const string& descr);
-
-
-    //- Destructor
-    ~Information();
-
-
-    // Member Functions
-
-    // Access
-
-        inline label id() const
-        {
-            return id_;
-        }
-
-
-        inline const string& description() const
-        {
-            return description_;
-        }
-
-
-        inline Information& parent() const
-        {
-            return *parent_;
-        }
-
-
-        inline label calls() const
-        {
-            return calls_;
-        }
-
-
-        inline const scalar& totalTime() const
-        {
-            return totalTime_;
-        }
-
-
-        inline const scalar& childTime() const
-        {
-            return childTime_;
-        }
-
-
-        inline int maxMem() const
-        {
-            return maxMem_;
-        }
-
-
-        inline bool onStack() const
-        {
-            return onStack_;
-        }
-
-
-    // Edit
-
-        //- Update it with a new timing information
-        void update(const scalar& elapsedTime);
-
-
-    // IOstream Operators
-
-        friend Ostream& operator<<(Ostream& os, const Information& info);
-
-};
-
-
-/*---------------------------------------------------------------------------*\
-                      Class profiling::Trigger Declaration
-\*---------------------------------------------------------------------------*/
-
-class profiling::Trigger
-{
-    // Private Data Members
-
-        //- The timer for the profiling information
-        clockTime clock_;
-
-        //- The profiling information
-        Information *ptr_;
-
-
-    // Private Member Functions
-
-        //- Disallow default bitwise copy construct
-        Trigger(const Trigger&) = delete;
-
-        //- Disallow default bitwise assignment
-        void operator=(const Trigger&) = delete;
-
-
-public:
-
-    // Constructors
-
-        //- Construct profiling with given description.
-        //  Descriptions beginning with 'application::' are reserved for
-        //  internal use.
-        Trigger(const char* name);
-
-        //- Construct profiling with given description.
-        //  Descriptions beginning with 'application::' are reserved for
-        //  internal use.
-        Trigger(const string& name);
-
-
-    //- Destructor
-    ~Trigger();
-
-
-    // Member Functions
-
-    // Access
-
-        //- True if the triggered profiling is active
-        bool running() const;
-
-
-    // Edit
-
-        //- Stop triggered profiling
-        void stop();
-
-};
-
-
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 } // End namespace Foam
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-// Macros
-
-//- Define profiling with specified name and description string
-//  This is required if the description contains space, colons etc.
-//  \sa addProfiling0
-//  \sa endProfiling
-#define addProfiling(name,descr)                                              \
-    ::Foam::profiling::Trigger  profilingTriggerFor##name(descr)
-
-//- Define profiling with specified name and description correspond to the name
-//  \sa addProfiling
-//  \sa endProfiling
-#define addProfiling0(name)                                                    \
-    ::Foam::profiling::Trigger  profilingTriggerFor##name(#name)
-
-//- Define profiling with specified name and description correspond to the
-//  compiler-defined function name string:
-//  \sa addProfiling
-//  \sa endProfiling
-#ifdef __GNUC__
-    #define addProfilingInFunction(name)                                       \
-    ::Foam::profiling::Trigger  profilingTriggerFor##name(__PRETTY_FUNCTION__)
-#else
-    #define addProfilingInFunction(name)                                       \
-    ::Foam::profiling::Trigger  profilingTriggerFor##name(__func__)
-#endif
-
-//- Remove profiling with specified name
-//  \sa addProfiling
-//  \sa addProfiling0
-#define endProfiling(name)      profilingTriggerFor##name.stop()
-
-
 #endif
 
 // ************************************************************************* //
diff --git a/src/OpenFOAM/global/profiling/profilingInformation.C b/src/OpenFOAM/global/profiling/profilingInformation.C
new file mode 100644
index 0000000000000000000000000000000000000000..937d5a01db1a1fda50a7c05c66f58ad0a425b2ab
--- /dev/null
+++ b/src/OpenFOAM/global/profiling/profilingInformation.C
@@ -0,0 +1,163 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2009-2016 Bernhard Gschaider
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "profilingInformation.H"
+#include "Switch.H"
+#include "IOstreams.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+Foam::label Foam::profilingInformation::nextId_(0);
+
+
+// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
+
+Foam::label Foam::profilingInformation::getNextId()
+{
+    return nextId_++;
+}
+
+
+void Foam::profilingInformation::raiseId(label maxVal)
+{
+    if (nextId_ < maxVal)
+    {
+        nextId_ = maxVal;
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::profilingInformation::profilingInformation()
+:
+    id_(getNextId()),
+    description_("application::main"),
+    parent_(this),
+    calls_(0),
+    totalTime_(0),
+    childTime_(0),
+    maxMem_(0),
+    onStack_(false)
+{}
+
+
+Foam::profilingInformation::profilingInformation
+(
+    const string& descr,
+    profilingInformation *parent
+)
+:
+    id_(getNextId()),
+    description_(descr),
+    parent_(parent),
+    calls_(0),
+    totalTime_(0),
+    childTime_(0),
+    maxMem_(0),
+    onStack_(false)
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::profilingInformation::~profilingInformation()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::profilingInformation::update(const scalar elapsed)
+{
+    ++calls_;
+    totalTime_ += elapsed;
+
+    if (id_ != parent().id())
+    {
+        parent().childTime_ += elapsed;
+    }
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::profilingInformation::push() const
+{
+    onStack_ = true;
+}
+
+
+void Foam::profilingInformation::pop() const
+{
+    onStack_ = false;
+}
+
+
+Foam::Ostream& Foam::profilingInformation::write
+(
+    Ostream& os,
+    const bool offset,
+    const scalar elapsedTime,
+    const scalar childTimes
+) const
+{
+    // write in dictionary format
+
+    os.beginBlock(word("trigger" + Foam::name(id_)));
+
+    os.writeEntry("id",             id_);
+    if (id_ != parent().id())
+    {
+        os.writeEntry("parentId",   parent().id());
+    }
+    os.writeEntry("description",    description());
+    os.writeEntry("calls",          calls()     + (offset ? 1 : 0));
+    os.writeEntry("totalTime",      totalTime() + elapsedTime);
+    os.writeEntry("childTime",      childTime() + childTimes);
+    if (maxMem_)
+    {
+        os.writeEntry("maxMem",     maxMem_);
+    }
+    os.writeEntry("onStack",        Switch(onStack()));
+
+    os.endBlock();
+
+    return os;
+}
+
+
+// * * * * * * * * * * * * * * * Friend Operators  * * * * * * * * * * * * * //
+
+Foam::Ostream& Foam::operator<<
+(
+    Ostream& os,
+    const profilingInformation& info
+)
+{
+    return info.write(os);
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/global/profiling/profilingInformation.H b/src/OpenFOAM/global/profiling/profilingInformation.H
new file mode 100644
index 0000000000000000000000000000000000000000..7aa395d80a57e33c51c5622774dc1793b7c3d28d
--- /dev/null
+++ b/src/OpenFOAM/global/profiling/profilingInformation.H
@@ -0,0 +1,236 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2009-2016 Bernhard Gschaider
+     \\/     M anipulation  | Copyright (C) 2016-2107 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::profilingInformation
+
+Description
+    Code profiling information in terms of time spent, number of calls etc.
+
+SourceFiles
+    profilingInformation.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef profilingInformation_H
+#define profilingInformation_H
+
+#include "label.H"
+#include "scalar.H"
+#include "string.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward declaration of classes
+class profilingInformation;
+class Ostream;
+
+// Forward declaration of friend functions and operators
+Ostream& operator<<(Ostream& os, const profilingInformation& info);
+
+
+/*---------------------------------------------------------------------------*\
+                    Class profilingInformation Declaration
+\*---------------------------------------------------------------------------*/
+
+class profilingInformation
+{
+    // Private Static Data Members
+
+        //- Counter to generate the ids
+        static label nextId_;
+
+        //- Get a new ID and update the counter
+        static label getNextId();
+
+        //- Raise the next possible ID (to avoid ID-clashes during reading)
+        static void raiseId(label maxVal);
+
+
+    // Private Data Members
+
+        //- Unique id to identify it
+        const label id_;
+
+        //- What this timer does
+        const string description_;
+
+        //- Pointer to the parent object (or self for top-level)
+        profilingInformation* parent_;
+
+        //- Nr of times this was called
+        long calls_;
+
+        //- Total time spent
+        scalar totalTime_;
+
+        //- Time spent in children
+        scalar childTime_;
+
+        //- Max memory usage on call.
+        //  Only valid when the calling profiling has memInfo active.
+        mutable int maxMem_;
+
+        //- Is this information currently on the stack?
+        mutable bool onStack_;
+
+
+    // Private Member Functions
+
+        //- Disallow default bitwise copy construct
+        profilingInformation(const profilingInformation&) = delete;
+
+        //- Disallow default bitwise assignment
+        void operator=(const profilingInformation&) = delete;
+
+
+protected:
+
+    // Friendship
+
+        friend class profiling;
+
+
+    // Constructors
+
+        //- Construct null - only the master-element
+        profilingInformation();
+
+
+    // Member Functions
+
+        //- Mark as being on the stack
+        void push() const;
+
+        //- Mark as being off the stack
+        void pop() const;
+
+
+        //- Write the profiling times, optionally with additional values
+        //  Use dictionary format.
+        Ostream& write
+        (
+            Ostream& os,
+            const bool offset = false,
+            const scalar elapsedTime = 0,
+            const scalar childTime = 0
+        ) const;
+
+
+public:
+
+    // Constructors
+
+        //- Construct from components
+        profilingInformation
+        (
+            const string& descr,
+            profilingInformation* parent
+        );
+
+
+    //- Destructor
+    ~profilingInformation();
+
+
+    // Member Functions
+
+      // Access
+
+        inline label id() const
+        {
+            return id_;
+        }
+
+
+        inline const string& description() const
+        {
+            return description_;
+        }
+
+
+        inline profilingInformation& parent() const
+        {
+            return *parent_;
+        }
+
+
+        inline label calls() const
+        {
+            return calls_;
+        }
+
+
+        inline scalar totalTime() const
+        {
+            return totalTime_;
+        }
+
+
+        inline scalar childTime() const
+        {
+            return childTime_;
+        }
+
+
+        inline int maxMem() const
+        {
+            return maxMem_;
+        }
+
+
+        inline bool onStack() const
+        {
+            return onStack_;
+        }
+
+
+      // Edit
+
+        //- Update it with a new timing information
+        void update(const scalar elapsedTime);
+
+
+    // IOstream Operators
+
+        friend Ostream& operator<<
+        (
+            Ostream& os,
+            const profilingInformation& info
+        );
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/global/profiling/profilingSysInfo.C b/src/OpenFOAM/global/profiling/profilingSysInfo.C
index 51b060173648af2c5d25d7a5314caa799c99a8bc..8ba947b20caa18bf1b36a10916bfa31f3005e256 100644
--- a/src/OpenFOAM/global/profiling/profilingSysInfo.C
+++ b/src/OpenFOAM/global/profiling/profilingSysInfo.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2016-2017 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -24,18 +24,23 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "profilingSysInfo.H"
-#include "demandDrivenData.H"
 #include "foamVersion.H"
+#include "clock.H"
+#include "Ostream.H"
+#include "OSspecific.H"
+
 
 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
 
 // file-scope function
 inline static void printEnv
 (
-    Foam::Ostream& os, const Foam::word& key, const Foam::word& envName
+    Foam::Ostream& os,
+    const Foam::word& key,
+    const std::string& envName
 )
 {
-    const std::string value = getEnv(envName);
+    const std::string value = Foam::getEnv(envName);
     if (!value.empty())
     {
         os.writeEntry(key, value);
@@ -45,26 +50,25 @@ inline static void printEnv
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
-Foam::profiling::sysInfo::sysInfo()
+Foam::profilingSysInfo::profilingSysInfo()
 {}
 
 
-
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
 
-Foam::profiling::sysInfo::~sysInfo()
+Foam::profilingSysInfo::~profilingSysInfo()
 {}
 
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-Foam::Ostream& Foam::profiling::sysInfo::write
+Foam::Ostream& Foam::profilingSysInfo::write
 (
     Ostream& os
 ) const
 {
-    os.writeEntry("host",       hostName(false)); // short name
-    os.writeEntry("date",       clock::dateTime());
+    os.writeEntry("host",       Foam::hostName(false)); // short name
+    os.writeEntry("date",       Foam::clock::dateTime());
 
     // compile-time information
     os.writeEntry("version",    std::string(FOAMversion));
diff --git a/src/OpenFOAM/global/profiling/profilingSysInfo.H b/src/OpenFOAM/global/profiling/profilingSysInfo.H
index b2e84f888f74e19a66cb0081ee6b644479fe693f..e13b953383af7914c23dc05b60e2bd6367c7a8d5 100644
--- a/src/OpenFOAM/global/profiling/profilingSysInfo.H
+++ b/src/OpenFOAM/global/profiling/profilingSysInfo.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2016-2017 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -22,10 +22,10 @@ License
     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 
 Class
-    Foam::profiling::sysInfo
+    Foam::profilingSysInfo
 
 Description
-    General system information
+    General system information useful for profiling
 
 SourceFiles
     profilingSysInfo.C
@@ -35,8 +35,6 @@ SourceFiles
 #ifndef profilingSysInfo_H
 #define profilingSysInfo_H
 
-#include "profiling.H"
-
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 namespace Foam
@@ -44,27 +42,22 @@ namespace Foam
 
 // Forward declaration of classes
 class Ostream;
+class profilingSysInfo;
 
 /*---------------------------------------------------------------------------*\
-                     Class profiling::sysInfo Declaration
+                      Class profilingSysInfo Declaration
 \*---------------------------------------------------------------------------*/
 
-class profiling::sysInfo
+class profilingSysInfo
 {
     // Private Member Functions
 
         //- Disallow default bitwise copy construct
-        sysInfo(const sysInfo&) = delete;
+        profilingSysInfo(const profilingSysInfo&) = delete;
 
         //- Disallow default bitwise assignment
-        void operator=(const sysInfo&) = delete;
-
-
-protected:
-
-    // Friendship
+        void operator=(const profilingSysInfo&) = delete;
 
-        friend class profiling;
 
 public:
 
@@ -72,11 +65,11 @@ public:
     // Constructors
 
         //- Construct from components
-        sysInfo();
+        profilingSysInfo();
 
 
     //- Destructor
-    ~sysInfo();
+    ~profilingSysInfo();
 
 
     // Member Functions
@@ -84,7 +77,7 @@ public:
         //- Update it with a new timing information
         void update();
 
-        //- Write the profiling sys-info, use dictionary format.
+        //- Write the profiling system-info, use dictionary format.
         Ostream& write(Ostream& os) const;
 };
 
diff --git a/src/OpenFOAM/global/profiling/profilingTrigger.C b/src/OpenFOAM/global/profiling/profilingTrigger.C
new file mode 100644
index 0000000000000000000000000000000000000000..6eac94c05ac39d8850be7af6a1ce7987e7d80178
--- /dev/null
+++ b/src/OpenFOAM/global/profiling/profilingTrigger.C
@@ -0,0 +1,75 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2009-2016 Bernhard Gschaider
+     \\/     M anipulation  | Copyright (C) 2016-2017 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "profiling.H"
+#include "profilingInformation.H"
+#include "profilingTrigger.H"
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::profilingTrigger::profilingTrigger(const char* name)
+:
+    clock_(),
+    ptr_(profiling::New(name, clock_))
+{}
+
+
+Foam::profilingTrigger::profilingTrigger(const string& name)
+:
+    clock_(),
+    ptr_(profiling::New(name, clock_))
+{}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::profilingTrigger::~profilingTrigger()
+{
+    stop();
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+bool Foam::profilingTrigger::running() const
+{
+    return ptr_;
+}
+
+
+void Foam::profilingTrigger::stop()
+{
+    if (ptr_)
+    {
+        ptr_->update(clock_.elapsedTime());
+        profiling::unstack(ptr_);
+        // pointer is managed by pool storage -> thus no delete here
+    }
+    ptr_ = 0;
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/global/profiling/profilingTrigger.H b/src/OpenFOAM/global/profiling/profilingTrigger.H
new file mode 100644
index 0000000000000000000000000000000000000000..f459f469705fd82f34ddb05345e84ac3d98d22d0
--- /dev/null
+++ b/src/OpenFOAM/global/profiling/profilingTrigger.H
@@ -0,0 +1,149 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2009-2016 Bernhard Gschaider
+     \\/     M anipulation  | Copyright (C) 2016-2107 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::profilingTrigger
+
+Description
+    Triggers for starting/stopping code profiling.
+
+SourceFiles
+    profilingTrigger.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef profilingTrigger_H
+#define profilingTrigger_H
+
+#include "clockTime.H"
+#include "string.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward declaration of classes
+class profilingInformation;
+
+/*---------------------------------------------------------------------------*\
+                      Class profilingTrigger Declaration
+\*---------------------------------------------------------------------------*/
+
+class profilingTrigger
+{
+    // Private Data Members
+
+        //- The timer for the profiling information
+        clockTime clock_;
+
+        //- The profiling information
+        profilingInformation *ptr_;
+
+
+    // Private Member Functions
+
+        //- Disallow default bitwise copy construct
+        profilingTrigger(const profilingTrigger&) = delete;
+
+        //- Disallow default bitwise assignment
+        void operator=(const profilingTrigger&) = delete;
+
+
+public:
+
+    // Constructors
+
+        //- Construct profiling with given description.
+        //  Descriptions beginning with 'application::' are reserved for
+        //  internal use.
+        profilingTrigger(const char* name);
+
+        //- Construct profiling with given description.
+        //  Descriptions beginning with 'application::' are reserved for
+        //  internal use.
+        profilingTrigger(const string& name);
+
+
+    //- Destructor
+    ~profilingTrigger();
+
+
+    // Member Functions
+
+      // Access
+
+        //- True if the triggered profiling is active
+        bool running() const;
+
+
+      // Edit
+
+        //- Stop triggered profiling
+        void stop();
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+// Macros
+
+//- Define profiling with specified name and description string
+//  This is required if the description contains space, colons etc.
+//  \sa addProfiling0
+//  \sa endProfiling
+#define addProfiling(name,descr)                                               \
+    ::Foam::profilingTrigger  profilingTriggerFor##name(descr)
+
+//- Define profiling with specified name and description correspond to the name
+//  \sa addProfiling
+//  \sa endProfiling
+#define addProfiling0(name)                                                    \
+    ::Foam::profilingTrigger  profilingTriggerFor##name(#name)
+
+//- Define profiling with specified name and description correspond to the
+//  compiler-defined function name string:
+//  \sa addProfiling
+//  \sa endProfiling
+#ifdef __GNUC__
+    #define addProfilingInFunction(name)                                       \
+    ::Foam::profilingTrigger  profilingTriggerFor##name(__PRETTY_FUNCTION__)
+#else
+    #define addProfilingInFunction(name)                                       \
+    ::Foam::profilingTrigger  profilingTriggerFor##name(__func__)
+#endif
+
+//- Remove profiling with specified name
+//  \sa addProfiling
+//  \sa addProfiling0
+#define endProfiling(name)    profilingTriggerFor##name.stop()
+
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrix.H b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrix.H
index 44b01b27f3110886df1de7dc52c0e36d5ef679f2..5da8c96dd10f34ed291d875487f3a85e2c76449b 100644
--- a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrix.H
+++ b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrix.H
@@ -59,7 +59,7 @@ SourceFiles
 #include "runTimeSelectionTables.H"
 #include "solverPerformance.H"
 #include "InfoProxy.H"
-#include "profiling.H"
+#include "profilingTrigger.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -119,7 +119,7 @@ public:
             //- Convergence tolerance relative to the initial
             scalar relTol_;
 
-            profiling::Trigger profiling_;
+            profilingTrigger profiling_;
 
         // Protected Member Functions