diff --git a/test/porousmediumflow/richards/implicit/richardsniconductionproblem.hh b/test/porousmediumflow/richards/implicit/richardsniconductionproblem.hh
index fadc4d0e5c76a553d12a4f710c2076b7db4bffb3..b3c8ff08d2c2fe61cc768fea384727d5711a73e6 100644
--- a/test/porousmediumflow/richards/implicit/richardsniconductionproblem.hh
+++ b/test/porousmediumflow/richards/implicit/richardsniconductionproblem.hh
@@ -27,9 +27,11 @@
 
 #include <math.h>
 
-#include <dumux/porousmediumflow/implicit/problem.hh>
+#include <dumux/discretization/cellcentered/tpfa/properties.hh>
+#include <dumux/discretization/box/properties.hh>
+
+#include <dumux/porousmediumflow/problem.hh>
 #include <dumux/porousmediumflow/richards/implicit/model.hh>
-#include <dumux/porousmediumflow/richards/implicit/problem.hh>
 #include <dumux/material/fluidmatrixinteractions/2p/thermalconductivitysomerton.hh>
 #include <dumux/material/fluidsystems/h2on2.hh>
 #include "richardsnispatialparams.hh"
@@ -44,7 +46,7 @@ namespace Properties
 {
 NEW_TYPE_TAG(RichardsNIConductionProblem, INHERITS_FROM(RichardsNI, RichardsNISpatialParams));
 NEW_TYPE_TAG(RichardsNIConductionBoxProblem, INHERITS_FROM(BoxModel, RichardsNIConductionProblem));
-NEW_TYPE_TAG(RichardsNIConductionCCProblem, INHERITS_FROM(CCModel, RichardsNIConductionProblem));
+NEW_TYPE_TAG(RichardsNIConductionCCProblem, INHERITS_FROM(CCTpfaModel, RichardsNIConductionProblem));
 
 // Set the grid type
 SET_TYPE_PROP(RichardsNIConductionProblem, Grid, Dune::YaspGrid<2>);
@@ -85,19 +87,23 @@ SET_TYPE_PROP(RichardsNIConductionProblem,
  * <tt>./test_ccrichardsniconduction -ParameterFile ./test_ccrichardsniconduction.input</tt>
  */
 template <class TypeTag>
-class RichardsNIConductionProblem : public RichardsProblem<TypeTag>
+class RichardsNIConductionProblem :public PorousMediumFlowProblem<TypeTag>
 {
-    typedef RichardsProblem<TypeTag> ParentType;
-
-    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
-    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
-    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
-    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
-    typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes;
-    typedef typename GET_PROP_TYPE(TypeTag, TimeManager) TimeManager;
-    typedef typename GET_PROP_TYPE(TypeTag, ThermalConductivityModel) ThermalConductivityModel;
-    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
+    using ParentType = PorousMediumFlowProblem<TypeTag>;
+
+    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
+    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
+    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
+    using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables);
+    using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem);
+    using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes);
+    using ThermalConductivityModel = typename GET_PROP_TYPE(TypeTag, ThermalConductivityModel);
+    using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementSolutionVector = typename GET_PROP_TYPE(TypeTag, ElementSolutionVector);
+    using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
+    using SubControlVolumeFace = typename GET_PROP_TYPE(TypeTag, SubControlVolumeFace);
+    using IapwsH2O = H2O<Scalar>;
 
     // copy some indices for convenience
     typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
@@ -106,19 +112,14 @@ class RichardsNIConductionProblem : public RichardsProblem<TypeTag>
         dimWorld = GridView::dimensionworld
     };
 
-    enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) };
-    enum { dofCodim = isBox ? dimWorld : 0 };
 
     enum {
         // indices of the primary variables
-        pressureIdx = Indices::pwIdx,
+        pressureIdx = Indices::pressureIdx,
+        conti0EqIdx = Indices::conti0EqIdx,
+        wPhaseOnly = Indices::wPhaseOnly,
         wPhaseIdx = Indices::wPhaseIdx,
-        nPhaseIdx = Indices::nPhaseIdx,
-        temperatureIdx = Indices::temperatureIdx
-    };
-    enum {
-        // index of the transport equation
-        contiEqIdx = Indices::contiEqIdx,
+        temperatureIdx = Indices::temperatureIdx,
         energyEqIdx = Indices::energyEqIdx
     };
 
@@ -128,25 +129,15 @@ class RichardsNIConductionProblem : public RichardsProblem<TypeTag>
     typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition;
 
 public:
-    RichardsNIConductionProblem(TimeManager &timeManager, const GridView &gridView)
-        : ParentType(timeManager, gridView)
+    RichardsNIConductionProblem(std::shared_ptr<const FVGridGeometry> fvGridGeometry)
+    : ParentType(fvGridGeometry)
     {
         //initialize fluid system
         FluidSystem::init();
 
-        name_ = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, std::string, Problem, Name);
-        outputInterval_ = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, int, Problem, OutputInterval);
+        name_ = getParam<std::string>("Problem.Name");
         temperatureHigh_ = 300.;
-    }
-
-
-    bool shouldWriteOutput() const
-    {
-        return
-            this->timeManager().timeStepIndex() == 0 ||
-            this->timeManager().timeStepIndex() % outputInterval_ == 0 ||
-            this->timeManager().episodeWillBeFinished() ||
-            this->timeManager().willBeFinished();
+        temperatureExact_.resize(fvGridGeometry->numDofs());
     }
 
     /*!
@@ -154,57 +145,53 @@ public:
      *        from the solution of the current time step to the VTK
      *        writer.
      */
-    void addOutputVtkFields()
+    //! get the analytical temperature
+    const std::vector<Scalar>& getExactTemperature()
     {
-        //Here we calculate the analytical solution
-        typedef Dune::BlockVector<Dune::FieldVector<double, 1> > ScalarField;
-        unsigned numDofs = this->model().numDofs();
+        return temperatureExact_;
+    }
 
-        //create required scalar fields
-        ScalarField *temperatureExact = this->resultWriter().allocateManagedBuffer(numDofs);
+  //! udpate the analytical temperature
+    void updateExactTemperature(const SolutionVector& curSol, Scalar time)
+    {
+        const auto someElement = *(elements(this->fvGridGeometry().gridView()).begin());
 
-        FVElementGeometry fvGeometry;
-        VolumeVariables volVars;
+        ElementSolutionVector someElemSol(someElement, curSol, this->fvGridGeometry());
+        const auto someInitSol = initialAtPos(someElement.geometry().center());
 
-        const auto firstElement = *this->gridView().template begin<0>();
-        fvGeometry.update(this->gridView(), firstElement);
-        PrimaryVariables initialPriVars(0);
-        GlobalPosition globalPos(0);
-        initial_(initialPriVars, globalPos);
-
-        //update the constant volume variables
-        volVars.update(initialPriVars, *this, firstElement, fvGeometry, 0, false);
-
-        Scalar porosity = this->spatialParams().porosity(firstElement, fvGeometry, 0);
-        Scalar densityW = volVars.density(wPhaseIdx);
-        Scalar heatCapacityW = FluidSystem::heatCapacity(volVars.fluidState(), 0);
-        Scalar densityS = this->spatialParams().solidDensity(firstElement, fvGeometry, 0);
-        Scalar heatCapacityS = this->spatialParams().solidHeatCapacity(firstElement, fvGeometry, 0);
-        Scalar storage = densityW*heatCapacityW*porosity + densityS*heatCapacityS*(1 - porosity);
-        Scalar effectiveThermalConductivity = ThermalConductivityModel::effectiveThermalConductivity(volVars, this->spatialParams(),
-                firstElement, fvGeometry, 0);
-        using std::max;
-        Scalar time = max(this->timeManager().time() + this->timeManager().timeStepSize(), 1e-10);
+        auto fvGeometry = localView(this->fvGridGeometry());
+        fvGeometry.bindElement(someElement);
+        const auto someScv = *(scvs(fvGeometry).begin());
 
-        for (const auto& element : elements(this->gridView()))
+        VolumeVariables volVars;
+        volVars.update(someElemSol, *this, someElement, someScv);
+
+        const auto porosity = this->spatialParams().porosity(someElement, someScv, someElemSol);
+        const auto densityW = volVars.density(wPhaseIdx);
+        const auto heatCapacityW = IapwsH2O::liquidHeatCapacity(someInitSol[temperatureIdx], someInitSol[pressureIdx]);
+        const auto densityS = this->spatialParams().solidDensity(someElement, someScv, someElemSol);
+        const auto heatCapacityS = this->spatialParams().solidHeatCapacity(someElement, someScv, someElemSol);
+        const auto storage = densityW*heatCapacityW*porosity + densityS*heatCapacityS*(1 - porosity);
+        const auto effectiveThermalConductivity = ThermalConductivityModel::effectiveThermalConductivity(volVars, this->spatialParams(),
+                                                                                                         someElement, fvGeometry, someScv);
+        using std::max;
+        time = max(time, 1e-10);
+        for (const auto& element : elements(this->fvGridGeometry().gridView()))
         {
-            fvGeometry.update(this->gridView(), element);
-            for (int scvIdx = 0; scvIdx < fvGeometry.numScv; ++scvIdx)
-            {
-                int globalIdx = this->model().dofMapper().subIndex(element, scvIdx, dofCodim);
+            auto fvGeometry = localView(this->fvGridGeometry());
+            fvGeometry.bindElement(element);
 
-                if (isBox)
-                    globalPos = element.geometry().corner(scvIdx);
-                else
-                    globalPos = element.geometry().center();
+            for (auto&& scv : scvs(fvGeometry))
+            {
+               auto globalIdx = scv.dofIndex();
+               const auto& globalPos = scv.dofPosition();
+               using std::erf;
+               using std::sqrt;
+               temperatureExact_[globalIdx] = temperatureHigh_ + (someInitSol[temperatureIdx] - temperatureHigh_)
+                                              *erf(0.5*sqrt(globalPos[0]*globalPos[0]*storage/time/effectiveThermalConductivity));
 
-                using std::sqrt;
-                using std::erf;
-                (*temperatureExact)[globalIdx] = temperatureHigh_ + (initialPriVars[temperatureIdx] - temperatureHigh_)
-                                                             *erf(0.5*sqrt(globalPos[0]*globalPos[0]*storage/time/effectiveThermalConductivity));
             }
         }
-        this->resultWriter().attachDofData(*temperatureExact, "temperatureExact", isBox);
     }
     /*!
      * \name Problem parameters
@@ -231,13 +218,12 @@ public:
      * \brief Specifies which kind of boundary condition should be
      *        used for which equation on a given boundary segment.
      *
-     * \param values The boundary types for the conservation equations
-     * \param globalPos The position for which the bc type should be evaluated
+     * \param globalPos The position for which the boundary type is set
      */
-    void boundaryTypesAtPos(BoundaryTypes &values,
-                            const GlobalPosition &globalPos) const
+    BoundaryTypes boundaryTypesAtPos(const GlobalPosition &globalPos) const
     {
-        if(globalPos[0] < eps_ || globalPos[0] > this->bBoxMax()[0] - eps_)
+        BoundaryTypes values;
+        if(globalPos[0] < eps_ || globalPos[0] > this->fvGridGeometry().bBoxMax()[0] - eps_)
         {
             values.setAllDirichlet();
         }
@@ -245,6 +231,7 @@ public:
         {
             values.setAllNeumann();
         }
+        return values;
     }
 
     /*!
@@ -256,14 +243,16 @@ public:
      *
      * For this method, the \a values parameter stores primary variables.
      */
-    void dirichletAtPos(PrimaryVariables &values, const GlobalPosition &globalPos) const
+    PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const
     {
-        initial_(values, globalPos);
+        PrimaryVariables values(0.0);
+        values = initial_(globalPos);
 
         if (globalPos[0] < eps_)
         {
             values[temperatureIdx] = temperatureHigh_;
         }
+        return values;
     }
 
     /*!
@@ -274,14 +263,10 @@ public:
      * in normal direction of each component. Negative values mean
      * influx.
      */
-    void neumann(PrimaryVariables &priVars,
-                 const Element &element,
-                 const FVElementGeometry &fvGeometry,
-                 const Intersection &intersection,
-                 const int scvIdx,
-                 const int boundaryFaceIdx) const
+    PrimaryVariables neumannAtPos(const GlobalPosition &globalPos) const
     {
-        priVars = 0;
+        PrimaryVariables values(0.0);
+        return values;
     }
 
     // \}
@@ -291,21 +276,6 @@ public:
      */
     // \{
 
-    /*!
-     * \brief Evaluate the source term for all phases within a given
-     *        sub-control-volume.
-     *
-     * For this method, the \a priVars parameter stores the rate mass
-     * of a component is generated or annihilate per volume
-     * unit. Positive values mean that mass is created, negative ones
-     * mean that it vanishes.
-     */
-    void sourceAtPos(PrimaryVariables &priVars,
-                     const GlobalPosition &globalPos) const
-    {
-        priVars = Scalar(0.0);
-    }
-
     /*!
      * \brief Returns the reference pressure [Pa] of the non-wetting
      *        fluid phase within a finite volume
@@ -318,9 +288,7 @@ public:
      * \param scvIdx The sub control volume index inside the finite
      *               volume geometry
      */
-    Scalar referencePressure(const Element &element,
-                             const FVElementGeometry &fvGeometry,
-                             const int scvIdx) const
+     Scalar nonWettingReferencePressure() const
     { return 1e5; };
 
     /*!
@@ -332,26 +300,29 @@ public:
      * For this method, the \a values parameter stores primary
      * variables.
      */
-    void initialAtPos(PrimaryVariables &values, const GlobalPosition &globalPos) const
+   PrimaryVariables initialAtPos(const GlobalPosition &globalPos) const
     {
-        initial_(values, globalPos);
+         return initial_(globalPos);
     }
 
     // \}
 
 private:
-    // the internal method for the initial condition
-    void initial_(PrimaryVariables &priVars,
-                  const GlobalPosition &globalPos) const
+    PrimaryVariables initial_(const GlobalPosition &globalPos) const
     {
+        PrimaryVariables priVars(0.0);
+        priVars.setState(wPhaseOnly);
         priVars[pressureIdx] = 1e5; // initial condition for the pressure
+
         priVars[temperatureIdx] = 290.;
+        return priVars;
     }
 
     Scalar temperatureHigh_;
     static constexpr Scalar eps_ = 1e-6;
     std::string name_;
     int outputInterval_;
+    std::vector<Scalar> temperatureExact_;
 };
 
 } //end namespace
diff --git a/test/porousmediumflow/richards/implicit/richardsniconvectionproblem.hh b/test/porousmediumflow/richards/implicit/richardsniconvectionproblem.hh
index 951edf57cac861ff0487131398b5f0670c145501..1472b7a585583d7c6b77c8a2dca260af91fa9e91 100644
--- a/test/porousmediumflow/richards/implicit/richardsniconvectionproblem.hh
+++ b/test/porousmediumflow/richards/implicit/richardsniconvectionproblem.hh
@@ -23,14 +23,16 @@
  * The simulation domain is a tube where water with an elevated temperature is injected
  * at a constant rate on the left hand side.
  */
-#ifndef DUMUX_1PNI_CONVECTION_PROBLEM_HH
-#define DUMUX_1PNI_CONVECTION_PROBLEM_HH
+#ifndef DUMUX_RICHARDS_CONVECTION_PROBLEM_HH
+#define DUMUX_RICHARDS_CONVECTION_PROBLEM_HH
 
 #include <math.h>
 
-#include <dumux/porousmediumflow/implicit/problem.hh>
+#include <dumux/discretization/cellcentered/tpfa/properties.hh>
+#include <dumux/discretization/box/properties.hh>
+
+#include <dumux/porousmediumflow/problem.hh>
 #include <dumux/porousmediumflow/richards/implicit/model.hh>
-#include <dumux/porousmediumflow/richards/implicit/problem.hh>
 #include <dumux/material/fluidmatrixinteractions/2p/thermalconductivitysomerton.hh>
 #include <dumux/material/fluidsystems/h2on2.hh>
 #include "richardsnispatialparams.hh"
@@ -45,7 +47,7 @@ namespace Properties
 {
 NEW_TYPE_TAG(RichardsNIConvectionProblem, INHERITS_FROM(RichardsNI, RichardsNISpatialParams));
 NEW_TYPE_TAG(RichardsNIConvectionBoxProblem, INHERITS_FROM(BoxModel, RichardsNIConvectionProblem));
-NEW_TYPE_TAG(RichardsNIConvectionCCProblem, INHERITS_FROM(CCModel, RichardsNIConvectionProblem));
+NEW_TYPE_TAG(RichardsNIConvectionCCProblem, INHERITS_FROM(CCTpfaModel, RichardsNIConvectionProblem));
 
 // Set the grid type
 SET_TYPE_PROP(RichardsNIConvectionProblem, Grid, Dune::YaspGrid<2>);
@@ -89,20 +91,24 @@ SET_TYPE_PROP(RichardsNIConvectionProblem,
  * <tt>./test_ccrichardsniconvection -ParameterFile ./test_ccrichardsniconvection.input</tt>
  */
 template <class TypeTag>
-class RichardsNIConvectionProblem : public RichardsProblem<TypeTag>
+class RichardsNIConvectionProblem : public PorousMediumFlowProblem<TypeTag>
 {
-    typedef RichardsProblem<TypeTag> ParentType;
-    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
-    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
-    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
-    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
-    typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes;
-    typedef typename GET_PROP_TYPE(TypeTag, TimeManager) TimeManager;
-    typedef typename GET_PROP_TYPE(TypeTag, ThermalConductivityModel) ThermalConductivityModel;
-    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
-    typedef H2O<Scalar> IapwsH2O;
+    using ParentType = PorousMediumFlowProblem<TypeTag>;
+
+    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
+    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
+    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry);
+    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
+    using PrimaryVariables = typename GET_PROP_TYPE(TypeTag, PrimaryVariables);
+    using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem);
+    using BoundaryTypes = typename GET_PROP_TYPE(TypeTag, BoundaryTypes);
+    using ThermalConductivityModel = typename GET_PROP_TYPE(TypeTag, ThermalConductivityModel);
+    using VolumeVariables = typename GET_PROP_TYPE(TypeTag, VolumeVariables);
+    using ElementVolumeVariables = typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables);
+    using ElementSolutionVector = typename GET_PROP_TYPE(TypeTag, ElementSolutionVector);
+    using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
+    using SubControlVolumeFace = typename GET_PROP_TYPE(TypeTag, SubControlVolumeFace);
+    using IapwsH2O = H2O<Scalar>;
 
     // copy some indices for convenience
     typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
@@ -111,19 +117,14 @@ class RichardsNIConvectionProblem : public RichardsProblem<TypeTag>
         dimWorld = GridView::dimensionworld
     };
 
-    enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) };
-    enum { dofCodim = isBox ? dimWorld : 0 };
 
     enum {
         // indices of the primary variables
-        pressureIdx = Indices::pwIdx,
+        pressureIdx = Indices::pressureIdx,
+        conti0EqIdx = Indices::conti0EqIdx,
+        wPhaseOnly = Indices::wPhaseOnly,
         wPhaseIdx = Indices::wPhaseIdx,
-        nPhaseIdx = Indices::nPhaseIdx,
-        temperatureIdx = Indices::temperatureIdx
-    };
-    enum {
-        // index of the transport equation
-        contiEqIdx = Indices::contiEqIdx,
+        temperatureIdx = Indices::temperatureIdx,
         energyEqIdx = Indices::energyEqIdx
     };
 
@@ -133,86 +134,74 @@ class RichardsNIConvectionProblem : public RichardsProblem<TypeTag>
     typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition;
 
 public:
-    RichardsNIConvectionProblem(TimeManager &timeManager, const GridView &gridView)
-        : ParentType(timeManager, gridView)
+    RichardsNIConvectionProblem(std::shared_ptr<const FVGridGeometry> fvGridGeometry)
+    : ParentType(fvGridGeometry)
     {
         //initialize fluid system
         FluidSystem::init();
 
-        name_ = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, std::string, Problem, Name);
-        outputInterval_ = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, int, Problem, OutputInterval);
-        darcyVelocity_ = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, Problem, DarcyVelocity);
+        name_ =  getParam<std::string>("Problem.Name");
+        darcyVelocity_ =  getParam<Scalar>("Problem.DarcyVelocity");
         temperatureHigh_ = 291.;
         temperatureLow_ = 290.;
         pressureHigh_ = 2e5;
         pressureLow_ = 1e5;
+        temperatureExact_.resize(fvGridGeometry->numDofs());
     }
 
 
-    bool shouldWriteOutput() const
-    {
-        return
-            this->timeManager().timeStepIndex() == 0 ||
-            this->timeManager().timeStepIndex() % outputInterval_ == 0 ||
-            this->timeManager().episodeWillBeFinished() ||
-            this->timeManager().willBeFinished();
-    }
-
-    /*!
+   /*!
      * \brief Append all quantities of interest which can be derived
      *        from the solution of the current time step to the VTK
      *        writer.
      */
-    void addOutputVtkFields()
+    //! get the analytical temperature
+    const std::vector<Scalar>& getExactTemperature()
     {
-        //Here we calculate the analytical solution
-        typedef Dune::BlockVector<Dune::FieldVector<double, 1> > ScalarField;
-        unsigned numDofs = this->model().numDofs();
+        return temperatureExact_;
+    }
 
-        //create required scalar fields
-        ScalarField *temperatureExact = this->resultWriter().allocateManagedBuffer(numDofs);
+  //! udpate the analytical temperature
+    void updateExactTemperature(const SolutionVector& curSol, Scalar time)
+    {
+        const auto someElement = *(elements(this->fvGridGeometry().gridView()).begin());
 
-        FVElementGeometry fvGeometry;
-        VolumeVariables volVars;
+        ElementSolutionVector someElemSol(someElement, curSol, this->fvGridGeometry());
+        const auto someInitSol = initialAtPos(someElement.geometry().center());
 
-        const auto firstElement = *this->gridView().template begin<0>();
-        fvGeometry.update(this->gridView(), firstElement);
-        PrimaryVariables initialPriVars(0);
-        GlobalPosition globalPos(0);
-        initial_(initialPriVars, globalPos);
-
-        //update the constant volume variables
-        volVars.update(initialPriVars, *this, firstElement, fvGeometry, 0, false);
-
-        Scalar porosity = this->spatialParams().porosity(firstElement, fvGeometry, 0);
-        Scalar densityW = volVars.density(wPhaseIdx);
-        Scalar heatCapacityW = FluidSystem::heatCapacity(volVars.fluidState(), 0);
-        Scalar storageW =  densityW*heatCapacityW*porosity;
-        Scalar densityS = this->spatialParams().solidDensity(firstElement, fvGeometry, 0);
-        Scalar heatCapacityS = this->spatialParams().solidHeatCapacity(firstElement, fvGeometry, 0);
-        Scalar storageTotal = storageW + densityS*heatCapacityS*(1 - porosity);
-        std::cout<<"storage: "<<storageTotal<<std::endl;
-        using std::max;
-        Scalar time = max(this->timeManager().time() + this->timeManager().timeStepSize(), 1e-10);
-        Scalar retardedFrontVelocity = darcyVelocity_*storageW/storageTotal/porosity;
-        std::cout<<"retarded velocity: "<<retardedFrontVelocity<<std::endl;
+        auto fvGeometry = localView(this->fvGridGeometry());
+        fvGeometry.bindElement(someElement);
+        const auto someScv = *(scvs(fvGeometry).begin());
 
-        for (const auto& element : elements(this->gridView()))
+        VolumeVariables volVars;
+        volVars.update(someElemSol, *this, someElement, someScv);
+
+        const auto porosity = this->spatialParams().porosity(someElement, someScv, someElemSol);
+        const auto densityW = volVars.density(wPhaseIdx);
+        const auto heatCapacityW = IapwsH2O::liquidHeatCapacity(someInitSol[temperatureIdx], someInitSol[pressureIdx]);
+        const auto densityS = this->spatialParams().solidDensity(someElement, someScv, someElemSol);
+        const auto heatCapacityS = this->spatialParams().solidHeatCapacity(someElement, someScv, someElemSol);
+        const auto storage = densityW*heatCapacityW*porosity + densityS*heatCapacityS*(1 - porosity);
+        const auto effectiveThermalConductivity = ThermalConductivityModel::effectiveThermalConductivity(volVars, this->spatialParams(),
+                                                                                                         someElement, fvGeometry, someScv);
+        using std::max;
+        time = max(time, 1e-10);
+        for (const auto& element : elements(this->fvGridGeometry().gridView()))
         {
-            fvGeometry.update(this->gridView(), element);
-            for (int scvIdx = 0; scvIdx < fvGeometry.numScv; ++scvIdx)
-            {
-                int globalIdx = this->model().dofMapper().subIndex(element, scvIdx, dofCodim);
+            auto fvGeometry = localView(this->fvGridGeometry());
+            fvGeometry.bindElement(element);
 
-                if (isBox)
-                    globalPos = element.geometry().corner(scvIdx);
-                else
-                    globalPos = element.geometry().center();
+            for (auto&& scv : scvs(fvGeometry))
+            {
+               auto globalIdx = scv.dofIndex();
+               const auto& globalPos = scv.dofPosition();
+               using std::erf;
+               using std::sqrt;
+               temperatureExact_[globalIdx] = temperatureHigh_ + (someInitSol[temperatureIdx] - temperatureHigh_)
+                                              *erf(0.5*sqrt(globalPos[0]*globalPos[0]*storage/time/effectiveThermalConductivity));
 
-                (*temperatureExact)[globalIdx] = globalPos[0] < retardedFrontVelocity*time ? temperatureHigh_ : temperatureLow_;
             }
         }
-        this->resultWriter().attachDofData(*temperatureExact, "temperatureExact", isBox);
     }
     /*!
      * \name Problem parameters
@@ -240,13 +229,12 @@ public:
      * \brief Specifies which kind of boundary condition should be
      *        used for which equation on a given boundary segment.
      *
-     * \param values The boundary types for the conservation equations
-     * \param globalPos The position for which the bc type should be evaluated
+     * \param globalPos The position for which the boundary type is set
      */
-    void boundaryTypesAtPos(BoundaryTypes &values,
-                            const GlobalPosition &globalPos) const
+    BoundaryTypes boundaryTypesAtPos(const GlobalPosition &globalPos) const
     {
-        if(globalPos[0] > this->bBoxMax()[0] - eps_)
+        BoundaryTypes values;
+        if(globalPos[0] > this->fvGridGeometry().bBoxMax()[0] - eps_)
         {
             values.setAllDirichlet();
         }
@@ -254,6 +242,7 @@ public:
         {
             values.setAllNeumann();
         }
+        return values;
     }
 
     /*!
@@ -265,50 +254,36 @@ public:
      *
      * For this method, the \a values parameter stores primary variables.
      */
-    void dirichletAtPos(PrimaryVariables &values, const GlobalPosition &globalPos) const
+    PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const
     {
-        initial_(values, globalPos);
+        return initial_(globalPos);
     }
 
     /*!
-     * \brief Evaluates the boundary conditions for a Neumann
-     *        boundary segment in dependency on the current solution.
+     * \brief Evaluate the boundary conditions for a neumann
+     *        boundary segment.
      *
-     * \param values Stores the Neumann values for the conservation equations in
-     *               \f$ [ \textnormal{unit of conserved quantity} / (m^(dim-1) \cdot s )] \f$
      * \param element The finite element
-     * \param fvGeometry The finite volume geometry of the element
-     * \param intersection The intersection between element and boundary
-     * \param scvIdx The local index of the sub-control volume
-     * \param boundaryFaceIdx The index of the boundary face
-     * \param elemVolVars All volume variables for the element
-     *
-     * This method is used for cases, when the Neumann condition depends on the
-     * solution and requires some quantities that are specific to the fully-implicit method.
-     * The \a values store the mass flux of each phase normal to the boundary.
-     * Negative values indicate an inflow.
+     * \param fvGeometry The finite-volume geometry in the box scheme
+     * \param elemVolVars The element volume variables
+     * \param scvf The subcontrolvolume face
+     *  Negative values mean influx.
      */
-     void solDependentNeumann(PrimaryVariables &values,
-                      const Element &element,
-                      const FVElementGeometry &fvGeometry,
-                      const Intersection &intersection,
-                      const int scvIdx,
-                      const int boundaryFaceIdx,
-                      const ElementVolumeVariables &elemVolVars) const
+    PrimaryVariables neumann(const Element &element,
+                             const FVElementGeometry& fvGeometry,
+                             const ElementVolumeVariables& elemVolVars,
+                             const SubControlVolumeFace& scvf) const
     {
-        values = 0;
-        GlobalPosition globalPos(0);
-        if (isBox)
-            globalPos = fvGeometry.boundaryFace[boundaryFaceIdx].ipGlobal;
-        else
-            globalPos = fvGeometry.boundaryFace[boundaryFaceIdx].ipGlobal;
+        PrimaryVariables values(0.0);
+        const auto globalPos = scvf.ipGlobal();
 
         if(globalPos[0] < eps_)
         {
-            values[pressureIdx] = -darcyVelocity_*elemVolVars[scvIdx].density(wPhaseIdx);
-            values[temperatureIdx] = -darcyVelocity_*elemVolVars[scvIdx].density(wPhaseIdx)
-                                     *IapwsH2O::liquidEnthalpy(temperatureHigh_, elemVolVars[scvIdx].pressure(wPhaseIdx));
+            values[pressureIdx] = -darcyVelocity_*elemVolVars[scvf.insideScvIdx()].density(wPhaseIdx);
+            values[temperatureIdx] = -darcyVelocity_*elemVolVars[scvf.insideScvIdx()].density(wPhaseIdx)
+                                     *IapwsH2O::liquidEnthalpy(temperatureHigh_, elemVolVars[scvf.insideScvIdx()].pressure(wPhaseIdx));
         }
+        return values;
     }
 
     // \}
@@ -318,20 +293,6 @@ public:
      */
     // \{
 
-    /*!
-     * \brief Evaluate the source term for all phases within a given
-     *        sub-control-volume.
-     *
-     * For this method, the \a priVars parameter stores the rate mass
-     * of a component is generated or annihilate per volume
-     * unit. Positive values mean that mass is created, negative ones
-     * mean that it vanishes.
-     */
-    void sourceAtPos(PrimaryVariables &priVars,
-                     const GlobalPosition &globalPos) const
-    {
-        priVars = Scalar(0.0);
-    }
 
     /*!
      * \brief Returns the reference pressure [Pa] of the non-wetting
@@ -345,9 +306,7 @@ public:
      * \param scvIdx The sub control volume index inside the finite
      *               volume geometry
      */
-    Scalar referencePressure(const Element &element,
-                             const FVElementGeometry &fvGeometry,
-                             const int scvIdx) const
+    Scalar nonWettingReferencePressure() const
     { return 1e5; };
 
     /*!
@@ -359,20 +318,21 @@ public:
      * For this method, the \a values parameter stores primary
      * variables.
      */
-    void initialAtPos(PrimaryVariables &values, const GlobalPosition &globalPos) const
+   PrimaryVariables initialAtPos(const GlobalPosition &globalPos) const
     {
-        initial_(values, globalPos);
+        return initial_(globalPos);
     }
 
     // \}
 
 private:
-    // the internal method for the initial condition
-    void initial_(PrimaryVariables &priVars,
-                  const GlobalPosition &globalPos) const
+    PrimaryVariables initial_(const GlobalPosition &globalPos) const
     {
+        PrimaryVariables priVars(0.0);
+        priVars.setState(wPhaseOnly);
         priVars[pressureIdx] = pressureLow_; // initial condition for the pressure
         priVars[temperatureIdx] = temperatureLow_;
+        return priVars;
     }
 
     Scalar temperatureHigh_;
@@ -382,7 +342,7 @@ private:
     Scalar darcyVelocity_;
     static constexpr Scalar eps_ = 1e-6;
     std::string name_;
-    int outputInterval_;
+    std::vector<Scalar> temperatureExact_;
 };
 
 } //end namespace
diff --git a/test/porousmediumflow/richards/implicit/richardsnispatialparams.hh b/test/porousmediumflow/richards/implicit/richardsnispatialparams.hh
index ee40841c2f0f84bdbf1a2b2346deca39148813ad..3986b00d0dc43408243089e2461dc6b8c6dea83f 100644
--- a/test/porousmediumflow/richards/implicit/richardsnispatialparams.hh
+++ b/test/porousmediumflow/richards/implicit/richardsnispatialparams.hh
@@ -70,25 +70,33 @@ public:
 template<class TypeTag>
 class RichardsNISpatialParams : public ImplicitSpatialParams<TypeTag>
 {
-    typedef ImplicitSpatialParams<TypeTag> ParentType;
-    typedef typename GET_PROP_TYPE(TypeTag, Grid) Grid;
-    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
-    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
-
-    typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector;
-
-
-    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
-    typedef typename GridView::template Codim<0>::Entity Element;
+    using ParentType = ImplicitSpatialParams<TypeTag>;
+    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
+    using Grid = typename GET_PROP_TYPE(TypeTag, Grid);
+    using GridView = typename GET_PROP_TYPE(TypeTag, GridView);
+    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
+
+    using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
+
+    using FVElementGeometry = typename GET_PROP_TYPE(TypeTag, FVElementGeometry);
+    using SubControlVolume = typename GET_PROP_TYPE(TypeTag, SubControlVolume);
+    using Element = typename GridView::template Codim<0>::Entity;
+    enum {
+        dimWorld=GridView::dimensionworld
+    };
+    using CoordScalar = typename Grid::ctype;
+    using GlobalPosition = Dune::FieldVector<CoordScalar,dimWorld>;
 
     //typedef LinearMaterial<Scalar> EffMaterialLaw;
 public:
+        // export permeability type
+    using PermeabilityType = Scalar;
 
-    typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw;
-    typedef typename MaterialLaw::Params MaterialLawParams;
+    using MaterialLaw = typename GET_PROP_TYPE(TypeTag, MaterialLaw);
+    using  MaterialLawParams = typename MaterialLaw::Params;
 
-    RichardsNISpatialParams(const GridView &gridView)
-        : ParentType(gridView)
+    RichardsNISpatialParams(const Problem& problem)
+        : ParentType(problem)
     {
         permeability_ = 1e-10;
         porosity_ = 0.4;
@@ -113,16 +121,6 @@ public:
     {}
 
 
-    /*!
-     * \brief Update the spatial parameters with the flow solution
-     *        after a timestep.
-     *
-     * \param globalSolution the global solution vector
-     */
-    void update(const SolutionVector &globalSolution)
-    {
-    }
-
     /*!
      * \brief Define the intrinsic permeability \f$\mathrm{[m^2]}\f$.
      *
@@ -130,9 +128,7 @@ public:
      * \param fvGeometry The current finite volume geometry of the element
      * \param scvIdx The index of the sub-control volume
      */
-    const Scalar intrinsicPermeability(const Element &element,
-            const FVElementGeometry &fvGeometry,
-            const int scvIdx) const
+    PermeabilityType permeabilityAtPos(const GlobalPosition& globalPos) const
     {
         return permeability_;
     }
@@ -144,9 +140,7 @@ public:
      * \param fvGeometry The finite volume geometry
      * \param scvIdx The local index of the sub-control volume where
      */
-    double porosity(const Element &element,
-            const FVElementGeometry &fvGeometry,
-            const int scvIdx) const
+    Scalar porosityAtPos(const GlobalPosition& globalPos) const
     {
         return porosity_;
     }
@@ -158,9 +152,7 @@ public:
      * \param fvGeometry The current finite volume geometry of the element
      * \param scvIdx The index of the sub-control volume
      */
-    const MaterialLawParams& materialLawParams(const Element &element,
-            const FVElementGeometry &fvGeometry,
-            const int scvIdx) const
+     const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition &globalPos) const
     {
         return materialParams_;
     }
@@ -170,13 +162,9 @@ public:
      *
      * This is only required for non-isothermal models.
      *
-     * \param element The finite element
-     * \param fvGeometry The finite volume geometry
-     * \param scvIdx The local index of the sub-control volume
+     * \param globalPos The global position
      */
-    Scalar solidHeatCapacity(const Element &element,
-                             const FVElementGeometry &fvGeometry,
-                             const int scvIdx) const
+    Scalar solidHeatCapacityAtPos(const GlobalPosition& globalPos) const
     {
         return 790; // specific heat capacity of granite [J / (kg K)]
     }
@@ -186,13 +174,9 @@ public:
      *
      * This is only required for non-isothermal models.
      *
-     * \param element The finite element
-     * \param fvGeometry The finite volume geometry
-     * \param scvIdx The local index of the sub-control volume
+     * \param globalPos The global position
      */
-    Scalar solidDensity(const Element &element,
-                        const FVElementGeometry &fvGeometry,
-                        const int scvIdx) const
+    Scalar solidDensityAtPos(const GlobalPosition& globalPos) const
     {
         return 2700; // density of granite [kg/m^3]
     }
@@ -200,14 +184,11 @@ public:
     /*!
      * \brief Returns the thermal conductivity \f$\mathrm{[W/(m K)]}\f$ of the porous material.
      *
-     * \param element The finite element
-     * \param fvGeometry The finite volume geometry
-     * \param scvIdx The local index of the sub-control volume where
-     *                    the heat capacity needs to be defined
+     * This is only required for non-isothermal models.
+     *
+     * \param globalPos The global position
      */
-    Scalar solidThermalConductivity(const Element &element,
-                                    const FVElementGeometry &fvGeometry,
-                                    const int scvIdx) const
+    Scalar solidThermalConductivityAtPos(const GlobalPosition& globalPos) const
     {
         return lambdaSolid_;
     }
diff --git a/test/porousmediumflow/richards/implicit/test_boxrichards.cc b/test/porousmediumflow/richards/implicit/test_boxrichards.cc
index 4d71dc885c67a23a56134cffe7b90ce9cb86f212..5805bb62baea7c9561600731e9a71703bd0f702c 100644
--- a/test/porousmediumflow/richards/implicit/test_boxrichards.cc
+++ b/test/porousmediumflow/richards/implicit/test_boxrichards.cc
@@ -19,7 +19,7 @@
 /*!
  * \file
  *
- * \brief Test for the Richards CC model.
+ * \brief Test for the Richards box model.
  */
 #include <config.h>
 
diff --git a/test/porousmediumflow/richards/implicit/test_boxrichardsniconduction.cc b/test/porousmediumflow/richards/implicit/test_boxrichardsniconduction.cc
index f14cc608144274cf04ea0e5e0b8ebe0695be4e39..014685dda5ce55739d91cd5f0668be873c847c29 100644
--- a/test/porousmediumflow/richards/implicit/test_boxrichardsniconduction.cc
+++ b/test/porousmediumflow/richards/implicit/test_boxrichardsniconduction.cc
@@ -19,12 +19,35 @@
 /*!
  * \file
  *
- * \brief test for the RichardsNI box model
+ * \brief Test for the Richards box model.
  */
 #include <config.h>
+
 #include "richardsniconductionproblem.hh"
-#include <dumux/common/start.hh>
 
+#include <ctime>
+#include <iostream>
+
+#include <dune/common/parallel/mpihelper.hh>
+#include <dune/common/timer.hh>
+#include <dune/grid/io/file/dgfparser/dgfexception.hh>
+#include <dune/grid/io/file/vtk.hh>
+#include <dune/istl/io.hh>
+
+#include <dumux/common/propertysystem.hh>
+#include <dumux/common/parameters.hh>
+#include <dumux/common/valgrind.hh>
+#include <dumux/common/dumuxmessage.hh>
+#include <dumux/common/defaultusagemessage.hh>
+
+#include <dumux/linear/amgbackend.hh>
+#include <dumux/nonlinear/newtonmethod.hh>
+#include <dumux/nonlinear/newtoncontroller.hh>
+#include <dumux/porousmediumflow/richards/implicit/newtoncontroller.hh>
+
+#include <dumux/assembly/fvassembler.hh>
+
+#include <dumux/io/vtkoutputmodule.hh>
 /*!
  * \brief Provides an interface for customizing error messages associated with
  *        reading in parameters.
@@ -45,13 +68,183 @@ void usage(const char *progName, const std::string &errorMsg)
                                         "\t-TimeManager.DtInitial Initial timestep size [s] \n"
                                         "\t-Grid.File             Name of the file containing the grid \n"
                                         "\t                       definition in DGF format\n";
+
         std::cout << errorMessageOut
                   << "\n";
     }
 }
 
-int main(int argc, char** argv)
+////////////////////////
+// the main function
+////////////////////////
+int main(int argc, char** argv) try
+{
+    using namespace Dumux;
+
+    // define the type tag for this problem
+    using TypeTag = TTAG(RichardsNIConductionBoxProblem);
+
+    // initialize MPI, finalize is done automatically on exit
+    const auto& mpiHelper = Dune::MPIHelper::instance(argc, argv);
+
+    // print dumux start message
+    if (mpiHelper.rank() == 0)
+        DumuxMessage::print(/*firstCall=*/true);
+
+    // parse command line arguments and input file
+    Parameters::init(argc, argv, usage);
+
+    // try to create a grid (from the given grid file or the input file)
+    using GridCreator = typename GET_PROP_TYPE(TypeTag, GridCreator);
+    GridCreator::makeGrid();
+    GridCreator::loadBalance();
+
+    ////////////////////////////////////////////////////////////
+    // run instationary non-linear problem on this grid
+    ////////////////////////////////////////////////////////////
+
+    // we compute on the leaf grid view
+    const auto& leafGridView = GridCreator::grid().leafGridView();
+
+    // create the finite volume grid geometry
+    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
+    auto fvGridGeometry = std::make_shared<FVGridGeometry>(leafGridView);
+    fvGridGeometry->update();
+
+    // the problem (initial and boundary conditions)
+    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
+    auto problem = std::make_shared<Problem>(fvGridGeometry);
+
+    // the solution vector
+    using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
+    SolutionVector x(fvGridGeometry->numDofs());
+    problem->applyInitialSolution(x);
+    auto xOld = x;
+
+    // the grid variables
+    using GridVariables = typename GET_PROP_TYPE(TypeTag, GridVariables);
+    auto gridVariables = std::make_shared<GridVariables>(problem, fvGridGeometry);
+    gridVariables->init(x, xOld);
+
+    // get some time loop parameters
+    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
+    const auto tEnd = getParam<Scalar>("TimeLoop.TEnd");
+    const auto maxDivisions = getParam<int>("TimeLoop.MaxTimeStepDivisions");
+    const auto maxDt = getParam<Scalar>("TimeLoop.MaxTimeStepSize");
+    auto dt = getParam<Scalar>("TimeLoop.DtInitial");
+
+    // check if we are about to restart a previously interrupted simulation
+    Scalar restartTime = 0;
+    if (Parameters::getTree().hasKey("Restart") || Parameters::getTree().hasKey("TimeLoop.Restart"))
+        restartTime = getParam<Scalar>("TimeLoop.Restart");
+
+    // intialize the vtk output module
+    using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields);
+    VtkOutputModule<TypeTag> vtkWriter(*problem, *fvGridGeometry, *gridVariables, x, problem->name());
+    VtkOutputFields::init(vtkWriter); //! Add model specific output fields
+    vtkWriter.addField(problem->getExactTemperature(), "temperatureExact");
+    vtkWriter.write(0.0);
+
+    // instantiate time loop
+    auto timeLoop = std::make_shared<TimeLoop<Scalar>>(restartTime, dt, tEnd);
+    timeLoop->setMaxTimeStepSize(maxDt);
+
+    // the assembler with time loop for instationary problem
+    using Assembler = FVAssembler<TypeTag, DiffMethod::numeric>;
+    auto assembler = std::make_shared<Assembler>(problem, fvGridGeometry, gridVariables, timeLoop);
+
+    // the linear solver
+    using LinearSolver = Dumux::ILU0BiCGSTABBackend<TypeTag>;
+    auto linearSolver = std::make_shared<LinearSolver>();
+
+    // the non-linear solver
+    using NewtonController = Dumux::RichardsNewtonController<TypeTag>;
+    using NewtonMethod = Dumux::NewtonMethod<NewtonController, Assembler, LinearSolver>;
+    auto newtonController = std::make_shared<NewtonController>(leafGridView.comm(), timeLoop);
+    NewtonMethod nonLinearSolver(newtonController, assembler, linearSolver);
+
+    // time loop
+    timeLoop->start(); do
+    {
+        // set previous solution for storage evaluations
+        assembler->setPreviousSolution(xOld);
+
+        // try solving the non-linear system
+        for (int i = 0; i < maxDivisions; ++i)
+        {
+            // linearize & solve
+            auto converged = nonLinearSolver.solve(x);
+
+            if (converged)
+                break;
+
+            if (!converged && i == maxDivisions-1)
+                DUNE_THROW(Dune::MathError,
+                            "Newton solver didn't converge after "
+                            << maxDivisions
+                            << " time-step divisions. dt="
+                            << timeLoop->timeStepSize()
+                            << ".\nThe solutions of the current and the previous time steps "
+                            << "have been saved to restart files.");
+        }
+         // compute the new analytical temperature field for the output
+        problem->updateExactTemperature(x, timeLoop->time()+timeLoop->timeStepSize());
+
+        // make the new solution the old solution
+        xOld = x;
+        gridVariables->advanceTimeStep();
+
+        // advance to the time loop to the next step
+        timeLoop->advanceTimeStep();
+
+        // write vtk output
+        vtkWriter.write(timeLoop->time());
+
+        // report statistics of this time step
+        timeLoop->reportTimeStep();
+
+        // set new dt as suggested by newton controller
+        timeLoop->setTimeStepSize(newtonController->suggestTimeStepSize(timeLoop->timeStepSize()));
+
+    } while (!timeLoop->finished());
+
+    timeLoop->finalize(leafGridView.comm());
+
+    ////////////////////////////////////////////////////////////
+    // finalize, print dumux message to say goodbye
+    ////////////////////////////////////////////////////////////
+
+    // print dumux end message
+    if (mpiHelper.rank() == 0)
+    {
+        Parameters::print();
+        DumuxMessage::print(/*firstCall=*/false);
+    }
+
+    return 0;
+}
+
+catch (Dumux::ParameterException &e)
+{
+    std::cerr << std::endl << e << " ---> Abort!" << std::endl;
+    return 1;
+}
+catch (Dune::DGFException & e)
+{
+    std::cerr << "DGF exception thrown (" << e <<
+                 "). Most likely, the DGF file name is wrong "
+                 "or the DGF file is corrupted, "
+                 "e.g. missing hash at end of file or wrong number (dimensions) of entries."
+                 << " ---> Abort!" << std::endl;
+    return 2;
+}
+catch (Dune::Exception &e)
+{
+    std::cerr << "Dune reported error: " << e << " ---> Abort!" << std::endl;
+    return 3;
+}
+catch (...)
 {
-    typedef TTAG(RichardsNIConductionBoxProblem) ProblemTypeTag;
-    return Dumux::start<ProblemTypeTag>(argc, argv, usage);
+    std::cerr << "Unknown exception thrown! ---> Abort!" << std::endl;
+    return 4;
 }
diff --git a/test/porousmediumflow/richards/implicit/test_boxrichardsniconduction.input b/test/porousmediumflow/richards/implicit/test_boxrichardsniconduction.input
index afed3ddd3cde6462f0baad1c93be5f6c65387179..65a74ff7aab30a415329a78b1515707db06bfa61 100644
--- a/test/porousmediumflow/richards/implicit/test_boxrichardsniconduction.input
+++ b/test/porousmediumflow/richards/implicit/test_boxrichardsniconduction.input
@@ -1,4 +1,4 @@
-[TimeManager]
+[TimeLoop]
 DtInitial = 1 # [s]
 TEnd = 1e5 # [s]
 MaxTimeStepSize = 1e10 # [s]
@@ -12,5 +12,5 @@ Name = test_boxrichardsniconduction # name passed to the output routines
 OutputInterval = 5 # every 5th timestep an output file is written
 EnableGravity= 0 # disable gravity
 
-[Vtk]
-AddVelocity = 1 # enable velocity output
+[Newton]
+EnableChop = false  # chop for better convergence
diff --git a/test/porousmediumflow/richards/implicit/test_boxrichardsniconvection.cc b/test/porousmediumflow/richards/implicit/test_boxrichardsniconvection.cc
index 10becacae6b3d1e0b84eeb8f5354ee59dd312833..c6b60e4770210543de8d2218ae600a5d3f97c4db 100644
--- a/test/porousmediumflow/richards/implicit/test_boxrichardsniconvection.cc
+++ b/test/porousmediumflow/richards/implicit/test_boxrichardsniconvection.cc
@@ -19,12 +19,35 @@
 /*!
  * \file
  *
- * \brief test for the RichardsNI box model
+ * \brief Test for the Richards box model.
  */
 #include <config.h>
+
 #include "richardsniconvectionproblem.hh"
-#include <dumux/common/start.hh>
 
+#include <ctime>
+#include <iostream>
+
+#include <dune/common/parallel/mpihelper.hh>
+#include <dune/common/timer.hh>
+#include <dune/grid/io/file/dgfparser/dgfexception.hh>
+#include <dune/grid/io/file/vtk.hh>
+#include <dune/istl/io.hh>
+
+#include <dumux/common/propertysystem.hh>
+#include <dumux/common/parameters.hh>
+#include <dumux/common/valgrind.hh>
+#include <dumux/common/dumuxmessage.hh>
+#include <dumux/common/defaultusagemessage.hh>
+
+#include <dumux/linear/amgbackend.hh>
+#include <dumux/nonlinear/newtonmethod.hh>
+#include <dumux/nonlinear/newtoncontroller.hh>
+#include <dumux/porousmediumflow/richards/implicit/newtoncontroller.hh>
+
+#include <dumux/assembly/fvassembler.hh>
+
+#include <dumux/io/vtkoutputmodule.hh>
 /*!
  * \brief Provides an interface for customizing error messages associated with
  *        reading in parameters.
@@ -45,13 +68,183 @@ void usage(const char *progName, const std::string &errorMsg)
                                         "\t-TimeManager.DtInitial Initial timestep size [s] \n"
                                         "\t-Grid.File             Name of the file containing the grid \n"
                                         "\t                       definition in DGF format\n";
+
         std::cout << errorMessageOut
                   << "\n";
     }
 }
 
-int main(int argc, char** argv)
+////////////////////////
+// the main function
+////////////////////////
+int main(int argc, char** argv) try
+{
+    using namespace Dumux;
+
+    // define the type tag for this problem
+    using TypeTag = TTAG(RichardsNIConvectionBoxProblem);
+
+    // initialize MPI, finalize is done automatically on exit
+    const auto& mpiHelper = Dune::MPIHelper::instance(argc, argv);
+
+    // print dumux start message
+    if (mpiHelper.rank() == 0)
+        DumuxMessage::print(/*firstCall=*/true);
+
+    // parse command line arguments and input file
+    Parameters::init(argc, argv, usage);
+
+    // try to create a grid (from the given grid file or the input file)
+    using GridCreator = typename GET_PROP_TYPE(TypeTag, GridCreator);
+    GridCreator::makeGrid();
+    GridCreator::loadBalance();
+
+    ////////////////////////////////////////////////////////////
+    // run instationary non-linear problem on this grid
+    ////////////////////////////////////////////////////////////
+
+    // we compute on the leaf grid view
+    const auto& leafGridView = GridCreator::grid().leafGridView();
+
+    // create the finite volume grid geometry
+    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
+    auto fvGridGeometry = std::make_shared<FVGridGeometry>(leafGridView);
+    fvGridGeometry->update();
+
+    // the problem (initial and boundary conditions)
+    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
+    auto problem = std::make_shared<Problem>(fvGridGeometry);
+
+    // the solution vector
+    using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
+    SolutionVector x(fvGridGeometry->numDofs());
+    problem->applyInitialSolution(x);
+    auto xOld = x;
+
+    // the grid variables
+    using GridVariables = typename GET_PROP_TYPE(TypeTag, GridVariables);
+    auto gridVariables = std::make_shared<GridVariables>(problem, fvGridGeometry);
+    gridVariables->init(x, xOld);
+
+    // get some time loop parameters
+    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
+    const auto tEnd = getParam<Scalar>("TimeLoop.TEnd");
+    const auto maxDivisions = getParam<int>("TimeLoop.MaxTimeStepDivisions");
+    const auto maxDt = getParam<Scalar>("TimeLoop.MaxTimeStepSize");
+    auto dt = getParam<Scalar>("TimeLoop.DtInitial");
+
+    // check if we are about to restart a previously interrupted simulation
+    Scalar restartTime = 0;
+    if (Parameters::getTree().hasKey("Restart") || Parameters::getTree().hasKey("TimeLoop.Restart"))
+        restartTime = getParam<Scalar>("TimeLoop.Restart");
+
+    // intialize the vtk output module
+    using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields);
+    VtkOutputModule<TypeTag> vtkWriter(*problem, *fvGridGeometry, *gridVariables, x, problem->name());
+    VtkOutputFields::init(vtkWriter); //! Add model specific output fields
+    vtkWriter.addField(problem->getExactTemperature(), "temperatureExact");
+    vtkWriter.write(0.0);
+
+    // instantiate time loop
+    auto timeLoop = std::make_shared<TimeLoop<Scalar>>(restartTime, dt, tEnd);
+    timeLoop->setMaxTimeStepSize(maxDt);
+
+    // the assembler with time loop for instationary problem
+    using Assembler = FVAssembler<TypeTag, DiffMethod::numeric>;
+    auto assembler = std::make_shared<Assembler>(problem, fvGridGeometry, gridVariables, timeLoop);
+
+    // the linear solver
+    using LinearSolver = Dumux::ILU0BiCGSTABBackend<TypeTag>;
+    auto linearSolver = std::make_shared<LinearSolver>();
+
+    // the non-linear solver
+    using NewtonController = Dumux::RichardsNewtonController<TypeTag>;
+    using NewtonMethod = Dumux::NewtonMethod<NewtonController, Assembler, LinearSolver>;
+    auto newtonController = std::make_shared<NewtonController>(leafGridView.comm(), timeLoop);
+    NewtonMethod nonLinearSolver(newtonController, assembler, linearSolver);
+
+    // time loop
+    timeLoop->start(); do
+    {
+        // set previous solution for storage evaluations
+        assembler->setPreviousSolution(xOld);
+
+        // try solving the non-linear system
+        for (int i = 0; i < maxDivisions; ++i)
+        {
+            // linearize & solve
+            auto converged = nonLinearSolver.solve(x);
+
+            if (converged)
+                break;
+
+            if (!converged && i == maxDivisions-1)
+                DUNE_THROW(Dune::MathError,
+                            "Newton solver didn't converge after "
+                            << maxDivisions
+                            << " time-step divisions. dt="
+                            << timeLoop->timeStepSize()
+                            << ".\nThe solutions of the current and the previous time steps "
+                            << "have been saved to restart files.");
+        }
+         // compute the new analytical temperature field for the output
+        problem->updateExactTemperature(x, timeLoop->time()+timeLoop->timeStepSize());
+
+        // make the new solution the old solution
+        xOld = x;
+        gridVariables->advanceTimeStep();
+
+        // advance to the time loop to the next step
+        timeLoop->advanceTimeStep();
+
+        // write vtk output
+        vtkWriter.write(timeLoop->time());
+
+        // report statistics of this time step
+        timeLoop->reportTimeStep();
+
+        // set new dt as suggested by newton controller
+        timeLoop->setTimeStepSize(newtonController->suggestTimeStepSize(timeLoop->timeStepSize()));
+
+    } while (!timeLoop->finished());
+
+    timeLoop->finalize(leafGridView.comm());
+
+    ////////////////////////////////////////////////////////////
+    // finalize, print dumux message to say goodbye
+    ////////////////////////////////////////////////////////////
+
+    // print dumux end message
+    if (mpiHelper.rank() == 0)
+    {
+        Parameters::print();
+        DumuxMessage::print(/*firstCall=*/false);
+    }
+
+    return 0;
+}
+
+catch (Dumux::ParameterException &e)
+{
+    std::cerr << std::endl << e << " ---> Abort!" << std::endl;
+    return 1;
+}
+catch (Dune::DGFException & e)
+{
+    std::cerr << "DGF exception thrown (" << e <<
+                 "). Most likely, the DGF file name is wrong "
+                 "or the DGF file is corrupted, "
+                 "e.g. missing hash at end of file or wrong number (dimensions) of entries."
+                 << " ---> Abort!" << std::endl;
+    return 2;
+}
+catch (Dune::Exception &e)
+{
+    std::cerr << "Dune reported error: " << e << " ---> Abort!" << std::endl;
+    return 3;
+}
+catch (...)
 {
-    typedef TTAG(RichardsNIConvectionBoxProblem) ProblemTypeTag;
-    return Dumux::start<ProblemTypeTag>(argc, argv, usage);
+    std::cerr << "Unknown exception thrown! ---> Abort!" << std::endl;
+    return 4;
 }
diff --git a/test/porousmediumflow/richards/implicit/test_boxrichardsniconvection.input b/test/porousmediumflow/richards/implicit/test_boxrichardsniconvection.input
index 98fd0d6c70570f9963ab0ee8c7b28f75c8d8c914..be59a892ccb35ed43722f57c706d2f07064079c8 100644
--- a/test/porousmediumflow/richards/implicit/test_boxrichardsniconvection.input
+++ b/test/porousmediumflow/richards/implicit/test_boxrichardsniconvection.input
@@ -1,4 +1,4 @@
-[TimeManager]
+[TimeLoop]
 DtInitial = 1 # [s]
 TEnd = 3e4 # [s]
 MaxTimeStepSize = 1e3 # [s]
@@ -13,5 +13,5 @@ OutputInterval = 5 # every 5th timestep an output file is written
 DarcyVelocity = 1e-4 # [m/s] inflow at the left boundary
 EnableGravity = 0 # disable gravity
 
-[Vtk]
-AddVelocity = 1 # enable velocity output
+[Newton]
+EnableChop = false  # chop for better convergence
diff --git a/test/porousmediumflow/richards/implicit/test_ccrichardsniconduction.cc b/test/porousmediumflow/richards/implicit/test_ccrichardsniconduction.cc
index 212f9d00847d999b175aaa5ddf1ebbed6f7bc733..07812769c37c38df271c776bd727c7a9a218124e 100644
--- a/test/porousmediumflow/richards/implicit/test_ccrichardsniconduction.cc
+++ b/test/porousmediumflow/richards/implicit/test_ccrichardsniconduction.cc
@@ -19,12 +19,35 @@
 /*!
  * \file
  *
- * \brief test for the RichardsNI cc model
+ * \brief Test for the Richards CC model.
  */
 #include <config.h>
+
 #include "richardsniconductionproblem.hh"
-#include <dumux/common/start.hh>
 
+#include <ctime>
+#include <iostream>
+
+#include <dune/common/parallel/mpihelper.hh>
+#include <dune/common/timer.hh>
+#include <dune/grid/io/file/dgfparser/dgfexception.hh>
+#include <dune/grid/io/file/vtk.hh>
+#include <dune/istl/io.hh>
+
+#include <dumux/common/propertysystem.hh>
+#include <dumux/common/parameters.hh>
+#include <dumux/common/valgrind.hh>
+#include <dumux/common/dumuxmessage.hh>
+#include <dumux/common/defaultusagemessage.hh>
+
+#include <dumux/linear/amgbackend.hh>
+#include <dumux/nonlinear/newtonmethod.hh>
+#include <dumux/nonlinear/newtoncontroller.hh>
+#include <dumux/porousmediumflow/richards/implicit/newtoncontroller.hh>
+
+#include <dumux/assembly/fvassembler.hh>
+
+#include <dumux/io/vtkoutputmodule.hh>
 /*!
  * \brief Provides an interface for customizing error messages associated with
  *        reading in parameters.
@@ -45,13 +68,183 @@ void usage(const char *progName, const std::string &errorMsg)
                                         "\t-TimeManager.DtInitial Initial timestep size [s] \n"
                                         "\t-Grid.File             Name of the file containing the grid \n"
                                         "\t                       definition in DGF format\n";
+
         std::cout << errorMessageOut
                   << "\n";
     }
 }
 
-int main(int argc, char** argv)
+////////////////////////
+// the main function
+////////////////////////
+int main(int argc, char** argv) try
+{
+    using namespace Dumux;
+
+    // define the type tag for this problem
+    using TypeTag = TTAG(RichardsNIConductionCCProblem);
+
+    // initialize MPI, finalize is done automatically on exit
+    const auto& mpiHelper = Dune::MPIHelper::instance(argc, argv);
+
+    // print dumux start message
+    if (mpiHelper.rank() == 0)
+        DumuxMessage::print(/*firstCall=*/true);
+
+    // parse command line arguments and input file
+    Parameters::init(argc, argv, usage);
+
+    // try to create a grid (from the given grid file or the input file)
+    using GridCreator = typename GET_PROP_TYPE(TypeTag, GridCreator);
+    GridCreator::makeGrid();
+    GridCreator::loadBalance();
+
+    ////////////////////////////////////////////////////////////
+    // run instationary non-linear problem on this grid
+    ////////////////////////////////////////////////////////////
+
+    // we compute on the leaf grid view
+    const auto& leafGridView = GridCreator::grid().leafGridView();
+
+    // create the finite volume grid geometry
+    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
+    auto fvGridGeometry = std::make_shared<FVGridGeometry>(leafGridView);
+    fvGridGeometry->update();
+
+    // the problem (initial and boundary conditions)
+    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
+    auto problem = std::make_shared<Problem>(fvGridGeometry);
+
+    // the solution vector
+    using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
+    SolutionVector x(fvGridGeometry->numDofs());
+    problem->applyInitialSolution(x);
+    auto xOld = x;
+
+    // the grid variables
+    using GridVariables = typename GET_PROP_TYPE(TypeTag, GridVariables);
+    auto gridVariables = std::make_shared<GridVariables>(problem, fvGridGeometry);
+    gridVariables->init(x, xOld);
+
+    // get some time loop parameters
+    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
+    const auto tEnd = getParam<Scalar>("TimeLoop.TEnd");
+    const auto maxDivisions = getParam<int>("TimeLoop.MaxTimeStepDivisions");
+    const auto maxDt = getParam<Scalar>("TimeLoop.MaxTimeStepSize");
+    auto dt = getParam<Scalar>("TimeLoop.DtInitial");
+
+    // check if we are about to restart a previously interrupted simulation
+    Scalar restartTime = 0;
+    if (Parameters::getTree().hasKey("Restart") || Parameters::getTree().hasKey("TimeLoop.Restart"))
+        restartTime = getParam<Scalar>("TimeLoop.Restart");
+
+    // intialize the vtk output module
+    using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields);
+    VtkOutputModule<TypeTag> vtkWriter(*problem, *fvGridGeometry, *gridVariables, x, problem->name());
+    VtkOutputFields::init(vtkWriter); //! Add model specific output fields
+    vtkWriter.addField(problem->getExactTemperature(), "temperatureExact");
+    vtkWriter.write(0.0);
+
+    // instantiate time loop
+    auto timeLoop = std::make_shared<TimeLoop<Scalar>>(restartTime, dt, tEnd);
+    timeLoop->setMaxTimeStepSize(maxDt);
+
+    // the assembler with time loop for instationary problem
+    using Assembler = FVAssembler<TypeTag, DiffMethod::numeric>;
+    auto assembler = std::make_shared<Assembler>(problem, fvGridGeometry, gridVariables, timeLoop);
+
+    // the linear solver
+    using LinearSolver = Dumux::ILU0BiCGSTABBackend<TypeTag>;
+    auto linearSolver = std::make_shared<LinearSolver>();
+
+    // the non-linear solver
+    using NewtonController = Dumux::RichardsNewtonController<TypeTag>;
+    using NewtonMethod = Dumux::NewtonMethod<NewtonController, Assembler, LinearSolver>;
+    auto newtonController = std::make_shared<NewtonController>(leafGridView.comm(), timeLoop);
+    NewtonMethod nonLinearSolver(newtonController, assembler, linearSolver);
+
+    // time loop
+    timeLoop->start(); do
+    {
+        // set previous solution for storage evaluations
+        assembler->setPreviousSolution(xOld);
+
+        // try solving the non-linear system
+        for (int i = 0; i < maxDivisions; ++i)
+        {
+            // linearize & solve
+            auto converged = nonLinearSolver.solve(x);
+
+            if (converged)
+                break;
+
+            if (!converged && i == maxDivisions-1)
+                DUNE_THROW(Dune::MathError,
+                            "Newton solver didn't converge after "
+                            << maxDivisions
+                            << " time-step divisions. dt="
+                            << timeLoop->timeStepSize()
+                            << ".\nThe solutions of the current and the previous time steps "
+                            << "have been saved to restart files.");
+        }
+         // compute the new analytical temperature field for the output
+        problem->updateExactTemperature(x, timeLoop->time()+timeLoop->timeStepSize());
+
+        // make the new solution the old solution
+        xOld = x;
+        gridVariables->advanceTimeStep();
+
+        // advance to the time loop to the next step
+        timeLoop->advanceTimeStep();
+
+        // write vtk output
+        vtkWriter.write(timeLoop->time());
+
+        // report statistics of this time step
+        timeLoop->reportTimeStep();
+
+        // set new dt as suggested by newton controller
+        timeLoop->setTimeStepSize(newtonController->suggestTimeStepSize(timeLoop->timeStepSize()));
+
+    } while (!timeLoop->finished());
+
+    timeLoop->finalize(leafGridView.comm());
+
+    ////////////////////////////////////////////////////////////
+    // finalize, print dumux message to say goodbye
+    ////////////////////////////////////////////////////////////
+
+    // print dumux end message
+    if (mpiHelper.rank() == 0)
+    {
+        Parameters::print();
+        DumuxMessage::print(/*firstCall=*/false);
+    }
+
+    return 0;
+}
+
+catch (Dumux::ParameterException &e)
+{
+    std::cerr << std::endl << e << " ---> Abort!" << std::endl;
+    return 1;
+}
+catch (Dune::DGFException & e)
+{
+    std::cerr << "DGF exception thrown (" << e <<
+                 "). Most likely, the DGF file name is wrong "
+                 "or the DGF file is corrupted, "
+                 "e.g. missing hash at end of file or wrong number (dimensions) of entries."
+                 << " ---> Abort!" << std::endl;
+    return 2;
+}
+catch (Dune::Exception &e)
+{
+    std::cerr << "Dune reported error: " << e << " ---> Abort!" << std::endl;
+    return 3;
+}
+catch (...)
 {
-    typedef TTAG(RichardsNIConductionCCProblem) ProblemTypeTag;
-    return Dumux::start<ProblemTypeTag>(argc, argv, usage);
+    std::cerr << "Unknown exception thrown! ---> Abort!" << std::endl;
+    return 4;
 }
diff --git a/test/porousmediumflow/richards/implicit/test_ccrichardsniconduction.input b/test/porousmediumflow/richards/implicit/test_ccrichardsniconduction.input
index 9f1d1ae0be5cd13fd00c17a9484ef04e71cd921f..fa4803bb64ad929e831eb4079febe74dea1dc96f 100644
--- a/test/porousmediumflow/richards/implicit/test_ccrichardsniconduction.input
+++ b/test/porousmediumflow/richards/implicit/test_ccrichardsniconduction.input
@@ -1,4 +1,4 @@
-[TimeManager]
+[TimeLoop]
 DtInitial = 1 # [s]
 TEnd = 1e5 # [s]
 MaxTimeStepSize = 1e10 # [s]
@@ -12,5 +12,5 @@ Name = test_ccrichardsniconduction # name passed to the output routines
 OutputInterval = 5 # every 5th timestep an output file is written
 EnableGravity= 0 # disable gravity
 
-[Vtk]
-AddVelocity = 1 # enable velocity output
+[Newton]
+EnableChop = false # chop for better convergence
diff --git a/test/porousmediumflow/richards/implicit/test_ccrichardsniconvection.cc b/test/porousmediumflow/richards/implicit/test_ccrichardsniconvection.cc
index f9406ad117b5014363abaed929ac637a795ec45e..47b703e730d8b33830e57c115736f2b9608364ec 100644
--- a/test/porousmediumflow/richards/implicit/test_ccrichardsniconvection.cc
+++ b/test/porousmediumflow/richards/implicit/test_ccrichardsniconvection.cc
@@ -19,12 +19,35 @@
 /*!
  * \file
  *
- * \brief test for the RichardsNI cc model
+ * \brief Test for the Richards CC model.
  */
 #include <config.h>
+
 #include "richardsniconvectionproblem.hh"
-#include <dumux/common/start.hh>
 
+#include <ctime>
+#include <iostream>
+
+#include <dune/common/parallel/mpihelper.hh>
+#include <dune/common/timer.hh>
+#include <dune/grid/io/file/dgfparser/dgfexception.hh>
+#include <dune/grid/io/file/vtk.hh>
+#include <dune/istl/io.hh>
+
+#include <dumux/common/propertysystem.hh>
+#include <dumux/common/parameters.hh>
+#include <dumux/common/valgrind.hh>
+#include <dumux/common/dumuxmessage.hh>
+#include <dumux/common/defaultusagemessage.hh>
+
+#include <dumux/linear/amgbackend.hh>
+#include <dumux/nonlinear/newtonmethod.hh>
+#include <dumux/nonlinear/newtoncontroller.hh>
+#include <dumux/porousmediumflow/richards/implicit/newtoncontroller.hh>
+
+#include <dumux/assembly/fvassembler.hh>
+
+#include <dumux/io/vtkoutputmodule.hh>
 /*!
  * \brief Provides an interface for customizing error messages associated with
  *        reading in parameters.
@@ -45,13 +68,183 @@ void usage(const char *progName, const std::string &errorMsg)
                                         "\t-TimeManager.DtInitial Initial timestep size [s] \n"
                                         "\t-Grid.File             Name of the file containing the grid \n"
                                         "\t                       definition in DGF format\n";
+
         std::cout << errorMessageOut
                   << "\n";
     }
 }
 
-int main(int argc, char** argv)
+////////////////////////
+// the main function
+////////////////////////
+int main(int argc, char** argv) try
+{
+    using namespace Dumux;
+
+    // define the type tag for this problem
+    using TypeTag = TTAG(RichardsNIConvectionCCProblem);
+
+    // initialize MPI, finalize is done automatically on exit
+    const auto& mpiHelper = Dune::MPIHelper::instance(argc, argv);
+
+    // print dumux start message
+    if (mpiHelper.rank() == 0)
+        DumuxMessage::print(/*firstCall=*/true);
+
+    // parse command line arguments and input file
+    Parameters::init(argc, argv, usage);
+
+    // try to create a grid (from the given grid file or the input file)
+    using GridCreator = typename GET_PROP_TYPE(TypeTag, GridCreator);
+    GridCreator::makeGrid();
+    GridCreator::loadBalance();
+
+    ////////////////////////////////////////////////////////////
+    // run instationary non-linear problem on this grid
+    ////////////////////////////////////////////////////////////
+
+    // we compute on the leaf grid view
+    const auto& leafGridView = GridCreator::grid().leafGridView();
+
+    // create the finite volume grid geometry
+    using FVGridGeometry = typename GET_PROP_TYPE(TypeTag, FVGridGeometry);
+    auto fvGridGeometry = std::make_shared<FVGridGeometry>(leafGridView);
+    fvGridGeometry->update();
+
+    // the problem (initial and boundary conditions)
+    using Problem = typename GET_PROP_TYPE(TypeTag, Problem);
+    auto problem = std::make_shared<Problem>(fvGridGeometry);
+
+    // the solution vector
+    using SolutionVector = typename GET_PROP_TYPE(TypeTag, SolutionVector);
+    SolutionVector x(fvGridGeometry->numDofs());
+    problem->applyInitialSolution(x);
+    auto xOld = x;
+
+    // the grid variables
+    using GridVariables = typename GET_PROP_TYPE(TypeTag, GridVariables);
+    auto gridVariables = std::make_shared<GridVariables>(problem, fvGridGeometry);
+    gridVariables->init(x, xOld);
+
+    // get some time loop parameters
+    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
+    const auto tEnd = getParam<Scalar>("TimeLoop.TEnd");
+    const auto maxDivisions = getParam<int>("TimeLoop.MaxTimeStepDivisions");
+    const auto maxDt = getParam<Scalar>("TimeLoop.MaxTimeStepSize");
+    auto dt = getParam<Scalar>("TimeLoop.DtInitial");
+
+    // check if we are about to restart a previously interrupted simulation
+    Scalar restartTime = 0;
+    if (Parameters::getTree().hasKey("Restart") || Parameters::getTree().hasKey("TimeLoop.Restart"))
+        restartTime = getParam<Scalar>("TimeLoop.Restart");
+
+    // intialize the vtk output module
+    using VtkOutputFields = typename GET_PROP_TYPE(TypeTag, VtkOutputFields);
+    VtkOutputModule<TypeTag> vtkWriter(*problem, *fvGridGeometry, *gridVariables, x, problem->name());
+    VtkOutputFields::init(vtkWriter); //! Add model specific output fields
+    vtkWriter.addField(problem->getExactTemperature(), "temperatureExact");
+    vtkWriter.write(0.0);
+
+    // instantiate time loop
+    auto timeLoop = std::make_shared<TimeLoop<Scalar>>(restartTime, dt, tEnd);
+    timeLoop->setMaxTimeStepSize(maxDt);
+
+    // the assembler with time loop for instationary problem
+    using Assembler = FVAssembler<TypeTag, DiffMethod::numeric>;
+    auto assembler = std::make_shared<Assembler>(problem, fvGridGeometry, gridVariables, timeLoop);
+
+    // the linear solver
+    using LinearSolver = Dumux::ILU0BiCGSTABBackend<TypeTag>;
+    auto linearSolver = std::make_shared<LinearSolver>();
+
+    // the non-linear solver
+    using NewtonController = Dumux::RichardsNewtonController<TypeTag>;
+    using NewtonMethod = Dumux::NewtonMethod<NewtonController, Assembler, LinearSolver>;
+    auto newtonController = std::make_shared<NewtonController>(leafGridView.comm(), timeLoop);
+    NewtonMethod nonLinearSolver(newtonController, assembler, linearSolver);
+
+    // time loop
+    timeLoop->start(); do
+    {
+        // set previous solution for storage evaluations
+        assembler->setPreviousSolution(xOld);
+
+        // try solving the non-linear system
+        for (int i = 0; i < maxDivisions; ++i)
+        {
+            // linearize & solve
+            auto converged = nonLinearSolver.solve(x);
+
+            if (converged)
+                break;
+
+            if (!converged && i == maxDivisions-1)
+                DUNE_THROW(Dune::MathError,
+                            "Newton solver didn't converge after "
+                            << maxDivisions
+                            << " time-step divisions. dt="
+                            << timeLoop->timeStepSize()
+                            << ".\nThe solutions of the current and the previous time steps "
+                            << "have been saved to restart files.");
+        }
+         // compute the new analytical temperature field for the output
+        problem->updateExactTemperature(x, timeLoop->time()+timeLoop->timeStepSize());
+
+        // make the new solution the old solution
+        xOld = x;
+        gridVariables->advanceTimeStep();
+
+        // advance to the time loop to the next step
+        timeLoop->advanceTimeStep();
+
+        // write vtk output
+        vtkWriter.write(timeLoop->time());
+
+        // report statistics of this time step
+        timeLoop->reportTimeStep();
+
+        // set new dt as suggested by newton controller
+        timeLoop->setTimeStepSize(newtonController->suggestTimeStepSize(timeLoop->timeStepSize()));
+
+    } while (!timeLoop->finished());
+
+    timeLoop->finalize(leafGridView.comm());
+
+    ////////////////////////////////////////////////////////////
+    // finalize, print dumux message to say goodbye
+    ////////////////////////////////////////////////////////////
+
+    // print dumux end message
+    if (mpiHelper.rank() == 0)
+    {
+        Parameters::print();
+        DumuxMessage::print(/*firstCall=*/false);
+    }
+
+    return 0;
+}
+
+catch (Dumux::ParameterException &e)
+{
+    std::cerr << std::endl << e << " ---> Abort!" << std::endl;
+    return 1;
+}
+catch (Dune::DGFException & e)
+{
+    std::cerr << "DGF exception thrown (" << e <<
+                 "). Most likely, the DGF file name is wrong "
+                 "or the DGF file is corrupted, "
+                 "e.g. missing hash at end of file or wrong number (dimensions) of entries."
+                 << " ---> Abort!" << std::endl;
+    return 2;
+}
+catch (Dune::Exception &e)
+{
+    std::cerr << "Dune reported error: " << e << " ---> Abort!" << std::endl;
+    return 3;
+}
+catch (...)
 {
-    typedef TTAG(RichardsNIConvectionCCProblem) ProblemTypeTag;
-    return Dumux::start<ProblemTypeTag>(argc, argv, usage);
+    std::cerr << "Unknown exception thrown! ---> Abort!" << std::endl;
+    return 4;
 }
diff --git a/test/porousmediumflow/richards/implicit/test_ccrichardsniconvection.input b/test/porousmediumflow/richards/implicit/test_ccrichardsniconvection.input
index a8d961715fd7da74e3a207179802805a25312375..8d1e9d7bc29d4fe9e0a2f777c89c6fec0abab165 100644
--- a/test/porousmediumflow/richards/implicit/test_ccrichardsniconvection.input
+++ b/test/porousmediumflow/richards/implicit/test_ccrichardsniconvection.input
@@ -1,4 +1,4 @@
-[TimeManager]
+[TimeLoop]
 DtInitial = 1 # [s]
 TEnd = 3e4 # [s]
 MaxTimeStepSize = 1e3 # [s]
@@ -13,5 +13,5 @@ OutputInterval = 5 # every 5th timestep an output file is written
 DarcyVelocity = 1e-4 # [m/s] inflow at the left boundary
 EnableGravity = 0 # disable gravity
 
-[Vtk]
-AddVelocity = 1 # enable velocity output
+[Newton]
+EnableChop = false  # chop for better convergence