diff --git a/.gitattributes b/.gitattributes
index 320e5b6fd5740692c6e4a6be9172cd253ddf8abd..3c53b0debcfdcee82ba8e4d7f48eaddf08851a68 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -37,6 +37,7 @@ CEP/Calibration/BBSKernel/include/BBSKernel/Expr/IonPhaseShift.h -text
 CEP/Calibration/BBSKernel/include/BBSKernel/Expr/LinearToCircularRL.h -text
 CEP/Calibration/BBSKernel/include/BBSKernel/Expr/Scope.h -text
 CEP/Calibration/BBSKernel/include/BBSKernel/Expr/TileArrayFactor.h -text
+CEP/Calibration/BBSKernel/include/BBSKernel/Expr/Timer.h -text
 CEP/Calibration/BBSKernel/include/BBSKernel/IndexedSequence.h -text
 CEP/Calibration/BBSKernel/include/BBSKernel/IonosphereExpr.h -text
 CEP/Calibration/BBSKernel/include/BBSKernel/MeasurementExpr.h -text
@@ -61,6 +62,7 @@ CEP/Calibration/BBSKernel/src/Expr/IonPhaseShift.cc -text
 CEP/Calibration/BBSKernel/src/Expr/LinearToCircularRL.cc -text
 CEP/Calibration/BBSKernel/src/Expr/Scope.cc -text
 CEP/Calibration/BBSKernel/src/Expr/TileArrayFactor.cc -text
+CEP/Calibration/BBSKernel/src/Expr/Timer.cc -text
 CEP/Calibration/BBSKernel/src/IonosphereExpr.cc -text
 CEP/Calibration/BBSKernel/src/StationResponse.cc -text
 CEP/Calibration/BBSKernel/src/UVWFlagger.cc -text
diff --git a/CEP/Calibration/BBSKernel/CMakeLists.txt b/CEP/Calibration/BBSKernel/CMakeLists.txt
index 37299980bb2cfb82378ea79667cc2c06bb56daa7..02e1faa60c527576a37c7facc9aa9137adb19e33 100644
--- a/CEP/Calibration/BBSKernel/CMakeLists.txt
+++ b/CEP/Calibration/BBSKernel/CMakeLists.txt
@@ -7,8 +7,14 @@ lofar_find_package(Boost REQUIRED)
 lofar_find_package(Casacore REQUIRED COMPONENTS 
   casa measures ms scimath tables)
 
+# Uncomment to check for unsafe conversions (gcc), for example conversion of
+# size_t to unsigned int (truncation).
 #add_definitions(-Wconversion)
 
+# Uncomment to enable timing of (classes of) expression tree nodes. NB. Only
+# enable if necessary, timing incurs an overhead of its own.
+#add_definitions(-DLOFAR_BBSKERNEL_EXPR_TIMER)
+
 add_subdirectory(include/BBSKernel)
 add_subdirectory(src)
 add_subdirectory(test)
diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/CMakeLists.txt b/CEP/Calibration/BBSKernel/include/BBSKernel/CMakeLists.txt
index 1528e6af709ddfc7aea1bf80f013dd6848a7718b..71603a60b3e3118ef41f5376933437f79afcef4c 100644
--- a/CEP/Calibration/BBSKernel/include/BBSKernel/CMakeLists.txt
+++ b/CEP/Calibration/BBSKernel/include/BBSKernel/CMakeLists.txt
@@ -90,5 +90,6 @@ install(FILES
   Expr/StationShift.h
   Expr/StationUVW.h
   Expr/TileArrayFactor.h
+  Expr/Timer.h
   Expr/YatawattaDipole.h
   DESTINATION include/${PACKAGE_NAME}/Expr)
diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/Evaluator.h b/CEP/Calibration/BBSKernel/include/BBSKernel/Evaluator.h
index 41140ecc2b1def6e782b29f2c6401fa6aa30cba3..754a2c510e0370e6c4956ccd74b85ad510b75081 100644
--- a/CEP/Calibration/BBSKernel/include/BBSKernel/Evaluator.h
+++ b/CEP/Calibration/BBSKernel/include/BBSKernel/Evaluator.h
@@ -56,6 +56,7 @@ public:
     };
 
     Evaluator(const VisBuffer::Ptr &lhs, const MeasurementExpr::Ptr &rhs);
+    ~Evaluator();
 
     // Restrict processing to the baselines included in the mask.
     void setBaselineMask(const BaselineMask &mask);
diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/BasicExpr.h b/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/BasicExpr.h
index 303c2d28a229f48a034f569de246683cc954cd2c..4fe0abc8b8e6c49843a3c029f392caa0af6d6a9e 100644
--- a/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/BasicExpr.h
+++ b/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/BasicExpr.h
@@ -192,6 +192,8 @@ const T_EXPR_VALUE BasicUnaryExpr<T_ARG0, T_EXPR_VALUE>::evaluateExpr
     // Evaluate arguments.
     const T_ARG0 arg0 = argument0()->evaluate(request, cache, grid);
 
+    EXPR_TIMER_START();
+
     // Evaluate flags.
     result.setFlags(arg0.flags());
 
@@ -206,6 +208,8 @@ const T_EXPR_VALUE BasicUnaryExpr<T_ARG0, T_EXPR_VALUE>::evaluateExpr
         it0.advance();
     }
 
+    EXPR_TIMER_STOP();
+
     return result;
 }
 
@@ -232,6 +236,8 @@ const T_EXPR_VALUE BasicBinaryExpr<T_ARG0, T_ARG1, T_EXPR_VALUE>::evaluateExpr
     const T_ARG0 arg0 = argument0()->evaluate(request, cache, grid);
     const T_ARG1 arg1 = argument1()->evaluate(request, cache, grid);
 
+    EXPR_TIMER_START();
+
     // Evaluate flags.
     FlagArray flags[2];
     flags[0] = arg0.flags();
@@ -255,6 +261,8 @@ const T_EXPR_VALUE BasicBinaryExpr<T_ARG0, T_ARG1, T_EXPR_VALUE>::evaluateExpr
         it1.advance(key);
     }
 
+    EXPR_TIMER_STOP();
+
     return result;
 }
 
@@ -286,6 +294,8 @@ const T_EXPR_VALUE BasicTernaryExpr<T_ARG0, T_ARG1, T_ARG2,
     const T_ARG1 arg1 = argument1()->evaluate(request, cache, grid);
     const T_ARG2 arg2 = argument2()->evaluate(request, cache, grid);
 
+    EXPR_TIMER_START();
+
     // Evaluate flags.
     FlagArray flags[3];
     flags[0] = arg0.flags();
@@ -313,6 +323,8 @@ const T_EXPR_VALUE BasicTernaryExpr<T_ARG0, T_ARG1, T_ARG2,
         it2.advance(key);
     }
 
+    EXPR_TIMER_STOP();
+
     return result;
 }
 
@@ -347,6 +359,8 @@ const T_EXPR_VALUE BasicExpr4<T_ARG0, T_ARG1, T_ARG2, T_ARG3,
     const T_ARG2 arg2 = argument2()->evaluate(request, cache, grid);
     const T_ARG3 arg3 = argument3()->evaluate(request, cache, grid);
 
+    EXPR_TIMER_START();
+
     // Evaluate flags.
     FlagArray flags[4];
     flags[0] = arg0.flags();
@@ -383,6 +397,8 @@ const T_EXPR_VALUE BasicExpr4<T_ARG0, T_ARG1, T_ARG2, T_ARG3,
         atEnd = it0.atEnd() && it1.atEnd() && it2.atEnd() && it3.atEnd();
     }
 
+    EXPR_TIMER_STOP();
+
     return result;
 }
 
@@ -419,6 +435,8 @@ const T_EXPR_VALUE BasicExpr5<T_ARG0, T_ARG1, T_ARG2, T_ARG3, T_ARG4,
     const T_ARG3 arg3 = argument3()->evaluate(request, cache, grid);
     const T_ARG4 arg4 = argument4()->evaluate(request, cache, grid);
 
+    EXPR_TIMER_START();
+
     // Evaluate flags.
     FlagArray flags[5];
     flags[0] = arg0.flags();
@@ -461,6 +479,8 @@ const T_EXPR_VALUE BasicExpr5<T_ARG0, T_ARG1, T_ARG2, T_ARG3, T_ARG4,
             && it4.atEnd();
     }
 
+    EXPR_TIMER_STOP();
+
     return result;
 }
 
diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/Expr.h b/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/Expr.h
index 21a8a7f7abeb29aeeb44256e6f48099eb81471c2..4e71315d80bf3b54a4b0dff991d99c398a2b83cb 100644
--- a/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/Expr.h
+++ b/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/Expr.h
@@ -33,6 +33,7 @@
 #include <BBSKernel/Expr/ExprValue.h>
 #include <BBSKernel/Expr/Request.h>
 #include <BBSKernel/Expr/Cache.h>
+#include <BBSKernel/Expr/Timer.h>
 
 namespace LOFAR
 {
diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/ExprAdaptors.h b/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/ExprAdaptors.h
index ffaf41cd3e06a702d4cb20389cf6672a111aec62..b542fd78cde789a786cf609cf1879a96d0049699 100644
--- a/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/ExprAdaptors.h
+++ b/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/ExprAdaptors.h
@@ -212,6 +212,8 @@ const Vector<LENGTH> AsExpr<Vector<LENGTH> >::evaluateExpr
         result.setElement(i, args[i].element());
     }
 
+    EXPR_TIMER_START();
+
     // Evaluate flags.
     FlagArray flags[LENGTH];
     for(unsigned int i = 0; i < LENGTH; ++i)
@@ -220,6 +222,8 @@ const Vector<LENGTH> AsExpr<Vector<LENGTH> >::evaluateExpr
     }
     result.setFlags(mergeFlags(flags, flags + LENGTH));
 
+    EXPR_TIMER_STOP();
+
     return result;
 }
 
diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/FlagIf.h b/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/FlagIf.h
index d98b033fb3223b97fbdc6c0dcb7d6847f1c52ff7..45f27c48fe89c3382ae35f8e3a11611dfb80acb1 100644
--- a/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/FlagIf.h
+++ b/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/FlagIf.h
@@ -92,10 +92,10 @@ const Scalar FlagIf<T_PREDICATE>::evaluateExpr(const Request &request,
     // Evaluate argument.
     const Scalar arg0 = argument0()->evaluate(request, cache, grid);
 
-    // Create result.
-    Scalar result;
-    // Pass through value.
-    result.setElement(arg0.element());
+    EXPR_TIMER_START();
+
+    // Create result (pass through value).
+    Scalar result(arg0.element());
 
     // Compute flags.
     const Matrix value = arg0.value();
@@ -125,6 +125,8 @@ const Scalar FlagIf<T_PREDICATE>::evaluateExpr(const Request &request,
         result.setFlags(arg0.hasFlags() ? arg0.flags() | flags : flags);
     }
 
+    EXPR_TIMER_STOP();
+
     return result;
 }
 
diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/MergeFlags.h b/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/MergeFlags.h
index f974e40360f755f62c47fd48ecf62bd01d6e91ad..6152a0c3e40462941c876b81e4217bf4bad156e5 100644
--- a/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/MergeFlags.h
+++ b/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/MergeFlags.h
@@ -83,6 +83,8 @@ const T_ARG0 MergeFlags<T_ARG0, T_ARG1>::evaluateExpr
     const T_ARG0 arg0 = argument0()->evaluate(request, cache, grid);
     const T_ARG1 arg1 = argument1()->evaluate(request, cache, grid);
 
+    EXPR_TIMER_START();
+
     if(arg1.hasFlags())
     {
         // Pass through value.
@@ -100,6 +102,8 @@ const T_ARG0 MergeFlags<T_ARG0, T_ARG1>::evaluateExpr
         result = arg0;
     }
 
+    EXPR_TIMER_STOP();
+
     return result;
 }
 
diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/Timer.h b/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/Timer.h
new file mode 100644
index 0000000000000000000000000000000000000000..0fce1df913a67469aa9818335f05da2d6e2ac46f
--- /dev/null
+++ b/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/Timer.h
@@ -0,0 +1,89 @@
+//# Timer.h: Singleton that can be used to measure the time spent in classes
+//# derived from Expr.
+//#
+//# Copyright (C) 2011
+//# ASTRON (Netherlands Institute for Radio Astronomy)
+//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+//#
+//# This file is part of the LOFAR software suite.
+//# The LOFAR software suite 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.
+//#
+//# The LOFAR software suite 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 the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>.
+//#
+//# $Id$
+
+#ifndef LOFAR_BBSKERNEL_EXPR_TIMER_H
+#define LOFAR_BBSKERNEL_EXPR_TIMER_H
+
+// \file
+// Singleton that can be used to measure the time spent in classes derived from
+// Expr.
+
+#include <Common/lofar_map.h>
+#include <Common/lofar_string.h>
+
+#include <Common/Singleton.h>
+#include <Common/Timer.h>
+
+#ifdef LOFAR_BBSKERNEL_EXPR_TIMER
+#define EXPR_TIMER_START()              Timer::instance().start(this)
+#define EXPR_TIMER_STOP()               Timer::instance().stop(this)
+#define EXPR_TIMER_START_NAMED(name)    Timer::instance().start(name)
+#define EXPR_TIMER_STOP_NAMED(name)     Timer::instance().stop(name)
+#else
+#define EXPR_TIMER_START()
+#define EXPR_TIMER_STOP()
+#define EXPR_TIMER_START_NAMED(name)
+#define EXPR_TIMER_STOP_NAMED(name)
+#endif
+
+namespace LOFAR
+{
+namespace BBS
+{
+
+// \addtogroup Expr
+// @{
+
+class ExprBase;
+
+class TimerImpl
+{
+public:
+    // Remove all timers. After this, any call to start for a certain timer
+    // will start counting from zero.
+    void reset();
+
+    // Dump all timers to the output stream.
+    void dump(ostream &out) const;
+
+    // Control timers that belong to classes derived from ExprBase.
+    void reset(const ExprBase *expr);
+    void start(const ExprBase *expr);
+    void stop(const ExprBase *expr);
+
+    // Control named timers.
+    void start(const string &name);
+    void stop(const string &name);
+
+private:
+    map<string, NSTimer>    itsTimers;
+};
+
+typedef Singleton<TimerImpl>        Timer;
+
+// @}
+
+} //# namespace BBS
+} //# namespace LOFAR
+
+#endif
diff --git a/CEP/Calibration/BBSKernel/src/CMakeLists.txt b/CEP/Calibration/BBSKernel/src/CMakeLists.txt
index 624b7b315efd80e90a03dd4427cdbf172bc54317..f53d0025240c18f10ac0a53398ded6384774de2a 100644
--- a/CEP/Calibration/BBSKernel/src/CMakeLists.txt
+++ b/CEP/Calibration/BBSKernel/src/CMakeLists.txt
@@ -76,6 +76,7 @@ lofar_add_library(bbskernel
   Expr/StationShift.cc
   Expr/StationUVW.cc
   Expr/TileArrayFactor.cc
+  Expr/Timer.cc
   Expr/YatawattaDipole.cc)
 
 # Because we're using dlopen()
diff --git a/CEP/Calibration/BBSKernel/src/Evaluator.cc b/CEP/Calibration/BBSKernel/src/Evaluator.cc
index 98e8b54096d03669a52bee883702562fbef3ae73..7375d59d848ef09b8fd66b5cf8cb4de7403ebc71 100644
--- a/CEP/Calibration/BBSKernel/src/Evaluator.cc
+++ b/CEP/Calibration/BBSKernel/src/Evaluator.cc
@@ -25,6 +25,7 @@
 
 #include <BBSKernel/Evaluator.h>
 #include <BBSKernel/Exceptions.h>
+#include <BBSKernel/Expr/Timer.h>
 
 namespace LOFAR
 {
@@ -58,6 +59,11 @@ Evaluator::Evaluator(const VisBuffer::Ptr &lhs, const MeasurementExpr::Ptr &rhs)
     itsRHS->setEvalGrid(itsLHS->grid());
 }
 
+Evaluator::~Evaluator()
+{
+    Timer::instance().reset();
+}
+
 void Evaluator::setBaselineMask(const BaselineMask &mask)
 {
     itsBlMap.clear();
@@ -146,11 +152,13 @@ void Evaluator::clearStats()
     {
         itsProcTimers[i].reset();
     }
+
+    Timer::instance().reset();
 }
 
 void Evaluator::dumpStats(ostream &out) const
 {
-    out << "Evaluator statistics: " << endl;
+    out << endl << "Evaluator statistics:" << endl;
     for(size_t i = 0; i < Evaluator::N_ProcTimer; ++i)
     {
         const double elapsed = itsProcTimers[i].getElapsed();
@@ -161,6 +169,8 @@ void Evaluator::dumpStats(ostream &out) const
             << " total " << elapsed << " count " << count << " avg " << average
             << endl;
     }
+
+    Timer::instance().dump(out);
 }
 
 } //# namespace BBS
diff --git a/CEP/Calibration/BBSKernel/src/Expr/ConditionNumber.cc b/CEP/Calibration/BBSKernel/src/Expr/ConditionNumber.cc
index 28c8633d6f4accee7c94830e0cb01479cc528564..2a9c1ac1cb32525701ea5cbe3bebf5c58723cd3a 100644
--- a/CEP/Calibration/BBSKernel/src/Expr/ConditionNumber.cc
+++ b/CEP/Calibration/BBSKernel/src/Expr/ConditionNumber.cc
@@ -34,7 +34,7 @@ ConditionNumber::ConditionNumber(const Expr<JonesMatrix>::ConstPtr &arg0)
 {
 }
 
-const Scalar::View ConditionNumber::evaluateImpl(const Grid &grid,
+const Scalar::View ConditionNumber::evaluateImpl(const Grid&,
     const JonesMatrix::View &arg0) const
 {
     Matrix norm00 = abs(arg0(0, 0));
diff --git a/CEP/Calibration/BBSKernel/src/Expr/EquatorialCentroid.cc b/CEP/Calibration/BBSKernel/src/Expr/EquatorialCentroid.cc
index afbf96b0db29d08fbab2f9b7174afbc526f31df6..5e6f24dd1f672d229d9afb1f14d8f3bddd793d47 100644
--- a/CEP/Calibration/BBSKernel/src/Expr/EquatorialCentroid.cc
+++ b/CEP/Calibration/BBSKernel/src/Expr/EquatorialCentroid.cc
@@ -77,6 +77,8 @@ const Vector<2> EquatorialCentroid::evaluateExpr(const Request &request,
         flags.push_back(args[i].flags());
     }
 
+    EXPR_TIMER_START();
+
     // Evaluate flags.
     result.setFlags(mergeFlags(flags.begin(), flags.end()));
 
@@ -125,10 +127,12 @@ const Vector<2> EquatorialCentroid::evaluateExpr(const Request &request,
         }
     }
 
+    EXPR_TIMER_STOP();
+
     return result;
 }
 
-const Vector<2>::View EquatorialCentroid::evaluateImpl(const Grid &grid,
+const Vector<2>::View EquatorialCentroid::evaluateImpl(const Grid&,
     const vector<Vector<2>::View> &args) const
 {
     Matrix cosDec = cos(args[0](1));
diff --git a/CEP/Calibration/BBSKernel/src/Expr/ExprAdaptors.cc b/CEP/Calibration/BBSKernel/src/Expr/ExprAdaptors.cc
index bcf49a4f2f4aeb33493e0df7a1952f822b8620dc..7e53892b60951a7d31b444682e8ed68a49e13628 100644
--- a/CEP/Calibration/BBSKernel/src/Expr/ExprAdaptors.cc
+++ b/CEP/Calibration/BBSKernel/src/Expr/ExprAdaptors.cc
@@ -81,6 +81,8 @@ const JonesMatrix AsExpr<JonesMatrix>::evaluateExpr(const Request &request,
         result.setElement(i, args[i].element());
     }
 
+    EXPR_TIMER_START();
+
     // Evaluate flags.
     FlagArray flags[4];
     for(unsigned int i = 0; i < 4; ++i)
@@ -89,6 +91,8 @@ const JonesMatrix AsExpr<JonesMatrix>::evaluateExpr(const Request &request,
     }
     result.setFlags(mergeFlags(flags, flags + 4));
 
+    EXPR_TIMER_STOP();
+
     return result;
 }
 
@@ -124,6 +128,8 @@ const JonesMatrix AsDiagonalMatrix::evaluateExpr(const Request &request,
     args[0] = argument0()->evaluate(request, cache, grid);
     args[1] = argument1()->evaluate(request, cache, grid);
 
+    EXPR_TIMER_START();
+
     result.setElement(0, 0, args[0].element());
     result.assign(0, 1, Matrix(makedcomplex(0.0, 0.0)));
     result.assign(1, 0, Matrix(makedcomplex(0.0, 0.0)));
@@ -135,6 +141,8 @@ const JonesMatrix AsDiagonalMatrix::evaluateExpr(const Request &request,
     flags[1] = args[1].flags();
     result.setFlags(mergeFlags(flags, flags + 2));
 
+    EXPR_TIMER_STOP();
+
     return result;
 }
 
diff --git a/CEP/Calibration/BBSKernel/src/Expr/ExprParm.cc b/CEP/Calibration/BBSKernel/src/Expr/ExprParm.cc
index fac38c0fc0e46c3430bb83c86cd496e93c03621a..35acc71edb891e8f431d1476af62431f4b9a512b 100644
--- a/CEP/Calibration/BBSKernel/src/Expr/ExprParm.cc
+++ b/CEP/Calibration/BBSKernel/src/Expr/ExprParm.cc
@@ -55,9 +55,11 @@ bool ExprParm::isDependent() const
     return itsPValueFlag;
 }
 
-const Scalar ExprParm::evaluateExpr(const Request &request, Cache &cache,
+const Scalar ExprParm::evaluateExpr(const Request &request, Cache&,
     unsigned int grid) const
 {
+    EXPR_TIMER_START();
+
     // Get the result from the Parm.
     vector<casa::Array<double> > buffers;
     itsParm->getResult(buffers, request[grid], getPValueFlag()); //false);
@@ -112,9 +114,9 @@ const Scalar ExprParm::evaluateExpr(const Request &request, Cache &cache,
         }
     }
 
-    Scalar scalar;
-    scalar.setElement(result);
-    return scalar;
+    EXPR_TIMER_STOP();
+
+    return Scalar(result);
 }
 
 } //# namespace BBS
diff --git a/CEP/Calibration/BBSKernel/src/Expr/ExprVisData.cc b/CEP/Calibration/BBSKernel/src/Expr/ExprVisData.cc
index 613d789ca5bed841d8e9690f5565cf204bdfa9e1..ba6a186c240a1463bcd4a0014ea87e847f1fd26c 100644
--- a/CEP/Calibration/BBSKernel/src/Expr/ExprVisData.cc
+++ b/CEP/Calibration/BBSKernel/src/Expr/ExprVisData.cc
@@ -58,6 +58,8 @@ void ExprVisData::setCorrelation(size_t element, Correlation::Type correlation)
 const JonesMatrix ExprVisData::evaluateExpr(const Request &request,
     Cache&, unsigned int grid) const
 {
+    EXPR_TIMER_START();
+
     vector<pair<size_t, size_t> > axisMapping[2];
     makeAxisMapping(request[grid][FREQ], itsChunk->grid()[FREQ],
         back_inserter(axisMapping[FREQ]));
@@ -76,6 +78,8 @@ const JonesMatrix ExprVisData::evaluateExpr(const Request &request,
     result.assign(1, 0, copyData(request[grid], 2, axisMapping));
     result.assign(1, 1, copyData(request[grid], 3, axisMapping));
 
+    EXPR_TIMER_STOP();
+
     return result;
 }
 
diff --git a/CEP/Calibration/BBSKernel/src/Expr/IonPhaseShift.cc b/CEP/Calibration/BBSKernel/src/Expr/IonPhaseShift.cc
index a92793e173f7c56df7df5201e589ad51feae4264..af0ae825c2bb373fca31f57816bf75c922538d42 100644
--- a/CEP/Calibration/BBSKernel/src/Expr/IonPhaseShift.cc
+++ b/CEP/Calibration/BBSKernel/src/Expr/IonPhaseShift.cc
@@ -148,6 +148,8 @@ const JonesMatrix IonPhaseShift::evaluateExpr(const Request &request,
 //        LOG_DEBUG_STR("TECfit_white:1:" << value.value(1));
     }
 
+    EXPR_TIMER_START();
+
     // Compute main value.
     Grid reqGrid(request[grid]);
     const size_t nFreq = reqGrid[FREQ]->size();
@@ -247,11 +249,13 @@ const JonesMatrix IonPhaseShift::evaluateExpr(const Request &request,
 //    LOG_DEBUG_STR("SHIFT Y: " << shiftY);
 
     JonesMatrix result;
+    result.setFlags(mergeFlags(flags.begin(), flags.end()));
     result.assign(0, 0, shiftX);
     result.assign(0, 1, Matrix(makedcomplex(0.0, 0.0)));
     result.assign(1, 0, Matrix(makedcomplex(0.0, 0.0)));
     result.assign(1, 1, shiftY);
-    result.setFlags(mergeFlags(flags.begin(), flags.end()));
+
+    EXPR_TIMER_STOP();
 
     return result;
 }
diff --git a/CEP/Calibration/BBSKernel/src/Expr/LMN.cc b/CEP/Calibration/BBSKernel/src/Expr/LMN.cc
index c835351a964ccf7dfad6125ec8eccc5dfd8d8635..ebdb3d1c22a5e9590a5438cf54f39f8422a0c667 100644
--- a/CEP/Calibration/BBSKernel/src/Expr/LMN.cc
+++ b/CEP/Calibration/BBSKernel/src/Expr/LMN.cc
@@ -43,7 +43,7 @@ LMN::LMN(const casa::MDirection &reference,
 {
 }
 
-const Vector<3>::View LMN::evaluateImpl(const Grid &grid,
+const Vector<3>::View LMN::evaluateImpl(const Grid&,
     const Vector<2>::View &direction) const
 {
     casa::Quantum<casa::Vector<casa::Double> > angles =
diff --git a/CEP/Calibration/BBSKernel/src/Expr/Literal.cc b/CEP/Calibration/BBSKernel/src/Expr/Literal.cc
index 0cd3917edd036901b865578e098236d84b1df8e1..349d25fe2784bcdfb33fe14399b5577966c8bbb9 100644
--- a/CEP/Calibration/BBSKernel/src/Expr/Literal.cc
+++ b/CEP/Calibration/BBSKernel/src/Expr/Literal.cc
@@ -40,10 +40,7 @@ Literal::Literal(dcomplex value)
 
 const Scalar Literal::evaluateExpr(const Request&, Cache&, unsigned int) const
 {
-    Scalar result;
-    result.assign(itsValue);
-
-    return result;
+    return Scalar(itsValue);
 }
 
 } //# namespace BBS
diff --git a/CEP/Calibration/BBSKernel/src/Expr/MatrixInverse.cc b/CEP/Calibration/BBSKernel/src/Expr/MatrixInverse.cc
index bf5c23368eec7c96fba0a934a5a73d4729658dbc..81aca5e994b5939426805ec20d70f85c4f53f3f6 100644
--- a/CEP/Calibration/BBSKernel/src/Expr/MatrixInverse.cc
+++ b/CEP/Calibration/BBSKernel/src/Expr/MatrixInverse.cc
@@ -49,7 +49,7 @@ MatrixInverse::MatrixInverse(const Expr<JonesMatrix>::ConstPtr &expr)
 {
 }
 
-const JonesMatrix::View MatrixInverse::evaluateImpl(const Grid &grid,
+const JonesMatrix::View MatrixInverse::evaluateImpl(const Grid&,
     const JonesMatrix::View &arg0) const
 {
     JonesMatrix::View result;
diff --git a/CEP/Calibration/BBSKernel/src/Expr/MatrixMul2.cc b/CEP/Calibration/BBSKernel/src/Expr/MatrixMul2.cc
index 91f289b97f964a75db9b77a69170e683e01625f1..80d570846fb828e970e7907dfc8b773ca88fa0d0 100644
--- a/CEP/Calibration/BBSKernel/src/Expr/MatrixMul2.cc
+++ b/CEP/Calibration/BBSKernel/src/Expr/MatrixMul2.cc
@@ -35,7 +35,7 @@ MatrixMul2::MatrixMul2(const Expr<JonesMatrix>::ConstPtr &lhs,
 {
 }
 
-const JonesMatrix::View MatrixMul2::evaluateImpl(const Grid &grid,
+const JonesMatrix::View MatrixMul2::evaluateImpl(const Grid&,
     const JonesMatrix::View &lhs, const JonesMatrix::View &rhs) const
 {
     // Determine dependencies.
diff --git a/CEP/Calibration/BBSKernel/src/Expr/MatrixMul3.cc b/CEP/Calibration/BBSKernel/src/Expr/MatrixMul3.cc
index 1a904c2a1f8870c73e34d931bf8f31ed314abbf3..01205476e09046c6b20fda634b7dc63ca0e8a960 100644
--- a/CEP/Calibration/BBSKernel/src/Expr/MatrixMul3.cc
+++ b/CEP/Calibration/BBSKernel/src/Expr/MatrixMul3.cc
@@ -38,7 +38,7 @@ MatrixMul3::MatrixMul3(const Expr<JonesMatrix>::ConstPtr &left,
 {
 }
 
-const JonesMatrix::View MatrixMul3::evaluateImpl(const Grid &grid,
+const JonesMatrix::View MatrixMul3::evaluateImpl(const Grid&,
     const JonesMatrix::View &left, const JonesMatrix::View &mid,
     const JonesMatrix::View &right) const
 {
diff --git a/CEP/Calibration/BBSKernel/src/Expr/MatrixSum.cc b/CEP/Calibration/BBSKernel/src/Expr/MatrixSum.cc
index 65b66da081350e0878a51ab26f3e3dd32eb99719..0b8a229058d0ff1378e465c7766b135ea3c67d2d 100644
--- a/CEP/Calibration/BBSKernel/src/Expr/MatrixSum.cc
+++ b/CEP/Calibration/BBSKernel/src/Expr/MatrixSum.cc
@@ -59,6 +59,8 @@ ExprBase::ConstPtr MatrixSum::argument(unsigned int i) const
 const JonesMatrix MatrixSum::evaluateExpr(const Request &request, Cache &cache,
     unsigned int grid) const
 {
+    EXPR_TIMER_START();
+
     // TODO: Use unsigned integer type for Matrix size.
     int nx = request[grid][FREQ]->size();
     int ny = request[grid][TIME]->size();
@@ -79,7 +81,9 @@ const JonesMatrix MatrixSum::evaluateExpr(const Request &request, Cache &cache,
     // this sum somehow.
     for(size_t i = 0; i < itsExpr.size(); ++i)
     {
+        EXPR_TIMER_STOP();
         const JonesMatrix term = itsExpr[i]->evaluate(request, cache, grid);
+        EXPR_TIMER_START();
 
         // Update flags.
         if(term.hasFlags())
@@ -101,15 +105,14 @@ const JonesMatrix MatrixSum::evaluateExpr(const Request &request, Cache &cache,
         element[1][1].value() += term.element(1, 1).value();
     }
 
-    JonesMatrix result;
+    JonesMatrix result(element[0][0], element[0][1], element[1][0],
+        element[1][1]);
     if(haveFlags)
     {
         result.setFlags(flags);
     }
-    result.setElement(0, 0, element[0][0]);
-    result.setElement(0, 1, element[0][1]);
-    result.setElement(1, 0, element[1][0]);
-    result.setElement(1, 1, element[1][1]);
+
+    EXPR_TIMER_STOP();
 
     return result;
 }
diff --git a/CEP/Calibration/BBSKernel/src/Expr/PointCoherence.cc b/CEP/Calibration/BBSKernel/src/Expr/PointCoherence.cc
index b7f0c7f999599a76b80a78e927576286bcfac0c5..c5f763391a375644126651224900c568b44d8795 100644
--- a/CEP/Calibration/BBSKernel/src/Expr/PointCoherence.cc
+++ b/CEP/Calibration/BBSKernel/src/Expr/PointCoherence.cc
@@ -34,7 +34,7 @@ PointCoherence::PointCoherence(const Expr<Vector<4> >::ConstPtr &stokes)
 {
 }
 
-const JonesMatrix::View PointCoherence::evaluateImpl(const Grid &grid,
+const JonesMatrix::View PointCoherence::evaluateImpl(const Grid&,
     const Vector<4>::View &stokes) const
 {
     JonesMatrix::View result;
diff --git a/CEP/Calibration/BBSKernel/src/Expr/PointSource.cc b/CEP/Calibration/BBSKernel/src/Expr/PointSource.cc
index cc37205a6fa764bac21fe18b01706bdcf9f0521b..9b9a1157e641fea78378ff768ec2c89b943b941f 100644
--- a/CEP/Calibration/BBSKernel/src/Expr/PointSource.cc
+++ b/CEP/Calibration/BBSKernel/src/Expr/PointSource.cc
@@ -76,8 +76,8 @@ PointSource::PointSource(const SourceInfo &source, Scope &scope)
 }
 
 Expr<JonesMatrix>::Ptr
-PointSource::coherence(const Expr<Vector<3> >::ConstPtr &uvwLHS,
-    const Expr<Vector<3> >::ConstPtr &uvwRHS) const
+PointSource::coherence(const Expr<Vector<3> >::ConstPtr&,
+    const Expr<Vector<3> >::ConstPtr&) const
 {
     if(itsCoherence)
     {
diff --git a/CEP/Calibration/BBSKernel/src/Expr/PolynomialLayer.cc b/CEP/Calibration/BBSKernel/src/Expr/PolynomialLayer.cc
index 3e5baf70607e313c7a3de5cdebc4cfc13f5652e4..fac09f1ba17bf13d05db061e89334b620f0dabbf 100644
--- a/CEP/Calibration/BBSKernel/src/Expr/PolynomialLayer.cc
+++ b/CEP/Calibration/BBSKernel/src/Expr/PolynomialLayer.cc
@@ -77,6 +77,8 @@ const Scalar PolynomialLayer::evaluateExpr(const Request &request,
         flags.push_back(coeff[i].flags());
     }
 
+    EXPR_TIMER_START();
+
     // Evaluate flags.
     result.setFlags(mergeFlags(flags.begin(), flags.end()));
 
@@ -127,6 +129,8 @@ const Scalar PolynomialLayer::evaluateExpr(const Request &request,
         }
     }
 
+    EXPR_TIMER_STOP();
+
     return result;
 }
 
diff --git a/CEP/Calibration/BBSKernel/src/Expr/Resampler.cc b/CEP/Calibration/BBSKernel/src/Expr/Resampler.cc
index 018f610c93a7f494049cdece10731064336925b5..a79e819e034c1a1177fe5e24ace4817079a3496a 100644
--- a/CEP/Calibration/BBSKernel/src/Expr/Resampler.cc
+++ b/CEP/Calibration/BBSKernel/src/Expr/Resampler.cc
@@ -43,6 +43,8 @@ const JonesMatrix Resampler::evaluateExpr(const Request &request, Cache &cache,
     // Evaluate arguments.
     const JonesMatrix arg = argument0()->evaluate(request, cache, itsGridId);
 
+    EXPR_TIMER_START();
+
     // Create axis mappings.
     vector<Span> axisMap[2];
     makeAxisMap(request[itsGridId][FREQ], request[grid][FREQ],
@@ -107,6 +109,8 @@ const JonesMatrix Resampler::evaluateExpr(const Request &request, Cache &cache,
         }
     }
 
+    EXPR_TIMER_STOP();
+
     return result;
 }
 
diff --git a/CEP/Calibration/BBSKernel/src/Expr/ScalarMatrixMul.cc b/CEP/Calibration/BBSKernel/src/Expr/ScalarMatrixMul.cc
index e303ae3c894f132254e78ebba44a68f5f7a5af04..3fcb4c9267706d8ce879e68f3ce789a130cb5fbb 100644
--- a/CEP/Calibration/BBSKernel/src/Expr/ScalarMatrixMul.cc
+++ b/CEP/Calibration/BBSKernel/src/Expr/ScalarMatrixMul.cc
@@ -37,7 +37,7 @@ ScalarMatrixMul::ScalarMatrixMul(const Expr<Scalar>::ConstPtr &lhs,
 {
 }
 
-const JonesMatrix::View ScalarMatrixMul::evaluateImpl(const Grid &grid,
+const JonesMatrix::View ScalarMatrixMul::evaluateImpl(const Grid&,
     const Scalar::View &lhs, const JonesMatrix::View &rhs) const
 {
     JonesMatrix::View result;
diff --git a/CEP/Calibration/BBSKernel/src/Expr/SpectralIndex.cc b/CEP/Calibration/BBSKernel/src/Expr/SpectralIndex.cc
index f990752a99900e87ffefb9f6b9ddb14b2d9cef5c..775961f17d35cd991ae54980c2b592c22e75ae79 100644
--- a/CEP/Calibration/BBSKernel/src/Expr/SpectralIndex.cc
+++ b/CEP/Calibration/BBSKernel/src/Expr/SpectralIndex.cc
@@ -83,6 +83,8 @@ const Scalar SpectralIndex::evaluateExpr(const Request &request, Cache &cache,
         flags.push_back(coeff[i].flags());
     }
 
+    EXPR_TIMER_START();
+
     // Evaluate flags.
     result.setFlags(mergeFlags(flags.begin(), flags.end()));
 
@@ -136,6 +138,8 @@ const Scalar SpectralIndex::evaluateExpr(const Request &request, Cache &cache,
         }
     }
 
+    EXPR_TIMER_STOP();
+
     return result;
 }
 
diff --git a/CEP/Calibration/BBSKernel/src/Expr/StationUVW.cc b/CEP/Calibration/BBSKernel/src/Expr/StationUVW.cc
index 3f83c999186ac90c0b033ed60e212e951a35e17f..2be7282a6b472303ddf49b2ccb8a280c0dca1613 100644
--- a/CEP/Calibration/BBSKernel/src/Expr/StationUVW.cc
+++ b/CEP/Calibration/BBSKernel/src/Expr/StationUVW.cc
@@ -48,9 +48,11 @@ StationUVW::StationUVW(const casa::MPosition &position,
 {
 }
 
-const Vector<3> StationUVW::evaluateExpr(const Request &request, Cache &cache,
+const Vector<3> StationUVW::evaluateExpr(const Request &request, Cache&,
     unsigned int grid) const
 {
+    EXPR_TIMER_START();
+
     // Get the station position relative to the array reference position
     // (to keep values small).
     const casa::MPosition mDeltaPos(itsPosition.getValue()
@@ -104,6 +106,8 @@ const Vector<3> StationUVW::evaluateExpr(const Request &request, Cache &cache,
     result.assign(1, V);
     result.assign(2, W);
 
+    EXPR_TIMER_STOP();
+
     return result;
 }
 
diff --git a/CEP/Calibration/BBSKernel/src/Expr/Timer.cc b/CEP/Calibration/BBSKernel/src/Expr/Timer.cc
new file mode 100644
index 0000000000000000000000000000000000000000..d186c1c95d0058d925b1a17c5e92243e763dd09e
--- /dev/null
+++ b/CEP/Calibration/BBSKernel/src/Expr/Timer.cc
@@ -0,0 +1,112 @@
+//# Timer.cc: Singleton that can be used to measure the time spent in classes derived from Expr.
+//#
+//# Copyright (C) 2011
+//# ASTRON (Netherlands Institute for Radio Astronomy)
+//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+//#
+//# This file is part of the LOFAR software suite.
+//# The LOFAR software suite 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.
+//#
+//# The LOFAR software suite 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 the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>.
+//#
+//# $Id$
+
+#include <lofar_config.h>
+#include <BBSKernel/Expr/Timer.h>
+
+#include <lofar_config.h>
+#include <BBSKernel/Expr/Timer.h>
+
+#include <BBSKernel/Expr/Expr.h>
+#include <Common/lofar_typeinfo.h>
+
+#ifdef HAVE_CPLUS_DEMANGLE
+#include <demangle.h>
+#endif
+
+namespace LOFAR
+{
+namespace BBS
+{
+
+void TimerImpl::reset()
+{
+    itsTimers.clear();
+}
+
+void TimerImpl::dump(ostream &out) const
+{
+#ifndef LOFAR_BBSKERNEL_EXPR_TIMER
+    out << "Timing of expression tree nodes not supported, please recompile"
+        " with -DLOFAR_BBSKERNEL_EXPR_TIMER to enable this feature." << endl;
+#else
+    typedef map<string, NSTimer>::const_iterator IterType;
+
+    double total = 0.0;
+    for(IterType it = itsTimers.begin(), end = itsTimers.end(); it != end;
+        ++it)
+    {
+        string name = it->first;
+
+#ifdef HAVE_CPLUS_DEMANGLE
+        char *fqname = cplus_demangle(name.c_str(),
+            DMGL_ANSI | DMGL_PARAMS | DMGL_TYPES);
+        if(fqname)
+        {
+            name = string(fqname);
+            free(fqname);
+        }
+#endif
+        const NSTimer &timer = it->second;
+        double elapsed = timer.getElapsed();
+        total += elapsed;
+        unsigned long long count = timer.getCount();
+        double average = count > 0 ? elapsed / count : 0.0;
+
+        out << "TIMER s EXPRTIMER " << name << " total " << elapsed
+            << " count " << count << " avg " << average << endl;
+    }
+
+    out << "TIMER s EXPRTIMER ALL total " << total << endl;
+#endif
+}
+
+void TimerImpl::reset(const ExprBase *expr)
+{
+    string name(typeid(*expr).name());
+    itsTimers[name].reset();
+}
+
+void TimerImpl::start(const ExprBase *expr)
+{
+    string name(typeid(*expr).name());
+    start(name);
+}
+
+void TimerImpl::stop(const ExprBase *expr)
+{
+    string name(typeid(*expr).name());
+    stop(name);
+}
+
+void TimerImpl::start(const string &name)
+{
+    itsTimers[name].start();
+}
+
+void TimerImpl::stop(const string &name)
+{
+    itsTimers[name].stop();
+}
+
+} //# namespace BBS
+} //# namespace LOFAR
diff --git a/CEP/Calibration/BBSKernel/src/MeasurementExprLOFAR.cc b/CEP/Calibration/BBSKernel/src/MeasurementExprLOFAR.cc
index 556e561cc338e6bfbc7fa405519ff4108ecacc63..04f0c8f88fdaf48fe4058f10423b7747a69250c8 100644
--- a/CEP/Calibration/BBSKernel/src/MeasurementExprLOFAR.cc
+++ b/CEP/Calibration/BBSKernel/src/MeasurementExprLOFAR.cc
@@ -623,6 +623,8 @@ const JonesMatrix MeasurementExprLOFAR::evaluate(unsigned int i)
     ASSERT(i < itsExpr.size());
     const JonesMatrix model = itsExpr[i]->evaluate(itsRequest, itsCache, 0);
 
+    EXPR_TIMER_START_NAMED("MeasurementExprLOFAR::evaluate()");
+
     // Pass-through the flags.
     result.setFlags(model.flags());
 
@@ -656,6 +658,8 @@ const JonesMatrix MeasurementExprLOFAR::evaluate(unsigned int i)
         it.advance(key);
     }
 
+    EXPR_TIMER_STOP_NAMED("MeasurementExprLOFAR::evaluate()");
+
     return result;
 }
 
diff --git a/CEP/Calibration/BBSKernel/src/VisEquator.cc b/CEP/Calibration/BBSKernel/src/VisEquator.cc
index 8d8cb9ae9fc752b7fdfc0316f5c38757b5c7e501..c2038a3a79b6eb1b0534a350b2c01666a77cd8ab 100644
--- a/CEP/Calibration/BBSKernel/src/VisEquator.cc
+++ b/CEP/Calibration/BBSKernel/src/VisEquator.cc
@@ -24,6 +24,7 @@
 #include <lofar_config.h>
 #include <BBSKernel/VisEquator.h>
 #include <BBSKernel/Exceptions.h>
+#include <BBSKernel/Expr/Timer.h>
 
 #include <Common/lofar_iomanip.h>
 #include <Common/LofarLogger.h>
@@ -64,6 +65,7 @@ VisEquator::VisEquator(const VisBuffer::Ptr &lhs, const MeasurementExpr::Ptr &rh
 VisEquator::~VisEquator()
 {
     itsRHS->clearSolvables();
+    Timer::instance().reset();
 }
 
 void VisEquator::setSolutionGrid(const Grid &grid)
@@ -199,6 +201,7 @@ void VisEquator::clearStats()
 {
     itsProcTimer.reset();
     itsProcContext.clearStats();
+    Timer::instance().reset();
 }
 
 void VisEquator::dumpStats(ostream &out) const
@@ -207,13 +210,13 @@ void VisEquator::dumpStats(ostream &out) const
 
     double elapsed = itsProcTimer.getElapsed();
     unsigned long long count = itsProcTimer.getCount();
-    const double speed = elapsed > 0.0 ? count / elapsed : 0.0;
     double average = count > 0 ? elapsed / count : 0.0;
 
-    out << "VisEquator statistics:" << endl;
-    out << "Speed: " << fixed << speed << " samples/s" << endl;
-    out << "No. of samples processed (unflagged): " << fixed << context.count
-        << endl;
+    const double speed = elapsed > 0.0 ? context.count / elapsed : 0.0;
+
+    out << endl << "VisEquator statistics:" << endl;
+    out << "unflagged samples: " << fixed << context.count
+        << " speed: " << fixed << speed << " samples/s" << endl;
     out << "TIMER s VISEQUATOR ALL total " << elapsed << " count " << count
         << " avg " << average << endl;
 
@@ -227,6 +230,8 @@ void VisEquator::dumpStats(ostream &out) const
             << " total" << " " << elapsed << " count " << count << " avg "
             << elapsed / count << endl;
     }
+
+    Timer::instance().dump(out);
 }
 
 void VisEquator::setBaselineMask(const BaselineMask &mask)