diff --git a/.gitattributes b/.gitattributes
index d4d0629ac0703a82689f16baf05df24e950a1d35..c1e14e0d2cc4a6d88d09ae58faff3576f492f2a3 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -19,12 +19,20 @@ CEP/Calibration/BBSControl/scripts/__init__.py -text
 CEP/Calibration/BBSControl/scripts/parmdbplot.py -text
 CEP/Calibration/BBSControl/src/calibrate -text
 CEP/Calibration/BBSControl/src/calibrate-part -text
+CEP/Calibration/BBSKernel/include/BBSKernel/ElementBeamExpr.h -text
+CEP/Calibration/BBSKernel/include/BBSKernel/Expr/EquatorialCentroid.h -text
+CEP/Calibration/BBSKernel/include/BBSKernel/Expr/Scope.h -text
+CEP/Calibration/BBSKernel/include/BBSKernel/IonosphereExpr.h -text
 CEP/Calibration/BBSKernel/src/Contrib/JPH_DipoleBeam/element_beam_HAMAKER_HBA.coeff -text
 CEP/Calibration/BBSKernel/src/Contrib/JPH_DipoleBeam/element_beam_HAMAKER_LBA.coeff -text
 CEP/Calibration/BBSKernel/src/Contrib/SBY_DipoleBeam/beam_dr_phi.c -text
 CEP/Calibration/BBSKernel/src/Contrib/SBY_DipoleBeam/beam_dr_theta.c -text
 CEP/Calibration/BBSKernel/src/Contrib/SBY_DipoleBeam/hba_beam_phi.c -text
 CEP/Calibration/BBSKernel/src/Contrib/SBY_DipoleBeam/hba_beam_theta.c -text
+CEP/Calibration/BBSKernel/src/ElementBeamExpr.cc -text
+CEP/Calibration/BBSKernel/src/Expr/EquatorialCentroid.cc -text
+CEP/Calibration/BBSKernel/src/Expr/Scope.cc -text
+CEP/Calibration/BBSKernel/src/IonosphereExpr.cc -text
 CEP/Calibration/BBSKernel/test/tJonesCMul3.cc -text
 CEP/Calibration/BBSKernel/test/tJonesCMul3.sh -text
 CEP/Calibration/BBSKernel/test/tParmMerge.in_mep1/DEFAULTVALUES/table.dat -text svneol=unset#unset
diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/ElementBeamExpr.h b/CEP/Calibration/BBSKernel/include/BBSKernel/ElementBeamExpr.h
new file mode 100644
index 0000000000000000000000000000000000000000..a25f2cc9e2cef8eca1af84fc473814d1f35dd6dd
--- /dev/null
+++ b/CEP/Calibration/BBSKernel/include/BBSKernel/ElementBeamExpr.h
@@ -0,0 +1,103 @@
+//# ElementBeamExpr.h: Wrapper class that constructs the correct beam expr based
+//# on the BeamConfig instance provided in the constructor. It also caches any
+//# shared auxilliary data.
+//#
+//# Copyright (C) 2009
+//# 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_ELEMENTBEAMEXPR_H
+#define LOFAR_BBSKERNEL_ELEMENTBEAMEXPR_H
+
+// \file
+// Wrapper class that constructs the correct beam expr based on the BeamConfig
+// instance provided in the constructor. It also caches any shared auxilliary
+// data.
+
+#include <BBSKernel/Expr/Expr.h>
+#include <BBSKernel/Expr/HamakerDipole.h>
+
+#include <Common/lofar_smartptr.h>
+
+#include <casa/OS/Path.h>
+
+namespace LOFAR
+{
+namespace BBS
+{
+
+class BeamConfig;
+class Scope;
+
+// \addtogroup BBSKernel
+// @{
+
+class ElementBeamExpr
+{
+public:
+    typedef shared_ptr<ElementBeamExpr>         Ptr;
+    typedef shared_ptr<const ElementBeamExpr>   ConstPtr;
+
+    static ElementBeamExpr::Ptr create(const BeamConfig &config, Scope &scope);
+
+    virtual ~ElementBeamExpr();
+
+    virtual Expr<JonesMatrix>::Ptr
+        construct(const Expr<Vector<2> >::ConstPtr &direction,
+            const Expr<Scalar>::ConstPtr &orientation) const = 0;
+};
+
+class HamakerBeamExpr: public ElementBeamExpr
+{
+public:
+    typedef shared_ptr<HamakerBeamExpr>         Ptr;
+    typedef shared_ptr<const HamakerBeamExpr>   ConstPtr;
+
+    HamakerBeamExpr(const BeamConfig &config, Scope &scope);
+
+    virtual Expr<JonesMatrix>::Ptr
+        construct(const Expr<Vector<2> >::ConstPtr &direction,
+            const Expr<Scalar>::ConstPtr &orientation) const;
+
+private:
+    HamakerBeamCoeff    itsCoeff;
+};
+
+class YatawattaBeamExpr: public ElementBeamExpr
+{
+public:
+    typedef shared_ptr<YatawattaBeamExpr>       Ptr;
+    typedef shared_ptr<const YatawattaBeamExpr> ConstPtr;
+
+    YatawattaBeamExpr(const BeamConfig &config, Scope &scope);
+
+    virtual Expr<JonesMatrix>::Ptr
+        construct(const Expr<Vector<2> >::ConstPtr &direction,
+            const Expr<Scalar>::ConstPtr &orientation) const;
+
+private:
+    casa::Path  itsModulePath[2];
+};
+
+// @}
+
+} //# namespace BBS
+} //# namespace LOFAR
+
+#endif
diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/EquatorialCentroid.h b/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/EquatorialCentroid.h
new file mode 100644
index 0000000000000000000000000000000000000000..5eb0b14e9aed7e829490854baa1e9c26c287ce3c
--- /dev/null
+++ b/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/EquatorialCentroid.h
@@ -0,0 +1,88 @@
+//# EquatorialCentroid.h: Compute the centroid of a list of positions in
+//# spherical coordinates.
+//#
+//# Copyright (C) 2009
+//# 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_SPHERICALCENTROID_H
+#define LOFAR_BBSKERNEL_EXPR_SPHERICALCENTROID_H
+
+// \file
+// Compute the centroid of a list of positions in spherical coordinates.
+
+#include <BBSKernel/Expr/Expr.h>
+
+namespace LOFAR
+{
+namespace BBS
+{
+
+// \addtogroup Expr
+// @{
+
+class EquatorialCentroid: public Expr<Vector<2> >
+{
+public:
+    typedef shared_ptr<EquatorialCentroid>       Ptr;
+    typedef shared_ptr<const EquatorialCentroid> ConstPtr;
+
+    EquatorialCentroid();
+
+    template <typename T_ITER>
+    EquatorialCentroid(T_ITER first, T_ITER last);
+
+    virtual ~EquatorialCentroid();
+
+    void connect(const Expr<Vector<2> >::ConstPtr &arg);
+
+protected:
+    virtual unsigned int nArguments() const;
+    virtual ExprBase::ConstPtr argument(unsigned int i) const;
+
+    virtual const Vector<2> evaluateExpr(const Request &request, Cache &cache,
+        unsigned int grid) const;
+
+    const Vector<2>::View evaluateImpl(const Grid &grid,
+        const vector<Vector<2>::View> &args) const;
+
+private:
+    vector<Expr<Vector<2> >::ConstPtr>  itsArgs;
+};
+
+// @}
+
+// -------------------------------------------------------------------------- //
+// - EquatorialCentroid implementation                                       - //
+// -------------------------------------------------------------------------- //
+
+template <typename T_ITER>
+EquatorialCentroid::EquatorialCentroid(T_ITER first, T_ITER last)
+{
+    for(; first != last; ++first)
+    {
+        connect(*first);
+        itsArgs.push_back(*first);
+    }
+}
+
+} //# namespace BBS
+} //# namespace LOFAR
+
+#endif
diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/Scope.h b/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/Scope.h
new file mode 100644
index 0000000000000000000000000000000000000000..40e3182896c5cf81c9a61b7efeeb9ee87876ea0e
--- /dev/null
+++ b/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/Scope.h
@@ -0,0 +1,69 @@
+//# Scope.h: A list of ExprParm instances that are used by a model expression.
+//#
+//# Copyright (C) 2009
+//# 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_SCOPE_H
+#define LOFAR_BBSKERNEL_EXPR_SCOPE_H
+
+// \file
+// A list of ExprParm instances that are used by a model expression.
+
+#include <Common/lofar_map.h>
+#include <Common/lofar_string.h>
+
+#include <BBSKernel/Expr/ExprParm.h>
+
+namespace LOFAR
+{
+namespace BBS
+{
+
+// \addtogroup Expr
+// @{
+
+class Scope
+{
+public:
+    typedef map<unsigned int, ExprParm::Ptr>::iterator          iterator;
+    typedef map<unsigned int, ExprParm::Ptr>::const_iterator    const_iterator;
+
+    void clear();
+
+    ExprParm::Ptr operator()(unsigned int category, const string &name);
+
+    iterator begin();
+    iterator end();
+    const_iterator begin() const;
+    const_iterator end() const;
+
+    iterator find(unsigned int id);
+    const_iterator find(unsigned int id) const;
+
+private:
+    map<unsigned int, ExprParm::Ptr>    itsParms;
+};
+
+// @}
+
+} //# namespace BBS
+} //# namespace LOFAR
+
+#endif
diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/IonosphereExpr.h b/CEP/Calibration/BBSKernel/include/BBSKernel/IonosphereExpr.h
new file mode 100644
index 0000000000000000000000000000000000000000..e5b63cf8adae3b6be76811af339d2c591e77403e
--- /dev/null
+++ b/CEP/Calibration/BBSKernel/include/BBSKernel/IonosphereExpr.h
@@ -0,0 +1,88 @@
+//# IonosphereExpr.h: Wrapper class that constructs ionosphere expressions based
+//# on the IonosphereConfig instance provided to the constructor. The class also
+//# stores a reference to any shared auxilliary data.
+//#
+//# Copyright (C) 2009
+//# 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_IONOSPHEREEXPR_H
+#define LOFAR_BBSKERNEL_IONOSPHEREEXPR_H
+
+// \file
+// Wrapper class that constructs ionosphere expressions based on the
+// IonosphereConfig instance provided to the constructor. The class also stores
+// a reference to any shared auxilliary data.
+
+#include <BBSKernel/Expr/Expr.h>
+#include <Common/lofar_smartptr.h>
+#include <Common/lofar_vector.h>
+
+namespace casa
+{
+    class MPosition;
+}
+
+namespace LOFAR
+{
+namespace BBS
+{
+
+class IonosphereConfig;
+class Scope;
+
+// \addtogroup BBSKernel
+// @{
+
+class IonosphereExpr
+{
+public:
+    typedef shared_ptr<IonosphereExpr>          Ptr;
+    typedef shared_ptr<const IonosphereExpr>    ConstPtr;
+
+    static IonosphereExpr::Ptr create(const IonosphereConfig &config,
+        Scope &scope);
+
+    virtual ~IonosphereExpr();
+
+    virtual Expr<JonesMatrix>::Ptr construct(const casa::MPosition &position,
+        const Expr<Vector<4> >::ConstPtr &piercePoint) const = 0;
+};
+
+class PolynomialLayerExpr: public IonosphereExpr
+{
+public:
+    typedef shared_ptr<PolynomialLayerExpr>         Ptr;
+    typedef shared_ptr<const PolynomialLayerExpr>   ConstPtr;
+
+    PolynomialLayerExpr(const IonosphereConfig &config, Scope &scope);
+
+    virtual Expr<JonesMatrix>::Ptr construct(const casa::MPosition &position,
+        const Expr<Vector<4> >::ConstPtr &piercePoint) const;
+
+private:
+    vector<Expr<Scalar>::Ptr>   itsCoeff;
+};
+
+// @}
+
+} //# namespace BBS
+} //# namespace LOFAR
+
+#endif
diff --git a/CEP/Calibration/BBSKernel/src/ElementBeamExpr.cc b/CEP/Calibration/BBSKernel/src/ElementBeamExpr.cc
new file mode 100644
index 0000000000000000000000000000000000000000..aaacbaabb4359ab7ba1e956a07ef5a30f3fab5dd
--- /dev/null
+++ b/CEP/Calibration/BBSKernel/src/ElementBeamExpr.cc
@@ -0,0 +1,114 @@
+//# ElementBeamExpr.cc: Wrapper class that constructs the correct beam expr based on the BeamConfig instance provided in the constructor. It also caches any shared auxilliary data.
+//#
+//# Copyright (C) 2009
+//# 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/ElementBeamExpr.h>
+#include <BBSKernel/Exceptions.h>
+#include <BBSKernel/ModelConfig.h>
+#include <BBSKernel/Expr/YatawattaDipole.h>
+
+namespace LOFAR
+{
+namespace BBS
+{
+
+ElementBeamExpr::~ElementBeamExpr()
+{
+}
+
+ElementBeamExpr::Ptr ElementBeamExpr::create(const BeamConfig &config,
+    Scope &scope)
+{
+    LOG_INFO_STR("Using element beam type: "
+        << config.getElementTypeAsString());
+    ASSERT(config.getElementType() != BeamConfig::UNKNOWN);
+
+    switch(config.getElementType())
+    {
+        case BeamConfig::HAMAKER_LBA:
+        case BeamConfig::HAMAKER_HBA:
+        {
+            return ElementBeamExpr::Ptr(new HamakerBeamExpr(config, scope));
+        }
+
+        case BeamConfig::YATAWATTA_LBA:
+        case BeamConfig::YATAWATTA_HBA:
+        {
+            return ElementBeamExpr::Ptr(new YatawattaBeamExpr(config, scope));
+        }
+
+        default:
+            THROW(BBSKernelException, "Unsupported element type encountered.");
+    }
+}
+
+HamakerBeamExpr::HamakerBeamExpr(const BeamConfig &config, Scope&)
+{
+    ASSERT(config.getElementType() == BeamConfig::HAMAKER_LBA
+        || config.getElementType() == BeamConfig::HAMAKER_HBA);
+
+    casa::Path path = config.getElementPath();
+    path.append("element_beam_" + config.getElementTypeAsString() + ".coeff");
+    LOG_INFO_STR("Element beam config file: " << path.expandedName());
+
+    // Read beam coefficients from file.
+    itsCoeff.init(path);
+}
+
+Expr<JonesMatrix>::Ptr
+HamakerBeamExpr::construct(const Expr<Vector<2> >::ConstPtr &direction,
+    const Expr<Scalar>::ConstPtr &orientation) const
+{
+    return Expr<JonesMatrix>::Ptr(new HamakerDipole(itsCoeff, direction,
+        orientation));
+}
+
+YatawattaBeamExpr::YatawattaBeamExpr(const BeamConfig &config, Scope&)
+{
+    ASSERT(config.getElementType() == BeamConfig::YATAWATTA_LBA
+        || config.getElementType() == BeamConfig::YATAWATTA_HBA);
+
+    // TODO: Transparantly handle platforms that use a different extension for
+    // loadable modules.
+    itsModulePath[0] = config.getElementPath();
+    itsModulePath[0].append("element_beam_" + config.getElementTypeAsString()
+        + "_theta.so");
+
+    itsModulePath[1] = config.getElementPath();
+    itsModulePath[1].append("element_beam_" + config.getElementTypeAsString()
+        + "_phi.so");
+
+    LOG_INFO_STR("Element beam loadable modules: ["
+        << itsModulePath[0].expandedName() << ","
+        << itsModulePath[1].expandedName() << "]");
+}
+
+Expr<JonesMatrix>::Ptr
+YatawattaBeamExpr::construct(const Expr<Vector<2> >::ConstPtr &direction,
+    const Expr<Scalar>::ConstPtr &orientation) const
+{
+    return Expr<JonesMatrix>::Ptr(new YatawattaDipole(itsModulePath[0],
+        itsModulePath[1], direction, orientation));
+}
+
+} //# namespace BBS
+} //# namespace LOFAR
diff --git a/CEP/Calibration/BBSKernel/src/Expr/EquatorialCentroid.cc b/CEP/Calibration/BBSKernel/src/Expr/EquatorialCentroid.cc
new file mode 100644
index 0000000000000000000000000000000000000000..afbf96b0db29d08fbab2f9b7174afbc526f31df6
--- /dev/null
+++ b/CEP/Calibration/BBSKernel/src/Expr/EquatorialCentroid.cc
@@ -0,0 +1,159 @@
+//# EquatorialCentroid.cc: Compute the centroid of a list of positions in
+//# spherical coordinates.
+//#
+//# Copyright (C) 2009
+//# 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/EquatorialCentroid.h>
+
+namespace LOFAR
+{
+namespace BBS
+{
+
+EquatorialCentroid::EquatorialCentroid()
+{
+}
+
+EquatorialCentroid::~EquatorialCentroid()
+{
+    for(unsigned int i = 0; i < itsArgs.size(); ++i)
+    {
+        disconnect(itsArgs[i]);
+    }
+}
+
+void EquatorialCentroid::connect(const Expr<Vector<2> >::ConstPtr &arg)
+{
+    ExprBase::connect(arg);
+    itsArgs.push_back(arg);
+}
+
+unsigned int EquatorialCentroid::nArguments() const
+{
+    return itsArgs.size();
+}
+
+ExprBase::ConstPtr EquatorialCentroid::argument(unsigned int i) const
+{
+    ASSERT(i < itsArgs.size());
+    return itsArgs[i];
+}
+
+const Vector<2> EquatorialCentroid::evaluateExpr(const Request &request,
+    Cache &cache, unsigned int grid) const
+{
+    // Allocate result.
+    Vector<2> result;
+
+    // Evaluate arguments.
+    const unsigned int nArg = nArguments();
+    vector<FlagArray> flags;
+    flags.reserve(nArg);
+
+    vector<Vector<2> > args;
+    args.reserve(nArg);
+    for(unsigned int i = 0; i < nArg; ++i)
+    {
+        args.push_back(itsArgs[i]->evaluate(request, cache, grid));
+        flags.push_back(args[i].flags());
+    }
+
+    // Evaluate flags.
+    result.setFlags(mergeFlags(flags.begin(), flags.end()));
+
+    // Compute main value.
+    vector<Vector<2>::View> argValues;
+    argValues.reserve(nArg);
+    for(unsigned int i = 0; i < nArg; ++i)
+    {
+        argValues.push_back(args[i].view());
+    }
+    result.assign(evaluateImpl(request[grid], argValues));
+
+    // Compute perturbed values.
+    vector<Vector<2>::Iterator> argIt;
+    argIt.reserve(nArg);
+
+    bool atEnd = true;
+    for(unsigned int i = 0; i < nArg; ++i)
+    {
+        argIt.push_back(Vector<2>::Iterator(args[i]));
+        atEnd = atEnd && argIt.back().atEnd();
+    }
+
+    PValueKey key;
+    while(!atEnd)
+    {
+        key = argIt.front().key();
+        for(unsigned int i = 1; i < nArg; ++i)
+        {
+            key = std::min(key, argIt[i].key());
+        }
+
+        for(unsigned int i = 0; i < nArg; ++i)
+        {
+            argValues[i] = argIt[i].value(key);
+        }
+
+        result.assign(key, evaluateImpl(request[grid], argValues));
+
+        argIt.front().advance(key);
+        atEnd = argIt.front().atEnd();
+        for(unsigned int i = 1; i < nArg; ++i)
+        {
+            argIt[i].advance(key);
+            atEnd = atEnd && argIt[i].atEnd();
+        }
+    }
+
+    return result;
+}
+
+const Vector<2>::View EquatorialCentroid::evaluateImpl(const Grid &grid,
+    const vector<Vector<2>::View> &args) const
+{
+    Matrix cosDec = cos(args[0](1));
+    Matrix x = cos(args[0](0)) * cosDec;
+    Matrix y = sin(args[0](0)) * cosDec;
+    Matrix z = sin(args[0](1));
+
+    for(unsigned int i = 1; i < args.size(); ++i)
+    {
+        cosDec = cos(args[i](1));
+        x = x + cos(args[i](0)) * cosDec;
+        y = y + sin(args[i](0)) * cosDec;
+        z = z + sin(args[i](1));
+    }
+
+    x /= args.size();
+    y /= args.size();
+    z /= args.size();
+
+    Vector<2>::View result;
+    result.assign(0, atan2(y, x));
+    result.assign(1, asin(z));
+
+    return result;
+}
+
+} //# namespace BBS
+} //# namespace LOFAR
diff --git a/CEP/Calibration/BBSKernel/src/Expr/Scope.cc b/CEP/Calibration/BBSKernel/src/Expr/Scope.cc
new file mode 100644
index 0000000000000000000000000000000000000000..38e02d1cad5baf42630e21099b5766991481972d
--- /dev/null
+++ b/CEP/Calibration/BBSKernel/src/Expr/Scope.cc
@@ -0,0 +1,80 @@
+//# Scope.cc: A list of ExprParm instances that are used by a model expression.
+//#
+//# Copyright (C) 2009
+//# 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/Scope.h>
+
+#include <BBSKernel/ParmManager.h>
+
+namespace LOFAR
+{
+namespace BBS
+{
+
+void Scope::clear()
+{
+    itsParms.clear();
+}
+
+ExprParm::Ptr Scope::operator()(unsigned int category, const string &name)
+{
+    ParmProxy::ConstPtr proxy(ParmManager::instance().get(category, name));
+
+    pair<Scope::const_iterator, bool> status =
+        itsParms.insert(make_pair(proxy->getId(),
+            ExprParm::Ptr(new ExprParm(proxy))));
+
+    return status.first->second;
+}
+
+Scope::iterator Scope::begin()
+{
+    return itsParms.begin();
+}
+
+Scope::iterator Scope::end()
+{
+    return itsParms.end();
+}
+
+Scope::const_iterator Scope::begin() const
+{
+    return itsParms.begin();
+}
+
+Scope::const_iterator Scope::end() const
+{
+    return itsParms.end();
+}
+
+Scope::iterator Scope::find(unsigned int id)
+{
+    return itsParms.find(id);
+}
+
+Scope::const_iterator Scope::find(unsigned int id) const
+{
+    return itsParms.find(id);
+}
+
+} //# namespace BBS
+} //# namespace LOFAR
diff --git a/CEP/Calibration/BBSKernel/src/IonosphereExpr.cc b/CEP/Calibration/BBSKernel/src/IonosphereExpr.cc
new file mode 100644
index 0000000000000000000000000000000000000000..7bc854e7e4bb241ba41eb457c23eb3d21f8712d3
--- /dev/null
+++ b/CEP/Calibration/BBSKernel/src/IonosphereExpr.cc
@@ -0,0 +1,95 @@
+//# IonosphereExpr.cc: Wrapper class that constructs ionosphere expressions
+//# based on the IonosphereConfig instance provided to the constructor. The
+//# class also stores a reference to any shared auxilliary data.
+//#
+//# Copyright (C) 2009
+//# 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/IonosphereExpr.h>
+#include <BBSKernel/ModelConfig.h>
+#include <BBSKernel/Expr/ExprAdaptors.h>
+#include <BBSKernel/Expr/Scope.h>
+#include <BBSKernel/Expr/PolynomialLayer.h>
+
+#include <measures/Measures/MPosition.h>
+
+namespace LOFAR
+{
+namespace BBS
+{
+
+IonosphereExpr::~IonosphereExpr()
+{
+}
+
+IonosphereExpr::Ptr IonosphereExpr::create(const IonosphereConfig &config,
+    Scope &scope)
+{
+    return IonosphereExpr::Ptr(new PolynomialLayerExpr(config, scope));
+}
+
+PolynomialLayerExpr::PolynomialLayerExpr(const IonosphereConfig &config,
+    Scope &scope)
+{
+    // Get ionosphere model parameters.
+    unsigned int nCoeff = config.getDegree() + 1;
+
+    // Make sure degree is at least 1 (a gradient over the field of view).
+    if(nCoeff <= 1)
+    {
+        LOG_WARN("Ionosphere model degree should be at least 1 (gradient); will"
+            " change from specified degree to gradient.");
+
+        nCoeff = 2;
+    }
+
+    itsCoeff.reserve(nCoeff * nCoeff - 1);
+    for(unsigned int i = 0; i < nCoeff; ++i)
+    {
+        for(unsigned int j = 0; j < nCoeff; ++j)
+        {
+            // For the moment we do not include MIM:0:0 (absolute TEC).
+            if(i == 0 && j == 0)
+            {
+                continue;
+            }
+
+            ostringstream oss;
+            oss << "MIM:" << i << ":" << j;
+            itsCoeff.push_back(scope(INSTRUMENT, oss.str()));
+        }
+    }
+
+    LOG_DEBUG_STR("Number of coefficients in ionospheric phase screen model: "
+        << itsCoeff.size());
+}
+
+Expr<JonesMatrix>::Ptr
+PolynomialLayerExpr::construct(const casa::MPosition &position,
+    const Expr<Vector<4> >::ConstPtr &piercePoint) const
+{
+    PolynomialLayer::Ptr angle(new PolynomialLayer(position,
+        piercePoint, itsCoeff.begin(), itsCoeff.end()));
+    return Expr<JonesMatrix>::Ptr(new AsDiagonalMatrix(angle, angle));
+}
+
+} //# namespace BBS
+} //# namespace LOFAR