diff --git a/dumux/boxmodels/2p/2pfluxvariables.hh b/dumux/boxmodels/2p/2pfluxvariables.hh
index 082d62298db5175332c4ea8370ac2e9e309516cd..4ea7096c07d4c285f68fd0dc19ac8e1bcdabc179 100644
--- a/dumux/boxmodels/2p/2pfluxvariables.hh
+++ b/dumux/boxmodels/2p/2pfluxvariables.hh
@@ -58,7 +58,7 @@ class TwoPFluxVariables
 
     typedef typename GridView::ctype CoordScalar;
     typedef typename GridView::template Codim<0>::Entity Element;
-    typedef typename GET_PROP_TYPE(TypeTag, PTAG(ElementVariables)) ElementVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(ElementVolumeVariables)) ElementVolumeVariables;
 
     enum {
         dim = GridView::dimension,
@@ -77,90 +77,100 @@ class TwoPFluxVariables
 public:
     /*
      * \brief The constructor
+     *
+     * \param problem The problem
+     * \param element The finite element
+     * \param elemGeom The finite-volume geometry in the box scheme
+     * \param faceIdx The local index of the SCV (sub-control-volume) face
+     * \param elemDat The volume variables of the current element
      */
-    TwoPFluxVariables()
-    {}
-
-#warning Docme
-    void update(const ElementVariables &elemVars, int scvfIdx)
+    TwoPFluxVariables(const Problem &problem,
+                 const Element &element,
+                 const FVElementGeometry &elemGeom,
+                 int faceIdx,
+                 const ElementVolumeVariables &elemDat)
+        : fvElemGeom_(elemGeom)
     {
-        insideScvIdx_ = elemVars.fvElemGeom().subContVolFace[scvfIdx].i;
-        outsideScvIdx_ = elemVars.fvElemGeom().subContVolFace[scvfIdx].j;
+        scvfIdx_ = faceIdx;
+
+        for (int phase = 0; phase < numPhases; ++phase) {
+            potentialGrad_[phase] = Scalar(0);
+        }
 
-        calculateGradients_(elemVars, scvfIdx);
-        calculateNormalFlux_(elemVars, scvfIdx);
+        calculateGradients_(problem, element, elemDat);
+        calculateK_(problem, element, elemDat);
     };
 
-    /*!
-     * \brief Return the extrusion factor of the SCVF.
+public:
+    /*
+     * \brief Return the intrinsic permeability.
      */
-    Scalar extrusionFactor() const
-    { return 1.0; }
+    const Tensor &intrinsicPermeability() const
+    { return K_; }
 
     /*!
-     * \brief Return a phase's pressure potential gradient.
+     * \brief Return the pressure potential gradient.
      *
      * \param phaseIdx The index of the fluid phase
      */
     const Vector &potentialGrad(int phaseIdx) const
     { return potentialGrad_[phaseIdx]; }
 
-    /*!
-     * \brief Return a phase's pressure potential gradient times
-     *        intrinsic permeability times the normal of the sub
-     *        control volume face times the area of the SCVF.
-     *
-     * \param phaseIdx The index of the fluid phase
-     */
-    Scalar normalFlux(int phaseIdx) const
-    { return normalFlux_[phaseIdx]; }
-
     /*!
      * \brief Return the local index of the downstream control volume
      *        for a given phase as a function of the normal flux.
      *
-     * \param phaseIdx The index of the fluid phase for which the downstream
-     *                 direction is requested.
+     * \param normalFlux The normal flux i.e. the given intrinsic permeability
+     *                   times the pressure potential gradient and SCV face normal.
      */
-    int downstreamIdx(int phaseIdx) const
-    { return (normalFlux_[phaseIdx] > 0)?outsideScvIdx_:insideScvIdx_; }
+    int downstreamIdx(Scalar normalFlux) const
+    { return (normalFlux >= 0)?face().j:face().i; }
 
     /*!
      * \brief Return the local index of the upstream control volume
      *        for a given phase as a function of the normal flux.
      *
-     * \param phaseIdx The index of the fluid phase for which the upstream
-     *                 direction is requested.
+     * \param normalFlux The normal flux i.e. the given intrinsic permeability
+     *                   times the pressure potential gradient and SCV face normal.
      */
-    int upstreamIdx(int phaseIdx) const
-    { return (normalFlux_[phaseIdx] > 0)?insideScvIdx_:outsideScvIdx_; }
+    int upstreamIdx(Scalar normalFlux) const
+    { return (normalFlux > 0)?face().i:face().j; }
+
+    /*!
+     * \brief Return the SCV (sub-control-volume) face
+    */
+    const SCVFace &face() const
+    { return fvElemGeom_.subContVolFace[scvfIdx_]; }
 
 protected:
-    void calculateGradients_(const ElementVariables &elemVars,
-                             int scvfIdx)
-    {
-        // reset all gradients to 0
-        for (int phase = 0; phase < numPhases; ++phase) {
-            potentialGrad_[phase] = Scalar(0);
-        }
-        
-        typedef typename FVElementGeometry::SubControlVolumeFace Scvf;
-        const Scvf &scvf = elemVars.fvElemGeom().subContVolFace[scvfIdx];
+    const FVElementGeometry &fvElemGeom_;
+    int scvfIdx_;
+
+    // gradients
+    Vector potentialGrad_[numPhases];
 
+    // intrinsic permeability
+    Tensor K_;
+
+private:
+    void calculateGradients_(const Problem &problem,
+                             const Element &element,
+                             const ElementVolumeVariables &elemVolVars)
+    {
         // calculate gradients
-        for (int scvIdx = 0;
-             scvIdx < elemVars.numScv();
-             scvIdx ++) // loop over adjacent vertices
+        for (int idx = 0;
+             idx < fvElemGeom_.numVertices;
+             idx++) // loop over adjacent vertices
         {
             // FE gradient at vertex idx
-            const Vector &feGrad = scvf.grad[scvIdx];
+            const Vector &feGrad = face().grad[idx];
 
             // compute sum of pressure gradients for each phase
             for (int phase = 0; phase < numPhases; phase++)
             {
                 // the pressure gradient
                 Vector tmp(feGrad);
-                tmp *= elemVars.volVars(scvIdx, /*historyIdx=*/0).pressure(phase);
+                tmp *= elemVolVars[idx].pressure(phase);
                 potentialGrad_[phase] += tmp;
             }
         }
@@ -172,22 +182,18 @@ protected:
         {
             // estimate the gravitational acceleration at a given SCV face
             // using the arithmetic mean
-            Vector g(elemVars.problem().boxGravity(elemVars.element(), 
-                                                   elemVars.fvElemGeom(), 
-                                                   insideScvIdx_));
-            g += elemVars.problem().boxGravity(elemVars.element(), 
-                                               elemVars.fvElemGeom(), 
-                                               outsideScvIdx_);
+            Vector g(problem.boxGravity(element, fvElemGeom_, face().i));
+            g += problem.boxGravity(element, fvElemGeom_, face().j);
             g /= 2;
-            
+
             for (int phaseIdx=0; phaseIdx < numPhases; phaseIdx++)
             {
                 // calculate the phase density at the integration point. we
                 // only do this if the wetting phase is present in both cells
-                Scalar SI = elemVars.volVars(insideScvIdx_, /*historyIdx=*/0).saturation(phaseIdx);
-                Scalar SJ = elemVars.volVars(outsideScvIdx_, /*historyIdx=*/0).saturation(phaseIdx);
-                Scalar rhoI = elemVars.volVars(insideScvIdx_, /*historyIdx=*/0).density(phaseIdx);
-                Scalar rhoJ = elemVars.volVars(outsideScvIdx_, /*historyIdx=*/0).density(phaseIdx);
+                Scalar SI = elemVolVars[face().i].saturation(phaseIdx);
+                Scalar SJ = elemVolVars[face().j].saturation(phaseIdx);
+                Scalar rhoI = elemVolVars[face().i].density(phaseIdx);
+                Scalar rhoJ = elemVolVars[face().j].density(phaseIdx);
                 Scalar fI = std::max(0.0, std::min(SI/1e-5, 0.5));
                 Scalar fJ = std::max(0.0, std::min(SJ/1e-5, 0.5));
                 if (fI + fJ == 0)
@@ -206,52 +212,20 @@ protected:
         }
     }
 
-    void calculateNormalFlux_(const ElementVariables &elemVars, 
-                              int scvfIdx)
+    void calculateK_(const Problem &problem,
+                     const Element &element,
+                     const ElementVolumeVariables &elemVolVars)
     {
-        const SpatialParameters &spatialParams = elemVars.problem().spatialParameters();
-
+        const SpatialParameters &spatialParams = problem.spatialParameters();
         // calculate the intrinsic permeability
-        Tensor K;
-        spatialParams.meanK(K,
-                            spatialParams.intrinsicPermeability(elemVars,
-                                                                insideScvIdx_),
-                            spatialParams.intrinsicPermeability(elemVars,
-                                                                outsideScvIdx_));
-
-        const Vector &normal = elemVars.fvElemGeom().subContVolFace[scvfIdx].normal;
-
-        // calculate the flux in the normal direction of the
-        // current sub control volume face:
-        //
-        // v = - (K grad p) * n
-        //
-        // (the minus comes from the Darcy law which states that
-        // the flux is from high to low pressure potentials.)
-        Vector tmpVec;
-                            
-        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
-            K.mv(potentialGrad(phaseIdx), tmpVec);
-
-            // scalar product with the face normal
-            normalFlux_[phaseIdx] = 0.0;
-            for (int i = 0; i < Vector::size; ++i) 
-                normalFlux_[phaseIdx] += tmpVec[i]*normal[i];
-
-            // flux is along negative pressure gradients
-            normalFlux_[phaseIdx] *= -1;
-        }
+        spatialParams.meanK(K_,
+                            spatialParams.intrinsicPermeability(element,
+                                                                fvElemGeom_,
+                                                                face().i),
+                            spatialParams.intrinsicPermeability(element,
+                                                                fvElemGeom_,
+                                                                face().j));
     }
-
-    // local indices of the inside and the outside sub-control volumes
-    int insideScvIdx_;
-    int outsideScvIdx_;
-
-    // gradients
-    Vector potentialGrad_[numPhases];
-
-    // normal fluxes
-    Scalar normalFlux_[numPhases];
 };
 
 } // end namepace
diff --git a/dumux/boxmodels/2p/2plocalresidual.hh b/dumux/boxmodels/2p/2plocalresidual.hh
index 8c45c76ba8bc1a42b0893da20ed72b049a0c8ba4..0b554f26fdb2beb559e25dff62c57e86428bf911 100644
--- a/dumux/boxmodels/2p/2plocalresidual.hh
+++ b/dumux/boxmodels/2p/2plocalresidual.hh
@@ -82,7 +82,7 @@ protected:
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(PrimaryVariables)) PrimaryVariables;
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(VolumeVariables)) VolumeVariables;
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(FluxVariables)) FluxVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, PTAG(ElementVariables)) ElementVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(ElementVolumeVariables)) ElementVolumeVariables;
 
     typedef Dune::FieldVector<Scalar, dimWorld> Vector;
     typedef Dune::FieldMatrix<Scalar, dim, dim> Tensor;
@@ -107,26 +107,23 @@ public:
      *  \param scvIdx The SCV (sub-control-volume) index
      *  \param usePrevSol Evaluate function with solution of current or previous time step
      */
-    void computeStorage(PrimaryVariables &result, 
-                        const ElementVariables &elemVars,
-                        int scvIdx,
-                        int historyIdx) const
+    void computeStorage(PrimaryVariables &result, int scvIdx, bool usePrevSol) const
     {
-        // retrieve the volume variables for the SCV at the specified
-        // point in time
-        const VolumeVariables &volVars = elemVars.volVars(scvIdx, historyIdx);
+        // if flag usePrevSol is set, the solution from the previous
+        // time step is used, otherwise the current solution is
+        // used. The secondary variables are used accordingly.  This
+        // is required to compute the derivative of the storage term
+        // using the implicit euler method.
+        const ElementVolumeVariables &elemDat = usePrevSol ? this->prevVolVars_() : this->curVolVars_();
+        const VolumeVariables &vertDat = elemDat[scvIdx];
 
         // wetting phase mass
-        result[contiWEqIdx] = 
-            volVars.density(wPhaseIdx)
-            * volVars.porosity()
-            * volVars.saturation(wPhaseIdx);
+        result[contiWEqIdx] = vertDat.density(wPhaseIdx) * vertDat.porosity()
+                * vertDat.saturation(wPhaseIdx);
 
         // non-wetting phase mass
-        result[contiNEqIdx] = 
-            volVars.density(nPhaseIdx)
-            * volVars.porosity()
-            * volVars.saturation(nPhaseIdx);
+        result[contiNEqIdx] = vertDat.density(nPhaseIdx) * vertDat.porosity()
+                * vertDat.saturation(nPhaseIdx);
     }
 
     /*!
@@ -136,13 +133,16 @@ public:
      * \param flux The flux over the SCV (sub-control-volume) face for each phase
      * \param faceIdx The index of the SCV face
      */
-    void computeFlux(PrimaryVariables &flux,
-                     const ElementVariables &elemVars,
-                     int scvfIdx) const
+    void computeFlux(PrimaryVariables &flux, int faceIdx) const
     {
+        FluxVariables vars(this->problem_(),
+                           this->elem_(),
+                           this->fvElemGeom_(),
+                           faceIdx,
+                           this->curVolVars_());
         flux = 0;
-        asImp_()->computeAdvectiveFlux(flux, elemVars, scvfIdx);
-        asImp_()->computeDiffusiveFlux(flux, elemVars, scvfIdx);
+        asImp_()->computeAdvectiveFlux(flux, vars);
+        asImp_()->computeDiffusiveFlux(flux, vars);
     }
 
     /*!
@@ -155,40 +155,31 @@ public:
      * This method is called by compute flux and is mainly there for
      * derived models to ease adding equations selectively.
      */
-    void computeAdvectiveFlux(PrimaryVariables &flux, 
-                              const ElementVariables &elemVars,
-                              int scvfIdx) const
+    void computeAdvectiveFlux(PrimaryVariables &flux, const FluxVariables &fluxVars) const
     {
-        const FluxVariables &fluxVars = elemVars.fluxVars(scvfIdx);
-        const FluxVariables &evalPointFluxVars = elemVars.evalPointFluxVars(scvfIdx);
-
         ////////
         // advective fluxes of all components in all phases
         ////////
         Vector tmpVec;
         for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
         {
-            // data attached to upstream and the downstream vertices
-            // of the current phase. The upstream decision has to be
-            // made using the evaluation point and *not* the current
-            // solution. (although the actual secondary variables must
-            // obviously come from the current solution.)
-            int upIdx = evalPointFluxVars.upstreamIdx(phaseIdx);
-            int dnIdx = evalPointFluxVars.downstreamIdx(phaseIdx);
-            const VolumeVariables &up = elemVars.volVars(upIdx, /*historyIdx=*/0);
-            const VolumeVariables &dn = elemVars.volVars(dnIdx, /*historyIdx=*/0);
-
-            // retrieve the 'velocity' in the normal direction of the
+            // calculate the flux in the normal direction of the
             // current sub control volume face:
             //
-            // v_\alpha := - (K grad p) * n
+            // v = - (K grad p) * n
             //
-            // note that v_\alpha is *not* equivalent to the Darcy
-            // velocity because the relative permebility is not
-            // included. Its purpose is to make the upwind decision,
-            // i.e. to decide whether the flow goes from sub control
-            // volume i to j or vice versa.
-            Scalar normalFlux = fluxVars.normalFlux(phaseIdx);
+            // (the minus comes from the Darcy law which states that
+            // the flux is from high to low pressure potentials.)
+            fluxVars.intrinsicPermeability().mv(fluxVars.potentialGrad(phaseIdx), tmpVec);
+            Scalar normalFlux = 0;
+            for (int i = 0; i < Vector::size; ++i)
+                normalFlux += tmpVec[i]*fluxVars.face().normal[i];
+            normalFlux *= -1;
+
+            // data attached to upstream and the downstream vertices
+            // of the current phase
+            const VolumeVariables &up = this->curVolVars_(fluxVars.upstreamIdx(normalFlux));
+            const VolumeVariables &dn = this->curVolVars_(fluxVars.downstreamIdx(normalFlux));
 
             // add advective flux of current component in current
             // phase
@@ -213,11 +204,10 @@ public:
      * non-isothermal two-phase models to calculate diffusive heat
      * fluxes
      */
-    void computeDiffusiveFlux(PrimaryVariables &flux, 
-                              const ElementVariables &elemVars,
-                              int scvfIdx) const
+    void computeDiffusiveFlux(PrimaryVariables &flux, const FluxVariables &fluxData) const
     {
-        // no diffusive fluxes for immiscible models
+        // diffusive fluxes
+        flux += 0.0;
     }
 
     /*!
@@ -227,12 +217,14 @@ public:
      * \param localVertexIdx The index of the SCV
      *
      */
-    void computeSource(PrimaryVariables &values,
-                       const ElementVariables &elemVars,
-                       int scvIdx) const
+    void computeSource(PrimaryVariables &q, int localVertexIdx) const
     {
         // retrieve the source term intrinsic to the problem
-        elemVars.problem().source(values, elemVars, scvIdx);
+        this->problem_().boxSDSource(q,
+                                     this->elem_(),
+                                     this->fvElemGeom_(),
+                                     localVertexIdx,
+                                     this->curVolVars_());
     }
 
 
diff --git a/dumux/boxmodels/2p/2pmodel.hh b/dumux/boxmodels/2p/2pmodel.hh
index 8c2126b9a3f41d834be180f831b9c798f75174f9..604d538d0d87294433bc5962c4fa453089356518 100644
--- a/dumux/boxmodels/2p/2pmodel.hh
+++ b/dumux/boxmodels/2p/2pmodel.hh
@@ -93,7 +93,7 @@ class TwoPModel : public BoxModel<TypeTag>
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(SolutionVector)) SolutionVector;
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(TwoPIndices)) Indices;
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(FluxVariables)) FluxVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, PTAG(ElementVariables)) ElementVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(ElementVolumeVariables)) ElementVolumeVariables;
 
 
     enum {
@@ -122,11 +122,8 @@ public:
      */
     Scalar primaryVarWeight(int globalVertexIdx, int pvIdx) const
     {
-        if (Indices::pressureIdx == pvIdx) {
-            Scalar absPv = 
-                std::abs(this->solution(/*historyIdx=*/1)[globalVertexIdx][pvIdx]);
-            return std::min(10.0/absPv, 1.0);
-        }
+        if (Indices::pressureIdx == pvIdx)
+            return std::min(10.0/this->prevSol()[globalVertexIdx][pvIdx], 1.0);
         return 1;
     }
 
@@ -176,7 +173,9 @@ public:
         unsigned numElements = this->gridView_().size(0);
         ScalarField *rank = writer.allocateManagedBuffer(numElements);
 
-        ElementVariables elemVars(this->problem_());
+        FVElementGeometry fvElemGeom;
+        VolumeVariables volVars;
+        ElementVolumeVariables elemVolVars;
 
         ElementIterator elemIt = this->gridView_().template begin<0>();
         ElementIterator elemEndIt = this->gridView_().template end<0>();
@@ -189,14 +188,19 @@ public:
             int idx = this->elementMapper().map(*elemIt);
             (*rank)[idx] = this->gridView_().comm().rank();
 
-            elemVars.updateFVElemGeom(*elemIt);
-            elemVars.updateScvVars(/*historyIdx=*/0);
+            fvElemGeom.update(this->gridView_(), *elemIt);
 
-            for (int scvIdx = 0; scvIdx < elemVars.numScv(); ++scvIdx)
+            int numVerts = elemIt->template count<dim> ();
+            for (int i = 0; i < numVerts; ++i)
             {
-                int globalIdx = this->vertexMapper().map(*elemIt, scvIdx, dim);
+                int globalIdx = this->vertexMapper().map(*elemIt, i, dim);
+                volVars.update(sol[globalIdx],
+                               this->problem_(),
+                               *elemIt,
+                               fvElemGeom,
+                               i,
+                               false);
 
-                const VolumeVariables &volVars = elemVars.volVars(scvIdx, /*historyIdx=*/0);
                 (*pW)[globalIdx] = volVars.pressure(wPhaseIdx);
                 (*pN)[globalIdx] = volVars.pressure(nPhaseIdx);
                 (*pC)[globalIdx] = volVars.capillaryPressure();
@@ -214,7 +218,6 @@ public:
                 }
             };
             
-#if 0
             if(velocityOutput)
             {
                 // calculate vertex velocities
@@ -270,7 +273,6 @@ public:
 
                       // Transformation of the global normal vector to normal vector in the reference element
                       const Dune::FieldMatrix<CoordScalar, dim, dim> jacobianT1 = elemIt->geometry().jacobianTransposed(localPosIP);
-                          elemIt->geometry().jacobianTransposed(localPosIP);
 
                       GlobalPosition localNormal(0);
                       jacobianT1.mv(globalNormal, localNormal);
@@ -329,9 +331,7 @@ public:
                     (*velocityN)[globalIdx] += scvVelocity;
                 }
             }
-#endif
         }
-#if 0
             if(velocityOutput)
             {
             	// divide the vertex velocities by the number of adjacent scvs i.e. cells
@@ -340,7 +340,7 @@ public:
     	        (*velocityN)[globalIdx] /= (*cellNum)[globalIdx];
     	        }
             }
-#endif
+
         writer.attachVertexData(*Sn, "Sn");
         writer.attachVertexData(*Sw, "Sw");
         writer.attachVertexData(*pN, "pn");
@@ -352,13 +352,11 @@ public:
         writer.attachVertexData(*mobN, "mobN");
         writer.attachVertexData(*poro, "porosity");
         writer.attachVertexData(*Te, "temperature");
-#if 0
         if(velocityOutput) // check if velocity output is demanded
         {
         	writer.attachVertexData(*velocityW,  "velocityW", dim);
         	writer.attachVertexData(*velocityN,  "velocityN", dim);
         }
-#endif
         writer.attachCellData(*rank, "process rank");
     }
 };
diff --git a/dumux/boxmodels/2p/2pproblem.hh b/dumux/boxmodels/2p/2pproblem.hh
index bb30c5d275166b2197d61e3679a6a4d0ef24a764..6981be5acc2f130a392677a9fa65c720929c1003 100644
--- a/dumux/boxmodels/2p/2pproblem.hh
+++ b/dumux/boxmodels/2p/2pproblem.hh
@@ -111,26 +111,6 @@ public:
      */
     // \{
 
-    /*!
-     * \brief Returns the temperature \f$\mathrm{[K]}\f$ within a control volume.
-     *
-     * \param context Container for the volume variables, element,
-     *                fvElementGeometry, etc 
-     * \param localIdx The local index of the sub control volume inside
-     *                 the element
-     */
-    template <class Context>
-    // if you get an deprecated warning here, please use context
-    // objects to specify your problem!
-    DUNE_DEPRECATED
-    Scalar temperature(const Context &context,
-                       int localIdx) const
-    {
-        return asImp_().boxTemperature(context.element(),
-                                       context.fvElemGeom(),
-                                       localIdx);                             
-    };
-
     /*!
      * \brief Returns the temperature \f$\mathrm{[K]}\f$ within a control volume.
      *
@@ -145,7 +125,6 @@ public:
     Scalar boxTemperature(const Element &element,
                           const FVElementGeometry fvGeom,
                           int scvIdx) const
-        DUNE_DEPRECATED // use context objects!
     { return asImp_().temperatureAtPos(fvGeom.subContVol[scvIdx].global); }
     
     /*!
@@ -157,7 +136,6 @@ public:
      * \param pos The position in global coordinates where the temperature should be specified.
      */
     Scalar temperatureAtPos(const GlobalPosition &pos) const
-        DUNE_DEPRECATED // use context objects!
     { return asImp_().temperature(); }
 
     /*!
@@ -168,30 +146,8 @@ public:
      * no energy equation is used.
      */
     Scalar temperature() const
-        DUNE_DEPRECATED // use context objects!
     { DUNE_THROW(Dune::NotImplemented, "temperature() method not implemented by the actual problem"); };
 
-
-    /*!
-     * \brief Returns the acceleration due to gravity \f$\mathrm{[m/s^2]}\f$.
-     *
-     * \param context Container for the volume variables, element,
-     *                fvElementGeometry, etc 
-     * \param localIdx The local index of the sub control volume inside
-     *                 the element
-     */
-    template <class Context>
-    // if you get an deprecated warning here, please use context
-    // objects to specify your problem!
-    DUNE_DEPRECATED
-    const Vector &gravity(const Context &context,
-                          int localIdx) const
-    {
-        return asImp_().boxGravity(context.element(),
-                                   context.fvElemGeom(),
-                                   localIdx);
-    };
-
     /*!
      * \brief Returns the acceleration due to gravity \f$\mathrm{[m/s^2]}\f$.
      *
@@ -199,9 +155,8 @@ public:
      * it just calls gravityAtPos().
      */
     const Vector &boxGravity(const Element &element,
-                             const FVElementGeometry &fvGeom,
-                             int scvIdx) const
-        DUNE_DEPRECATED // use context objects!
+                                     const FVElementGeometry &fvGeom,
+                                     int scvIdx) const
     { return asImp_().gravityAtPos(fvGeom.subContVol[scvIdx].global); }
 
     /*!
diff --git a/dumux/boxmodels/2p/2pvolumevariables.hh b/dumux/boxmodels/2p/2pvolumevariables.hh
index 52391ab80b82605d9c05af62eae5289ddd974dea..8612933a7e4ad1a204ccd5deb2d18fe7f2a60262 100644
--- a/dumux/boxmodels/2p/2pvolumevariables.hh
+++ b/dumux/boxmodels/2p/2pvolumevariables.hh
@@ -56,8 +56,6 @@ class TwoPVolumeVariables : public BoxVolumeVariables<TypeTag>
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(MaterialLawParams)) MaterialLawParams;
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(FVElementGeometry)) FVElementGeometry;
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(PrimaryVariables)) PrimaryVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, PTAG(ElementVariables)) ElementVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, PTAG(SpatialParameters)) SpatialParameters;
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(TwoPIndices)) Indices;
 
     enum {
@@ -91,26 +89,28 @@ public:
      * \param isOldSol Evaluate function with solution of current or previous time step
      */
     void update(const PrimaryVariables &priVars,
-                const ElementVariables &elemVars,
+                const Problem &problem,
+                const Element &element,
+                const FVElementGeometry &elemGeom,
                 int scvIdx,
-                int historyIdx)
+                bool isOldSol)
     {
         ParentType::update(priVars,
-                           elemVars,
+                           problem,
+                           element,
+                           elemGeom,
                            scvIdx,
-                           historyIdx);
+                           isOldSol);
 
         asImp().updateTemperature_(priVars,
-                                   elemVars,
+                                   element,
+                                   elemGeom,
                                    scvIdx,
-                                   historyIdx);
+                                   problem);
 
-        const SpatialParameters &spatialParams = 
-            elemVars.problem().spatialParameters();
-
-        // material law parameters       
+        // material law parameters
         const MaterialLawParams &materialParams =
-            spatialParams.materialLawParams(elemVars, scvIdx);
+            problem.spatialParameters().materialLawParams(element, elemGeom, scvIdx);
 
         Scalar p[numPhases];
         Scalar Sn;
@@ -147,7 +147,9 @@ public:
                                         fluidState_);
 
         // porosity
-        porosity_ = spatialParams.porosity(elemVars, scvIdx);
+        porosity_ = problem.spatialParameters().porosity(element,
+                                                         elemGeom,
+                                                         scvIdx);
     }
 
     /*!
@@ -216,12 +218,12 @@ public:
 
 protected:
     void updateTemperature_(const PrimaryVariables &priVars,
-                            const ElementVariables &elemVars,
+                            const Element &element,
+                            const FVElementGeometry &elemGeom,
                             int scvIdx,
-                            int historyIdx)
+                            const Problem &problem)
     {
-        temperature_ = 
-            elemVars.problem().temperature(elemVars, scvIdx);
+        temperature_ = problem.boxTemperature(element, elemGeom, scvIdx);
     }
 
     FluidState fluidState_;
diff --git a/dumux/boxmodels/common/boxassembler.hh b/dumux/boxmodels/common/boxassembler.hh
index ef31386e032977419c8bd9438fe49eddef70a7b5..045ad46f77fd5b9033efc95b492d44fb60eb403e 100644
--- a/dumux/boxmodels/common/boxassembler.hh
+++ b/dumux/boxmodels/common/boxassembler.hh
@@ -113,6 +113,9 @@ public:
 
     BoxAssembler()
     {
+        enableJacobianRecycling_ = GET_PARAM(TypeTag, bool, EnableJacobianRecycling);
+        enablePartialReassemble_ = GET_PARAM(TypeTag, bool, EnablePartialReassemble);
+
         problemPtr_ = 0;
         matrix_ = 0;
 
@@ -156,7 +159,7 @@ public:
         // initialize the storage part of the Jacobian matrix. Since
         // we only need this if Jacobian matrix recycling is enabled,
         // we do not waste space if it is disabled
-        if (enableJacobianRecycling_()) {
+        if (enableJacobianRecycling_) {
             storageJacobian_.resize(numVerts);
             storageTerm_.resize(numVerts);
         }
@@ -164,7 +167,7 @@ public:
         totalElems_ = gridView_().comm().sum(numElems);
 
         // initialize data needed for partial reassembly
-        if (enablePartialReassemble_()) {
+        if (enablePartialReassemble_) {
             vertexColor_.resize(numVerts);
             vertexDelta_.resize(numVerts);
             elementColor_.resize(numElems);
@@ -173,14 +176,14 @@ public:
     }
 
     /*!
-     * \brief Assemble the global Jacobian of the residual and the residual for the current solution.
+     * \brief Assemble the local jacobian of the problem.
      *
      * The current state of affairs (esp. the previous and the current
      * solutions) is represented by the model object.
      */
     void assemble()
     {
-        bool printReassembleStatistics = enablePartialReassemble_() && !reuseMatrix_;
+        bool printReassembleStatistics = enablePartialReassemble_ && !reuseMatrix_;
         int succeeded;
         try {
             assemble_();
@@ -228,7 +231,7 @@ public:
      */
     void setMatrixReuseable(bool yesno = true)
     {
-        if (enableJacobianRecycling_())
+        if (enableJacobianRecycling_)
             reuseMatrix_ = yesno;
     }
 
@@ -244,7 +247,7 @@ public:
 
         // do not use partial reassembly for the next iteration
         nextReassembleAccuracy_ = 0.0;
-        if (enablePartialReassemble_()) {
+        if (enablePartialReassemble_) {
             std::fill(vertexColor_.begin(),
                       vertexColor_.end(),
                       Red);
@@ -280,7 +283,7 @@ public:
     void updateDiscrepancy(const SolutionVector &u,
                            const SolutionVector &uDelta)
     {
-        if (!enablePartialReassemble_())
+        if (!enablePartialReassemble_)
             return;
 
         // update the vector with the distances of the current
@@ -339,7 +342,7 @@ public:
      */
     void computeColors(Scalar relTol)
     {
-        if (!enablePartialReassemble_())
+        if (!enablePartialReassemble_)
             return;
 
         ElementIterator elemIt = gridView_().template begin<0>();
@@ -483,7 +486,7 @@ public:
      */
     int vertexColor(const Element &element, int vertIdx) const
     {
-        if (!enablePartialReassemble_())
+        if (!enablePartialReassemble_)
             return Red; // reassemble unconditionally!
 
         int globalIdx = vertexMapper_().map(element, vertIdx, dim);
@@ -497,7 +500,7 @@ public:
      */
     int vertexColor(int globalVertIdx) const
     {
-        if (!enablePartialReassemble_())
+        if (!enablePartialReassemble_)
             return Red; // reassemble unconditionally!
         return vertexColor_[globalVertIdx];
     }
@@ -509,7 +512,7 @@ public:
      */
     int elementColor(const Element &element) const
     {
-        if (!enablePartialReassemble_())
+        if (!enablePartialReassemble_)
             return Red; // reassemble unconditionally!
 
         int globalIdx = elementMapper_().map(element);
@@ -523,7 +526,7 @@ public:
      */
     int elementColor(int globalElementIdx) const
     {
-        if (!enablePartialReassemble_())
+        if (!enablePartialReassemble_)
             return Red; // reassemble unconditionally!
         return elementColor_[globalElementIdx];
     }
@@ -540,27 +543,8 @@ public:
     const SolutionVector& residual() const
     { return residual_; }
 
-private:
-    static bool enableJacobianRecycling_()
-    { return GET_PARAM(TypeTag, bool, EnableJacobianRecycling); }
-    static bool enablePartialReassemble_()
-    { return GET_PARAM(TypeTag, bool, EnablePartialReassemble); }
-
-    Problem &problem_()
-    { return *problemPtr_; }
-    const Problem &problem_() const
-    { return *problemPtr_; }
-    const Model &model_() const
-    { return problem_().model(); }
-    Model &model_()
-    { return problem_().model(); }
-    const GridView &gridView_() const
-    { return problem_().gridView(); }
-    const VertexMapper &vertexMapper_() const
-    { return problem_().vertexMapper(); }
-    const ElementMapper &elementMapper_() const
-    { return problem_().elementMapper(); }
 
+private:
     // Construct the BCRS matrix for the global jacobian
     void createMatrix_()
     {
@@ -639,7 +623,7 @@ private:
         // always reset the right hand side.
         residual_ = 0.0;
 
-        if (!enablePartialReassemble_()) {
+        if (!enablePartialReassemble_) {
             // If partial reassembly of the jacobian is not enabled,
             // we can just reset everything!
             (*matrix_) = 0;
@@ -756,20 +740,21 @@ private:
 
             residual_[globI] += model_().localJacobian().residual(i);
             if (enableJacobianRecycling_) {
-                // save storage term and its Jacobian in case we can
-                // reuse the current linearization...
+                // save the flux term and the jacobian of the
+                // storage term in case we can reuse the current
+                // linearization...
                 storageJacobian_[globI] +=
-                    model_().localJacobian().jacobianStorage(i);
+                    model_().localJacobian().storageJacobian(i);
 
                 storageTerm_[globI] +=
-                    model_().localJacobian().residualStorage(i);
+                    model_().localJacobian().storageTerm(i);
             }
 
             // update the jacobian matrix
             for (int j=0; j < numVertices; ++ j) {
                 int globJ = vertexMapper_().map(elem, j, dim);
                 (*matrix_)[globI][globJ] +=
-                    model_().localJacobian().jacobian(i, j);
+                    model_().localJacobian().mat(i,j);
             }
         }
     }
@@ -800,6 +785,22 @@ private:
         }
     }
 
+
+    Problem &problem_()
+    { return *problemPtr_; }
+    const Problem &problem_() const
+    { return *problemPtr_; }
+    const Model &model_() const
+    { return problem_().model(); }
+    Model &model_()
+    { return problem_().model(); }
+    const GridView &gridView_() const
+    { return problem_().gridView(); }
+    const VertexMapper &vertexMapper_() const
+    { return problem_().vertexMapper(); }
+    const ElementMapper &elementMapper_() const
+    { return problem_().elementMapper(); }
+
     Problem *problemPtr_;
 
     // the jacobian matrix
@@ -826,6 +827,9 @@ private:
 
     Scalar nextReassembleAccuracy_;
     Scalar reassembleAccuracy_;
+
+    bool enableJacobianRecycling_;
+    bool enablePartialReassemble_;
 };
 
 } // namespace Dumux
diff --git a/dumux/boxmodels/common/boxelementvolumevariables.hh b/dumux/boxmodels/common/boxelementvolumevariables.hh
index 63ac9daf88d3e2406c314304cf51db6e79da28a6..8e692ab0d072b8e8e4d6446f7f3ac915241082a6 100644
--- a/dumux/boxmodels/common/boxelementvolumevariables.hh
+++ b/dumux/boxmodels/common/boxelementvolumevariables.hh
@@ -1,5 +1,5 @@
 /*****************************************************************************
- *   Copyright (C) 2010-2011 by Andreas Lauser                               *
+ *   Copyright (C) 2010 by Andreas Lauser                                    *
  *   Institute of Hydraulic Engineering                                      *
  *   University of Stuttgart, Germany                                        *
  *   email: <givenname>.<name>@iws.uni-stuttgart.de                          *
@@ -22,8 +22,8 @@
  *
  * \brief Volume variables gathered on an element
  */
-#ifndef DUMUX_BOX_ELEMENT_VARIABLES_HH
-#define DUMUX_BOX_ELEMENT_VARIABLES_HH
+#ifndef DUMUX_BOX_ELEMENT_VOLUME_VARIABLES_HH
+#define DUMUX_BOX_ELEMENT_VOLUME_VARIABLES_HH
 
 #include "boxproperties.hh"
 
@@ -38,28 +38,16 @@ namespace Dumux
  *        volume variables object for each of the element's vertices
  */
 template<class TypeTag>
-class BoxElementVariables
+class BoxElementVolumeVariables : public std::vector<typename GET_PROP_TYPE(TypeTag, PTAG(VolumeVariables)) >
 {
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(VolumeVariables)) VolumeVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, PTAG(FluxVariables)) FluxVariables;
-
-    // the history size of the time discretization in number of steps
-    enum { timeDiscHistorySize = GET_PROP_VALUE(TypeTag, PTAG(TimeDiscHistorySize)) };
-
-    struct ScvStore_ {
-        VolumeVariables volVars[timeDiscHistorySize];
-        VolumeVariables bcTypes;
-    };
-    typedef std::vector<ScvStore_> ScvVarsVector;
-    typedef std::vector<FluxVariables> ScvfVarsVector;
+    typedef std::vector<VolumeVariables> ParentType;
 
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(Scalar)) Scalar;
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(Problem)) Problem;
-    typedef typename GET_PROP_TYPE(TypeTag, PTAG(Model)) Model;
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(FVElementGeometry)) FVElementGeometry;
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(SolutionVector)) SolutionVector;
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(VertexMapper)) VertexMapper;
-    typedef typename GET_PROP_TYPE(TypeTag, PTAG(BoundaryTypes)) BoundaryTypes;
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(PrimaryVariables)) PrimaryVariables;
 
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(GridView)) GridView;
@@ -69,107 +57,47 @@ class BoxElementVariables
     enum { dim = GridView::dimension };
     enum { numEq = GET_PROP_VALUE(TypeTag, PTAG(NumEq)) };
 
-    typedef Dune::FieldVector<Scalar, dim> GlobalPosition;
-
 public:
     /*!
      * \brief The constructor.
      */
-    explicit BoxElementVariables(const Problem &problem)
-        : gridView_(problem.gridView())
-    {
-        // remember the problem object
-        problemPtr_ = &problem;
-        modelPtr_ = &problem.model();
-    }
+    BoxElementVolumeVariables()
+    { }
 
     /*!
-     * \brief Construct the volume variables of an element from scratch.
+     * \brief Construct the volume variables for all of vertices of an element.
      *
      * \param problem The problem which needs to be simulated.
      * \param element The DUNE Codim<0> entity for which the volume variables ought to be calculated
+     * \param fvElemGeom The finite volume geometry of the element
+     * \param oldSol Tells whether the model's previous or current solution should be used.
      */
-    void updateAll(const Element &elem)
-    {
-        updateFVElemGeom(elem);
-        updateBoundaryTypes();
-        updateAllScvVars();
-        updateAllScvfVars();
-    }
-
-    void updateFVElemGeom(const Element &elem)
-    {
-        // remember the current element
-        elemPtr_ = &elem;
-
-        // update the finite element geometry
-        fvElemGeom_.update(gridView_, elem);
-    }
-
-    void updateBoundaryTypes()
+    void update(const Problem &problem,
+                const Element &element,
+                const FVElementGeometry &fvElemGeom,
+                bool oldSol)
     {
-        // resize the SCV and the SCVF arrays
-        if (fvElemGeom_.numVertices > scvVars_.size()) {
-            scvVars_.resize(fvElemGeom_.numVertices);
-            boundaryTypes_.resize(fvElemGeom_.numVertices);
+        const SolutionVector &globalSol =
+            oldSol?
+            problem.model().prevSol():
+            problem.model().curSol();
+        const VertexMapper &vertexMapper = problem.vertexMapper();
+        // we assert that the i-th shape function is
+        // associated to the i-th vert of the element.
+        int n = element.template count<dim>();
+        this->resize(n);
+        for (int i = 0; i < n; i++) {
+            const PrimaryVariables &solI
+                = globalSol[vertexMapper.map(element, i, dim)];
+            (*this)[i].update(solI,
+                              problem,
+                              element,
+                              fvElemGeom,
+                              i,
+                              oldSol);
         }
-        if (fvElemGeom_.numEdges > scvfVars_.size())
-            scvfVars_.resize(fvElemGeom_.numEdges);
-
-        // fill the boundary types stuff
-        hasNeumann_ = false;
-        hasDirichlet_ = false;
-        for (int scvIdx = 0; scvIdx < numScv(); ++scvIdx) {
-            int globalIdx = model().vertexMapper().map(element(), scvIdx, dim);
-            boundaryTypes_[scvIdx] = model().boundaryTypes(globalIdx);
-            hasDirichlet_ = hasDirichlet_ || boundaryTypes_[scvIdx]->hasDirichlet();
-            hasNeumann_ = hasNeumann_ || boundaryTypes_[scvIdx]->hasNeumann();
-        }
-
-        // set the default evaluation points
-        scvIdxSaved_ = -1;
-        scvfVarsEval_ = &scvfVars_;
-    }
-
-    void updateAllScvVars()
-    {
-        for (int historyIdx = 0; historyIdx < timeDiscHistorySize; ++ historyIdx)
-            updateScvVars(historyIdx);
     };
 
-    void updateScvVars(int historyIdx)
-    {
-        // update the volume variables for the whole history
-        const VertexMapper &vertexMapper = problem().vertexMapper();
-        const SolutionVector &globalSol = model().solution(historyIdx);
-
-        // set the hints for the volume variables
-        model().setHints(*this, historyIdx);
-
-        int nScv = numScv();
-        for (int scvIdx = 0; scvIdx < nScv; scvIdx++) {
-            const PrimaryVariables &scvSol
-                = globalSol[vertexMapper.map(element(), scvIdx, dim)];
-            updateScvVars(scvSol, scvIdx, historyIdx);
-        }
-    };
-
-    void updateScvVars(const PrimaryVariables &priVars, int scvIdx, int historyIdx)
-    {
-        scvVars_[scvIdx].volVars[historyIdx].update(priVars,
-                                                    /*context=*/*this,
-                                                    scvIdx,
-                                                    historyIdx);
-    }
-
-    void updateAllScvfVars()
-    {
-        for (int scvfIdx = 0; scvfIdx < numScvf(); scvfIdx++) {
-            scvfVars_[scvfIdx].update(/*context=*/ *this,
-                                      /*localIndex=*/scvfIdx);
-        }
-    }
-
     /*!
      * \brief Construct the volume variables for all of vertices of an
      *        element given a solution vector computed by PDELab.
@@ -184,216 +112,27 @@ public:
      * \param elementSolVector The local solution for the element using PDELab ordering
      */
     template<typename ElemSolVectorType>
-    void updatePDELab(const Element &element,
-                      const ElemSolVectorType &elementSolVector)
+    void updatePDELab(const Problem &problem,
+                      const Element &element,
+                      const FVElementGeometry &fvElemGeom,
+                      const ElemSolVectorType& elementSolVector)
     {
-        updateFVElemGeom(element);
-        updateBoundaryTypes(element);
-
-        // update the current time step's volume variables
-        PrimaryVariables scvSol;
-        for (int scvIdx = 0; scvIdx < numScv(); scvIdx++)
+        int n = element.template count<dim>();
+        this->resize(n);
+        for (int vertexIdx = 0; vertexIdx < n; vertexIdx++)
         {
-            // reorder the solution
-            for (int eqnIdx = 0; eqnIdx < numEq; eqnIdx++)
-                scvSol[eqnIdx] = elementSolVector[scvIdx + eqnIdx*numScv()];
+            PrimaryVariables solI(0);
+            for (int eqnIdx=0; eqnIdx<numEq; eqnIdx++)
+                solI[eqnIdx] = elementSolVector[vertexIdx + eqnIdx*n];
+            (*this)[vertexIdx].update(solI,
+                                      problem,
+                                      element,
+                                      fvElemGeom,
+                                      vertexIdx,
+                                      false);
 
-            // update the volume variables for the newest history index
-            updateScvVars_(scvSol, /*historyIdx=*/0, scvIdx);
         }
     };
-
-    /*!
-     * \brief Return a reference to the problem.
-     */
-    const Problem &problem() const
-    { return *problemPtr_; }
-
-    /*!
-     * \brief Return a reference to the model.
-     */
-    const Model &model() const
-    { return *modelPtr_; }
-
-    /*!
-     * \brief Return a reference to the grid view.
-     */
-    const GridView &gridView() const
-    { return gridView_; }
-
-    /*!
-     * \brief Return the current element.
-     */
-    const Element &element() const
-    { return *elemPtr_; }
-
-    /*!
-     * \brief Return the number of sub-control volumes of the current element.
-     */
-    int numScv() const
-    { return fvElemGeom_.numVertices; }
-
-    /*!
-     * \brief Return the number of sub-control volume faces of the current element.
-     */
-    int numScvf() const
-    { return fvElemGeom_.numEdges; }
-
-    /*!
-     * \brief Return the current finite element geometry.
-     */
-    const FVElementGeometry &fvElemGeom() const
-    { return fvElemGeom_; }
-
-    /*!
-     * \brief Return the position of a local entities in global coordinates
-     */
-    const GlobalPosition &pos(int scvIdx) const
-    { return fvElemGeom_.subContVol[scvIdx].global; }
-
-    /*!
-     * \brief Returns whether the current element is on the domain's
-     *        boundary.
-     */
-    bool onBoundary() const
-    { return hasNeumann_ || hasDirichlet_; };
-
-    /*!
-     * \brief Returns whether the current element has a Neumann boundary segment.
-     */
-    bool hasNeumann() const
-    { return hasNeumann_; };
-
-    /*!
-     * \brief Returns whether the current element has a Dirichlet vertex
-     */
-    bool hasDirichlet() const
-    { return hasDirichlet_; };
-
-    /*!
-     * \brief Returns the boundary types for a given vertex
-     */
-    const BoundaryTypes &boundaryTypes(int scvIdx) const
-    {
-        return *boundaryTypes_[scvIdx];
-    }
-
-    /*!
-     * \brief Save the current flux variables and use them as the
-     *        evaluation point.
-     */
-    void saveScvfVars()
-    {
-        scvfVarsSaved_ = scvfVars_;
-
-        // change evaluation point
-        scvfVarsEval_ = &scvfVarsSaved_;
-    }
-
-    /*!
-     * \brief Restore current flux variables from the saved ones.
-     */
-    void restoreScvfVars()
-    {
-        //scvfVarsSaved_ = scvfVars_; // not needed
-
-        // change evaluation point
-        scvfVarsEval_ = &scvfVars_;
-    }
-
-    /*!
-     * \brief Return a reference to the volume variables of a
-     *        sub-control volume at a given time.
-     *
-     * If the time step index is not given, return the volume
-     * variables for the current time. 
-     *
-     * \param scvIdx The local index of the sub-control volume for
-     *               which the volume variables are requested
-     * \param historyIdx The index of the time step for which the 
-     *                    volume variables are requested. 0 means 
-     *                    current time step, 1 previous time step,
-     *                    2 next-to-previous, etc.
-     */
-    const VolumeVariables &volVars(int scvIdx, int historyIdx = 0) const
-    { return scvVars_[scvIdx].volVars[historyIdx]; }
-
-    /*!
-     * \copydoc volVars()
-     */
-    VolumeVariables &volVars(int scvIdx, int historyIdx = 0)
-    { return scvVars_[scvIdx].volVars[historyIdx]; }
-
-    /*!
-     * \brief Returns the volume variables at the evaluation point.
-     */
-    void saveScvVars(int scvIdx)
-    { 
-        scvIdxSaved_ = scvIdx;
-        scvVarsSaved_ = scvVars_[scvIdx].volVars[/*historyIdx=*/0];
-    }
-
-    /*!
-     * \brief Restores the volume variables at the evaluation point.
-     */
-    void restoreScvVars(int scvIdx)
-    { 
-        scvIdxSaved_ = -1;
-        scvVars_[scvIdx].volVars[/*historyIdx=*/0] = scvVarsSaved_;
-    }
-
-    /*!
-     * \brief Return a reference to the flux variables of a
-     *        sub-control volume face.
-     *
-     * \param scvfIdx The local index of the sub-control volume face for
-     *               which the flux variables are requested
-     */
-    const FluxVariables &fluxVars(int scvIdx) const
-    { return scvfVars_[scvIdx]; }
-
-    /*!
-     * \brief Return a reference to the flux variables of a
-     *        sub-control volume face for the evaluation point.
-     *
-     * \param scvfIdx The local index of the sub-control volume face for
-     *               which the flux variables are requested
-     */
-    const FluxVariables &evalPointFluxVars(int scvfIdx) const
-    { 
-        return (*scvfVarsEval_)[scvfIdx];
-    }
-
-    /*!
-     * \brief Returns the volume variables for history index 0 at the
-     *        evaluation point.
-     */
-    const VolumeVariables &evalPointVolVars(int scvIdx) const
-    { 
-        if (scvIdxSaved_ == scvIdx)
-            return scvVarsSaved_;
-        return volVars(scvIdx, /*historyIdx=*/0);
-    }
-
-protected:
-    ScvVarsVector scvVars_;  
-
-    int scvIdxSaved_;
-    VolumeVariables scvVarsSaved_;
-
-    ScvfVarsVector scvfVars_;
-    ScvfVarsVector scvfVarsSaved_;
-
-    ScvfVarsVector *scvfVarsEval_;
-
-    const Problem *problemPtr_;
-    const Model *modelPtr_;
-    const Element *elemPtr_;
-    const GridView gridView_;
-    FVElementGeometry fvElemGeom_;
-    bool hasNeumann_;
-    bool hasDirichlet_;
-    std::vector<const BoundaryTypes*> boundaryTypes_;
 };
 
 } // namespace Dumux
diff --git a/dumux/boxmodels/common/boxlocaljacobian.hh b/dumux/boxmodels/common/boxlocaljacobian.hh
index 05fee5964a1c63a6dcf78e22c55fb9cbb0720c4b..9ccf1ffed81e285d28b74674d5e9d9fcff0eeab8 100644
--- a/dumux/boxmodels/common/boxlocaljacobian.hh
+++ b/dumux/boxmodels/common/boxlocaljacobian.hh
@@ -30,7 +30,6 @@
 #ifndef DUMUX_BOX_LOCAL_JACOBIAN_HH
 #define DUMUX_BOX_LOCAL_JACOBIAN_HH
 
-#include <dune/istl/bvector.hh>
 #include <dune/istl/matrix.hh>
 
 #include "boxelementboundarytypes.hh"
@@ -78,12 +77,17 @@ private:
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(Problem)) Problem;
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(Model)) Model;
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(GridView)) GridView;
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(JacobianAssembler)) JacobianAssembler;
 
     enum {
         numEq = GET_PROP_VALUE(TypeTag, PTAG(NumEq)),
 
         dim = GridView::dimension,
         dimWorld = GridView::dimensionworld,
+
+        Red = JacobianAssembler::Red,
+        Yellow = JacobianAssembler::Yellow,
+        Green = JacobianAssembler::Green,
     };
 
 
@@ -109,30 +113,23 @@ private:
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(PrimaryVariables)) PrimaryVariables;
 
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(VolumeVariables)) VolumeVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, PTAG(ElementVariables)) ElementVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(ElementVolumeVariables)) ElementVolumeVariables;
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(ElementBoundaryTypes)) ElementBoundaryTypes;
 
     typedef Dune::FieldMatrix<Scalar, numEq, numEq> MatrixBlock;
     typedef Dune::Matrix<MatrixBlock> LocalBlockMatrix;
 
-    typedef Dune::FieldVector<Scalar, numEq> VectorBlock;
-    typedef Dune::BlockVector<VectorBlock> LocalBlockVector;
-    typedef Dune::BlockVector<MatrixBlock> LocalStorageMatrix;
-
     // copying a local jacobian is not a good idea
     BoxLocalJacobian(const BoxLocalJacobian &);
 
 public:
     BoxLocalJacobian()
-    { 
-        internalElemVars_ = 0;
-    }
-
-    ~BoxLocalJacobian()
     {
-        delete internalElemVars_;
+        numericDifferenceMethod_ = GET_PARAM(TypeTag, int, NumericDifferenceMethod);
+        Valgrind::SetUndefined(problemPtr_);
     }
 
+
     /*!
      * \brief Initialize the local Jacobian object.
      *
@@ -142,67 +139,140 @@ public:
      * \param prob The problem which we want to simulate.
      */
     void init(Problem &prob)
-    { 
+    {
         problemPtr_ = &prob;
-        modelPtr_ = &prob.model();
-        internalElemVars_ = new ElementVariables(prob);
+        localResidual_.init(prob);
+
+        // assume quadrilinears as elements with most vertices
+        A_.setSize(2<<dim, 2<<dim);
+        storageJacobian_.resize(2<<dim);
     }
 
     /*!
      * \brief Assemble an element's local Jacobian matrix of the
      *        defect.
      *
-     * This assembles the 'grad f(x^k)' and 'f(x^k)' part of the newton update
+     * \param element The DUNE Codim<0> entity which we look at.
      */
     void assemble(const Element &element)
     {
-        internalElemVars_->updateAll(element);
+        // set the current grid element and update the element's
+        // finite volume geometry
+        elemPtr_ = &element;
+        fvElemGeom_.update(gridView_(), element);
+        reset_();
+
+        bcTypes_.update(problem_(), elem_(), fvElemGeom_);
+
+        // this is pretty much a HACK because the internal state of
+        // the problem is not supposed to be changed during the
+        // evaluation of the residual. (Reasons: It is a violation of
+        // abstraction, makes everything more prone to errors and is
+        // not thread save.) The real solution are context objects!
+        problem_().updateCouplingParams(elem_());
+
+        // set the hints for the volume variables
+        model_().setHints(element, prevVolVars_, curVolVars_);
+
+        // update the secondary variables for the element at the last
+        // and the current time levels
+        prevVolVars_.update(problem_(),
+                            elem_(),
+                            fvElemGeom_,
+                            true /* isOldSol? */);
+
+        curVolVars_.update(problem_(),
+                           elem_(),
+                           fvElemGeom_,
+                           false /* isOldSol? */);
+
+        // update the hints of the model
+        model_().updateCurHints(element, curVolVars_);
 
-        assemble(*internalElemVars_);
-    }
-
-    /*!
-     * \brief Assemble an element's local Jacobian matrix of the
-     *        defect, given all secondary variables for the element.
-     *
-     * After calling this method the ElementVariables are in undefined
-     * state, so do not use it anymore!
-     */
-    void assemble(ElementVariables &elemVars)
-    {        
-        // update the weights of the primary variables using the
-        // current element variables
-        model_().updatePVWeights(elemVars);
-        
-        resize_(elemVars);
-        reset_(elemVars);
-       
         // calculate the local residual
-        localResidual_.eval(residual_, residualStorage_, elemVars);
+        localResidual().eval(elem_(),
+                             fvElemGeom_,
+                             prevVolVars_,
+                             curVolVars_,
+                             bcTypes_);
+        residual_ = localResidual().residual();
+        storageTerm_ = localResidual().storageTerm();
 
-        // save all flux variables calculated using the unmodified
-        // primary variables. This automatically makes these flux
-        // variables the evaluation point.
-        elemVars.saveScvfVars();
+        model_().updatePVWeights(elem_(), curVolVars_);
 
         // calculate the local jacobian matrix
-        int numScv = elemVars.numScv();
-        for (int scvIdx = 0; scvIdx < numScv; scvIdx++) {
+        int numVertices = fvElemGeom_.numVertices;
+        ElementSolutionVector partialDeriv(numVertices);
+        PrimaryVariables storageDeriv;
+        for (int j = 0; j < numVertices; j++) {
             for (int pvIdx = 0; pvIdx < numEq; pvIdx++) {
-                asImp_().evalPartialDerivative_(elemVars,
-                                                scvIdx,
+                asImp_().evalPartialDerivative_(partialDeriv,
+                                                storageDeriv,
+                                                j,
                                                 pvIdx);
 
-                // update the local stiffness matrix with the current
-                // partial derivatives
-                updateLocalJacobian_(elemVars, scvIdx, pvIdx);
+                // update the local stiffness matrix with the current partial
+                // derivatives
+                updateLocalJacobian_(j,
+                                     pvIdx,
+                                     partialDeriv,
+                                     storageDeriv);
             }
         }
-
-        // restore flux variables. 
-        //elemVars.restoreScvfVars(); // not necessary
     }
 
+    /*!
+     * \brief Returns a reference to the object which calculates the
+     *        local residual.
+     */
+    const LocalResidual &localResidual() const
+    { return localResidual_; }
+
+    /*!
+     * \brief Returns a reference to the object which calculates the
+     *        local residual.
+     */
+    LocalResidual &localResidual()
+    { return localResidual_; }
+
+    /*!
+     * \brief Returns the Jacobian of the equations at vertex i to the
+     *        primary variables at vertex j.
+     *
+     * \param i The local vertex (or sub-control volume) index on which
+     *          the equations are defined
+     * \param j The local vertex (or sub-control volume) index which holds
+     *          primary variables
+     */
+    const MatrixBlock &mat(int i, int j) const
+    { return A_[i][j]; }
+
+    /*!
+     * \brief Returns the Jacobian of the storage term at vertex i.
+     *
+     * \param i The local vertex (or sub-control volume) index
+     */
+    const MatrixBlock &storageJacobian(int i) const
+    { return storageJacobian_[i]; }
+
+    /*!
+     * \brief Returns the residual of the equations at vertex i.
+     *
+     * \param i The local vertex (or sub-control volume) index on which
+     *          the equations are defined
+     */
+    const PrimaryVariables &residual(int i) const
+    { return residual_[i]; }
+
+    /*!
+     * \brief Returns the storage term for vertex i.
+     *
+     * \param i The local vertex (or sub-control volume) index on which
+     *          the equations are defined
+     */
+    const PrimaryVariables &storageTerm(int i) const
+    { return storageTerm_[i]; }
+
     /*!
      * \brief Returns the epsilon value which is added and removed
      *        from the current solution.
@@ -211,8 +281,7 @@ public:
      *                   which the local derivative ought to be calculated.
      * \param pvIdx      The index of the primary variable which gets varied
      */
-    Scalar numericEpsilon(const ElementVariables &elemVars, 
-                          int scvIdx,
+    Scalar numericEpsilon(int scvIdx,
                           int pvIdx) const
     {
         // define the base epsilon as the geometric mean of 1 and the
@@ -222,102 +291,71 @@ public:
         static const Scalar baseEps 
             = Dumux::geometricMean<Scalar>(std::numeric_limits<Scalar>::epsilon(),
                                            1.0);
-        
+
         // the epsilon value used for the numeric differentiation is
         // now scaled by the absolute value of the primary variable...
-        Scalar pv = elemVars.volVars(scvIdx, /*historyIdx=*/0).primaryVar(pvIdx);
+        Scalar pv = this->curVolVars_[scvIdx].primaryVar(pvIdx);
         return baseEps*(std::abs(pv) + 1);
     }
 
-    /*!
-     * \brief Return reference to the local residual.
-     */
-    LocalResidual &localResidual()
-    { return localResidual_; }
-    const LocalResidual &localResidual() const
-    { return localResidual_; }
+protected:
+    Implementation &asImp_()
+    { return *static_cast<Implementation*>(this); }
+    const Implementation &asImp_() const
+    { return *static_cast<const Implementation*>(this); }
 
     /*!
-     * \brief Returns the local Jacobian matrix of the residual of a sub-control volume.
-     *
-     * \param domainScvIdx The local index of the sub control volume which contains the independents
-     * \param rangeScvIdx The local index of the sub control volume which contains the local residual
+     * \brief Returns a reference to the problem.
      */
-    const MatrixBlock &jacobian(int domainScvIdx, int rangeScvIdx) const
-    { return jacobian_[domainScvIdx][rangeScvIdx]; }
+    const Problem &problem_() const
+    {
+        Valgrind::CheckDefined(problemPtr_);
+        return *problemPtr_;
+    };
 
     /*!
-     * \brief Returns the local Jacobian matrix the storage term of a sub-control volume.
-     *
-     * \param scvIdx The local index of sub control volume
+     * \brief Returns a reference to the grid view.
      */
-    const MatrixBlock &jacobianStorage(int scvIdx) const
-    { return jacobianStorage_[scvIdx]; }
+    const GridView &gridView_() const
+    { return problem_().gridView(); }
 
     /*!
-     * \brief Returns the local residual of a sub-control volume.
-     *
-     * \param scvIdx The local index of the sub control volume
+     * \brief Returns a reference to the element.
      */
-    const VectorBlock &residual(int scvIdx) const
-    { return residual_[scvIdx]; }
+    const Element &elem_() const
+    {
+        Valgrind::CheckDefined(elemPtr_);
+        return *elemPtr_;
+    };
 
     /*!
-     * \brief Returns the local storage term of a sub-control volume.
-     *
-     * \param scvIdx The local index of the sub control volume
+     * \brief Returns a reference to the model.
      */
-    const VectorBlock &residualStorage(int scvIdx) const
-    { return residualStorage_[scvIdx]; }
-
-protected:
-    Implementation &asImp_()
-    { return *static_cast<Implementation*>(this); }
-    const Implementation &asImp_() const
-    { return *static_cast<const Implementation*>(this); }
-
-    const Problem &problem_() const
-    { return *problemPtr_; }
     const Model &model_() const
-    { return *modelPtr_; }
+    { return problem_().model(); };
 
     /*!
-     * \brief Returns the numeric difference method which is applied.
+     * \brief Returns a reference to the jacobian assembler.
      */
-    static int numericDifferenceMethod_() 
-    { return GET_PARAM(TypeTag, int, NumericDifferenceMethod); }
+    const JacobianAssembler &jacAsm_() const
+    { return model_().jacobianAssembler(); }
 
     /*!
-     * \brief Resize all internal attributes to the size of the
-     *        element.
+     * \brief Returns a reference to the vertex mapper.
      */
-    void resize_(const ElementVariables &elemVars)
-    {
-        int n = elemVars.numScv();
-
-        jacobian_.setSize(n, n);
-        jacobianStorage_.resize(n);
-        
-        residual_.resize(n);
-        residualStorage_.resize(n);
-        
-        derivResidual_.resize(n);
-        derivStorage_.resize(n);
-    };
+    const VertexMapper &vertexMapper_() const
+    { return problem_().vertexMapper(); };
 
     /*!
-     * \brief Reset the all relevant internal attributes to 0
+     * \brief Reset the local jacobian matrix to 0
      */
-    void reset_(const ElementVariables &elemVars)
+    void reset_()
     {
-        int numScv = elemVars.numScv();
-        for (int i = 0; i < numScv; ++ i) {
-            residual_[i] = 0.0;
-            residualStorage_[i] = 0.0;
-
-            jacobianStorage_[i] = 0.0;
-            for (int j = 0; j < numScv; ++ j) {
-                jacobian_[i][j] = 0.0;
+        int n = elem_().template count<dim>();
+        for (int i = 0; i < n; ++ i) {
+            storageJacobian_[i] = 0.0;
+            for (int j = 0; j < n; ++ j) {
+                A_[i][j] = 0.0;
             }
         }
     }
@@ -366,19 +404,21 @@ protected:
      *              for which the partial derivative ought to be
      *              calculated
      */
-    void evalPartialDerivative_(ElementVariables &elemVars,
+    void evalPartialDerivative_(ElementSolutionVector &dest,
+                                PrimaryVariables &destStorage,
                                 int scvIdx,
                                 int pvIdx)
     {
-        // save all quantities which depend on the specified primary
-        // variable at the given sub control volume
-        elemVars.saveScvVars(scvIdx);
+        int globalIdx = vertexMapper_().map(elem_(), scvIdx, dim);
+
+        PrimaryVariables priVars(model_().curSol()[globalIdx]);
+        VolumeVariables origVolVars(curVolVars_[scvIdx]);
 
-        PrimaryVariables priVars(elemVars.volVars(scvIdx, /*historyIdx=*/0).primaryVars());
-        Scalar eps = asImp_().numericEpsilon(elemVars, scvIdx, pvIdx);
+        curVolVars_[scvIdx].setEvalPoint(&origVolVars);
+        Scalar eps = asImp_().numericEpsilon(scvIdx, pvIdx);
         Scalar delta = 0;
 
-        if (numericDifferenceMethod_() >= 0) {
+        if (numericDifferenceMethod_ >= 0) {
             // we are not using backward differences, i.e. we need to
             // calculate f(x + \epsilon)
 
@@ -387,19 +427,32 @@ protected:
             delta += eps;
 
             // calculate the residual
-            elemVars.updateScvVars(priVars, scvIdx, /*historyIdx=*/0);
-            elemVars.updateAllScvfVars();
-            localResidual_.eval(derivResidual_, derivStorage_, elemVars);
+            curVolVars_[scvIdx].update(priVars,
+                                       problem_(),
+                                       elem_(),
+                                       fvElemGeom_,
+                                       scvIdx,
+                                       false);
+            localResidual().eval(elem_(),
+                                 fvElemGeom_,
+                                 prevVolVars_,
+                                 curVolVars_,
+                                 bcTypes_);
+
+            // store the residual and the storage term
+            dest = localResidual().residual();
+            destStorage = localResidual().storageTerm()[scvIdx];
         }
         else {
             // we are using backward differences, i.e. we don't need
             // to calculate f(x + \epsilon) and we can recycle the
             // (already calculated) residual f(x)
-            derivResidual_ = residual_;
-            derivStorage_[scvIdx] = residualStorage_[scvIdx];
+            dest = residual_;
+            destStorage = storageTerm_[scvIdx];
         }
 
-        if (numericDifferenceMethod_() <= 0) {
+
+        if (numericDifferenceMethod_ <= 0) {
             // we are not using forward differences, i.e. we don't
             // need to calculate f(x - \epsilon)
 
@@ -407,35 +460,40 @@ protected:
             priVars[pvIdx] -= delta + eps;
             delta += eps;
 
-            // calculate residual again, this time we use the local
-            // residual's internal storage.
-            elemVars.updateScvVars(priVars, scvIdx, /*historyIdx=*/0);
-            elemVars.updateAllScvfVars();
-            localResidual_.eval(elemVars);
-            
-            derivResidual_ -= localResidual_.residual();
-            derivStorage_[scvIdx] -= localResidual_.storageTerm()[scvIdx];
+            // calculate residual again
+            curVolVars_[scvIdx].update(priVars,
+                                       problem_(),
+                                       elem_(),
+                                       fvElemGeom_,
+                                       scvIdx,
+                                       false);
+            localResidual().eval(elem_(),
+                                 fvElemGeom_,
+                                 prevVolVars_,
+                                 curVolVars_,
+                                 bcTypes_);
+            dest -= localResidual().residual();
+            destStorage -= localResidual().storageTerm()[scvIdx];
         }
         else {
             // we are using forward differences, i.e. we don't need to
             // calculate f(x - \epsilon) and we can recycle the
             // (already calculated) residual f(x)
-            derivResidual_ -= residual_;
-            derivStorage_[scvIdx] -= residualStorage_[scvIdx];
+            dest -= residual_;
+            destStorage -= storageTerm_[scvIdx];
         }
 
         // divide difference in residuals by the magnitude of the
         // deflections between the two function evaluation
-        derivResidual_ /= delta;
-        derivStorage_[scvIdx] /= delta;
+        dest /= delta;
+        destStorage /= delta;
 
-        // restore the original state of the element's volume
-        // variables
-        elemVars.restoreScvVars(scvIdx);
+        // restore the original state of the element's volume variables
+        curVolVars_[scvIdx] = origVolVars;
 
-#ifndef NDEBUG
-        for (unsigned i = 0; i < derivResidual_.size(); ++i)
-            Valgrind::CheckDefined(derivResidual_[i]);
+#if HAVE_VALGRIND
+        for (unsigned i = 0; i < dest.size(); ++i)
+            Valgrind::CheckDefined(dest[i]);
 #endif
     }
 
@@ -444,44 +502,56 @@ protected:
      *        partial derivatives of all equations in regard to the
      *        primary variable 'pvIdx' at vertex 'scvIdx' .
      */
-    void updateLocalJacobian_(const ElementVariables &elemVars,
-                              int scvIdx,
-                              int pvIdx)
+    void updateLocalJacobian_(int scvIdx,
+                              int pvIdx,
+                              const ElementSolutionVector &deriv,
+                              const PrimaryVariables &storageDeriv)
     {
         // store the derivative of the storage term
         for (int eqIdx = 0; eqIdx < numEq; eqIdx++) {
-            jacobianStorage_[scvIdx][eqIdx][pvIdx] = derivStorage_[scvIdx][eqIdx];
+            storageJacobian_[scvIdx][eqIdx][pvIdx] = storageDeriv[eqIdx];
         }
 
-        int numScv = elemVars.numScv();
-        for (int eqScvIdx = 0; eqScvIdx < numScv; eqScvIdx++)
+        for (int i = 0; i < fvElemGeom_.numVertices; i++)
         {
+            if (jacAsm_().vertexColor(elem_(), i) == Green) {
+                // Green vertices are not to be changed!
+                continue;
+            }
+
             for (int eqIdx = 0; eqIdx < numEq; eqIdx++) {
-                // A[eqScvIdx][scvIdx][eqIdx][pvIdx] is the rate of
-                // change of the residual of equation 'eqIdx' at
-                // vertex 'eqScvIdx' depending on the primary variable
-                // 'pvIdx' at vertex 'scvIdx'.
-                jacobian_[eqScvIdx][scvIdx][eqIdx][pvIdx] = derivResidual_[eqScvIdx][eqIdx];
-                Valgrind::CheckDefined(jacobian_[eqScvIdx][scvIdx][eqIdx][pvIdx]);
+                // A[i][scvIdx][eqIdx][pvIdx] is the rate of change of
+                // the residual of equation 'eqIdx' at vertex 'i'
+                // depending on the primary variable 'pvIdx' at vertex
+                // 'scvIdx'.
+                this->A_[i][scvIdx][eqIdx][pvIdx] = deriv[i][eqIdx];
+                Valgrind::CheckDefined(this->A_[i][scvIdx][eqIdx][pvIdx]);
             }
         }
     }
 
+    const Element *elemPtr_;
+    FVElementGeometry fvElemGeom_;
+
+    ElementBoundaryTypes bcTypes_;
+
+    // The problem we would like to solve
     Problem *problemPtr_;
-    Model *modelPtr_;
 
-    ElementVariables *internalElemVars_;
+    // secondary variables at the previous and at the current time
+    // levels
+    ElementVolumeVariables prevVolVars_;
+    ElementVolumeVariables curVolVars_;
 
-    LocalBlockMatrix jacobian_;
-    LocalStorageMatrix jacobianStorage_;
+    LocalResidual localResidual_;
 
-    LocalBlockVector residual_;
-    LocalBlockVector residualStorage_;
+    LocalBlockMatrix A_;
+    std::vector<MatrixBlock> storageJacobian_;
 
-    LocalBlockVector derivResidual_;
-    LocalBlockVector derivStorage_;
+    ElementSolutionVector residual_;
+    ElementSolutionVector storageTerm_;
 
-    LocalResidual localResidual_;
+    int numericDifferenceMethod_;
 };
 }
 
diff --git a/dumux/boxmodels/common/boxlocalresidual.hh b/dumux/boxmodels/common/boxlocalresidual.hh
index b3176627521054f4dd00e5e3a041a1efc27dda12..d22a826c8fa3dc6143c212761b96aac1e6918a3c 100644
--- a/dumux/boxmodels/common/boxlocalresidual.hh
+++ b/dumux/boxmodels/common/boxlocalresidual.hh
@@ -25,7 +25,7 @@
 #ifndef DUMUX_BOX_LOCAL_RESIDUAL_HH
 #define DUMUX_BOX_LOCAL_RESIDUAL_HH
 
-#include <dune/istl/bvector.hh>
+#include <dune/istl/matrix.hh>
 #include <dune/grid/common/geometry.hh>
 
 #include <dumux/common/valgrind.hh>
@@ -47,33 +47,48 @@ class BoxLocalResidual
 private:
     typedef BoxLocalResidual<TypeTag> ThisType;
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(LocalResidual)) Implementation;
-
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(Problem)) Problem;
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(Model)) Model;
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(GridView)) GridView;
-    enum { dim = GridView::dimension };
+
+    enum {
+        numEq = GET_PROP_VALUE(TypeTag, PTAG(NumEq)),
+
+        dim = GridView::dimension,
+        dimWorld = GridView::dimensionworld
+    };
+
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(Scalar)) Scalar;
+    typedef typename GridView::Grid::ctype CoordScalar;
+
+    typedef Dune::FieldVector<Scalar, dim>  LocalPosition;
+    typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition;
+
     typedef typename GridView::template Codim<0>::Entity Element;
+    typedef typename GridView::template Codim<0>::Iterator ElementIterator;
     typedef typename GridView::template Codim<dim>::Entity Vertex;
     typedef typename GridView::template Codim<dim>::EntityPointer VertexPointer;
-    typedef typename GridView::ctype CoordScalar;
 
     typedef typename Dune::GenericReferenceElements<CoordScalar, dim> ReferenceElements;
     typedef typename Dune::GenericReferenceElement<CoordScalar, dim> ReferenceElement;
 
-    typedef typename GridView::Intersection Intersection;
     typedef typename GridView::IntersectionIterator IntersectionIterator;
     typedef typename Element::Geometry Geometry;
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(FVElementGeometry)) FVElementGeometry;
 
-    typedef typename GET_PROP_TYPE(TypeTag, PTAG(ElementVariables)) ElementVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, PTAG(Scalar)) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(VertexMapper)) VertexMapper;
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(ElementSolutionVector)) ElementSolutionVector;
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(PrimaryVariables)) PrimaryVariables;
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(BoundaryTypes)) BoundaryTypes;
-    enum { numEq = GET_PROP_VALUE(TypeTag, PTAG(NumEq)) };
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(ElementBoundaryTypes)) ElementBoundaryTypes;
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(VolumeVariables)) VolumeVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(ElementVolumeVariables)) ElementVolumeVariables;
+
+    typedef Dune::FieldMatrix<Scalar, numEq, numEq>  MatrixBlock;
+    typedef Dune::Matrix<MatrixBlock> LocalBlockMatrix;
 
-    typedef Dune::FieldVector<Scalar, numEq> VectorBlock;
-    typedef Dune::BlockVector<VectorBlock> LocalBlockVector;
-    
     // copying the local residual class is not a good idea
-    BoxLocalResidual(const BoxLocalResidual &)
-    {};
+    BoxLocalResidual(const BoxLocalResidual &);
 
 public:
     BoxLocalResidual()
@@ -82,217 +97,312 @@ public:
     ~BoxLocalResidual()
     { }
 
+    /*!
+     * \brief Initialize the local residual.
+     *
+     * This assumes that all objects of the simulation have been fully
+     * allocated but not necessarrily initialized completely.
+     *
+     * \param prob The representation of the physical problem to be
+     *             solved.
+     */
+    void init(Problem &prob)
+    { problemPtr_ = &prob; }
+
     /*!
      * \brief Compute the local residual, i.e. the deviation of the
-     *        conservation equations from zero and store the results
-     *        internally.
+     *        equations from zero.
      *
-     * The results can be requested afterwards using the residual()
-     * and storageTerm() methods.
+     * \param element The DUNE Codim<0> entity for which the residual
+     *                ought to be calculated
      */
-    void eval(const ElementVariables &elemVars)
+    void eval(const Element &element)
     {
-        int numScv = elemVars.numScv();
-        internalResidual_.resize(numScv);
-        internalStorageTerm_.resize(numScv);
-        eval(internalResidual_, internalStorageTerm_, elemVars);
-    };
-    
+        FVElementGeometry fvElemGeom;
+
+        fvElemGeom.update(gridView_(), element);
+        fvElemGeomPtr_ = &fvElemGeom;
+
+        ElementVolumeVariables volVarsPrev, volVarsCur;
+        // update the hints
+        model_().setHints(element, volVarsPrev, volVarsCur);
+
+        volVarsPrev.update(problem_(),
+                           element,
+                           fvElemGeom_(),
+                           true /* oldSol? */);
+        volVarsCur.update(problem_(),
+                          element,
+                          fvElemGeom_(),
+                          false /* oldSol? */);
+
+        ElementBoundaryTypes bcTypes;
+        bcTypes.update(problem_(), element, fvElemGeom_());
+
+        // this is pretty much a HACK because the internal state of
+        // the problem is not supposed to be changed during the
+        // evaluation of the residual. (Reasons: It is a violation of
+        // abstraction, makes everything more prone to errors and is
+        // not thread save.) The real solution are context objects!
+        problem_().updateCouplingParams(element);
+
+        asImp_().eval(element, fvElemGeom_(), volVarsPrev, volVarsCur, bcTypes);
+    }
     /*!
-     * \brief Return the result of the eval() call using internal
-     *        storage.
+     * \brief Compute the local residual, i.e. the deviation of the
+     *        equations from zero. Gets a solution vector computed by PDELab
+     *
+     * \param element The DUNE Codim<0> entity for which the residual
+     *                ought to be calculated
+     * \param elementSolVector The local solution for the element using PDELab ordering
      */
-    const LocalBlockVector &residual() const
-    { return internalResidual_; }
-    const VectorBlock &residual(int scvIdx) const
-    { return internalResidual_[scvIdx]; }
+    template<typename ElemSolVectorType>
+    void evalPDELab(const Element &element, const ElemSolVectorType& elementSolVector)
+    {
+        FVElementGeometry fvGeom;
+        fvGeom.update(gridView_(), element);
+        ElementVolumeVariables volVarsPrev, volVarsCur;
+        volVarsPrev.update(problem_(),
+                           element,
+                           fvGeom,
+                           true /* oldSol? */);
+        volVarsCur.updatePDELab(problem_(),
+                          element,
+                          fvGeom,
+                          elementSolVector);
+        ElementBoundaryTypes bcTypes;
+        bcTypes.update(problem_(), element, fvGeom);
+
+        // this is pretty much a HACK because the internal state of
+        // the problem is not supposed to be changed during the
+        // evaluation of the residual. (Reasons: It is a violation of
+        // abstraction, makes everything more prone to errors and is
+        // not thread save.) The real solution are context objects!
+        problem_().updateCouplingParams(element);
+
+        asImp_().eval(element, fvGeom, volVarsPrev, volVarsCur, bcTypes);
+    }
 
     /*!
-     * \brief Return the storage term calculated using the last call
-     *        to eval() using internal storage.
+     * \brief Compute the storage term for the current solution.
+     *
+     * This can be used to figure out how much of each conservation
+     * quantity is inside the element.
+     *
+     * \param element The DUNE Codim<0> entity for which the storage
+     *                term ought to be calculated
      */
-    const LocalBlockVector &storageTerm() const
-    { return internalStorageTerm_; }
-    const VectorBlock &storageTerm(int scvIdx) const
-    { return internalStorageTerm_[scvIdx]; }
-    
+    void evalStorage(const Element &element)
+    {
+        elemPtr_ = &element;
+
+        FVElementGeometry fvElemGeom;
+        fvElemGeom.update(gridView_(), element);
+        fvElemGeomPtr_ = &fvElemGeom;
+
+        ElementBoundaryTypes bcTypes;
+        bcTypes.update(problem_(), element, fvElemGeom_());
+        bcTypesPtr_ = &bcTypes;
+
+        // no previous volume variables!
+        prevVolVarsPtr_ = 0;
+
+        ElementVolumeVariables volVars;
+
+        // update the hints
+        model_().setHints(element, volVars);
+
+        // calculate volume current variables
+        volVars.update(problem_(), element, fvElemGeom_(), false);
+        curVolVarsPtr_ = &volVars;
+
+        asImp_().evalStorage_();
+    }
+
+    /*!
+     * \brief Compute the flux term for the current solution.
+     *
+     * \param element The DUNE Codim<0> entity for which the residual
+     *                ought to be calculated
+     * \param curVolVars The volume averaged variables for all
+     *                   sub-contol volumes of the element
+     */
+    void evalFluxes(const Element &element,
+                    const ElementVolumeVariables &curVolVars)
+    {
+        elemPtr_ = &element;
+
+        FVElementGeometry fvElemGeom;
+        fvElemGeom.update(gridView_(), element);
+        fvElemGeomPtr_ = &fvElemGeom;
+
+        ElementBoundaryTypes bcTypes;
+        bcTypes.update(problem_(), element, fvElemGeom_());
+
+        residual_.resize(fvElemGeom_().numVertices);
+        residual_ = 0;
+
+        bcTypesPtr_ = &bcTypes;
+        prevVolVarsPtr_ = 0;
+        curVolVarsPtr_ = &curVolVars;
+        asImp_().evalFluxes_();
+    }
+
     /*!
      * \brief Compute the local residual, i.e. the deviation of the
-     *        conservation equations from zero.
+     *        equations from zero.
      *
-     * \param residual Stores the residual vector
-     * \param storageTerm Stores the derivative of the storage term to time
-     * \param elemVars All the element's secondary variables required to calculate the local residual
+     * \param element The DUNE Codim<0> entity for which the residual
+     *                ought to be calculated
+     * \param fvGeom The finite-volume geometry of the element
+     * \param prevVolVars The volume averaged variables for all
+     *                   sub-contol volumes of the element at the previous
+     *                   time level
+     * \param curVolVars The volume averaged variables for all
+     *                   sub-contol volumes of the element at the current
+     *                   time level
+     * \param bcTypes The types of the boundary conditions for all
+     *                vertices of the element
      */
-    void eval(LocalBlockVector &residual,
-              LocalBlockVector &storageTerm,
-              const ElementVariables &elemVars) const
+    void eval(const Element &element,
+              const FVElementGeometry &fvGeom,
+              const ElementVolumeVariables &prevVolVars,
+              const ElementVolumeVariables &curVolVars,
+              const ElementBoundaryTypes &bcTypes)
     {
-        residual = 0.0;
-        storageTerm = 0.0;
+        //Valgrind::CheckDefined(fvGeom);
+        Valgrind::CheckDefined(prevVolVars);
+        Valgrind::CheckDefined(curVolVars);
 
-        // evaluate the flux terms
-        asImp_().evalFluxes(residual, elemVars);
+#if !defined NDEBUG && HAVE_VALGRIND
+        for (int i=0; i < fvGeom.numVertices; i++) {
+            prevVolVars[i].checkDefined();
+            curVolVars[i].checkDefined();
+        }
+#endif // HAVE_VALGRIND
+
+        elemPtr_ = &element;
+        fvElemGeomPtr_ = &fvGeom;
+        bcTypesPtr_ = &bcTypes;
+        prevVolVarsPtr_ = &prevVolVars;
+        curVolVarsPtr_ = &curVolVars;
+
+        // resize the vectors for all terms
+        int numVerts = fvElemGeom_().numVertices;
+        residual_.resize(numVerts);
+        storageTerm_.resize(numVerts);
+
+        residual_ = 0.0;
+        storageTerm_ = 0.0;
+
+        asImp_().evalFluxes_();
 
 #if !defined NDEBUG && HAVE_VALGRIND
-        for (int i=0; i < elemVars.fvElemGeom().numVertices; i++)
-            Valgrind::CheckDefined(residual[i]);
+        for (int i=0; i < fvElemGeom_().numVertices; i++)
+            Valgrind::CheckDefined(residual_[i]);
 #endif // HAVE_VALGRIND
 
-        // evaluate the storage and the source terms
-        asImp_().evalVolumeTerms_(residual, storageTerm, elemVars);
+        asImp_().evalVolumeTerms_();
 
 #if !defined NDEBUG && HAVE_VALGRIND
-        for (int i=0; i < elemVars.fvElemGeom().numVertices; i++) 
-            Valgrind::CheckDefined(residual[i]);
-#endif // !defined NDEBUG && HAVE_VALGRIND
+        for (int i=0; i < fvElemGeom_().numVertices; i++) {
+            Valgrind::CheckDefined(residual_[i]);
+        }
+#endif // HAVE_VALGRIND
 
         // evaluate the boundary conditions
-        asImp_().evalBoundary_(residual, storageTerm, elemVars);
+        asImp_().evalBoundary_();
 
 #if !defined NDEBUG && HAVE_VALGRIND
-        for (int i=0; i < elemVars.fvElemGeom().numVertices; i++)
-            Valgrind::CheckDefined(residual[i]);
+        for (int i=0; i < fvElemGeom_().numVertices; i++)
+            Valgrind::CheckDefined(residual_[i]);
 #endif // HAVE_VALGRIND
     }
 
     /*!
-     * \brief Calculate the amount of all conservation quantities
-     *        stored in all element's sub-control volumes for a given
-     *        history index.
-     *
-     * This is used to figure out how much of each conservation
-     * quantity is inside the element.
+     * \brief Returns the local residual for a given sub-control
+     *        volume of the element.
      */
-    void evalStorage(const ElementVariables &elemVars, 
-                     int historyIdx)
-    {
-        int numScv = elemVars.numScv();
-        internalStorageTerm_.resize(numScv);
-        evalStorage(internalStorageTerm_,
-                    elemVars,
-                    historyIdx);
-    }
+    const ElementSolutionVector &residual() const
+    { return residual_; }
 
     /*!
-     * \brief Calculate the amount of all conservation quantities
-     *        stored in all element's sub-control volumes for a given
-     *        history index.
+     * \brief Returns the local residual for a given sub-control
+     *        volume of the element.
      *
-     * This is used to figure out how much of each conservation
-     * quantity is inside the element.
+     * \param scvIdx The local index of the sub-control volume
+     *               (i.e. the element's local vertex index)
      */
-    void evalStorage(LocalBlockVector &storage,
-                     const ElementVariables &elemVars, 
-                     int historyIdx) const
-    {
-        // calculate the amount of conservation each quantity inside
-        // all sub control volumes
-        for (int scvIdx=0; scvIdx < elemVars.numScv(); scvIdx++)
-        {
-            storage[scvIdx] = 0.0;
-            asImp_().computeStorage(storage[scvIdx], 
-                                    elemVars,
-                                    scvIdx,
-                                    historyIdx);
-            storage[scvIdx] *= 
-                elemVars.fvElemGeom().subContVol[scvIdx].volume
-                * elemVars.volVars(scvIdx).extrusionFactor();
-        }
-    }
+    const PrimaryVariables &residual(int scvIdx) const
+    { return residual_[scvIdx]; }
 
     /*!
-     * \brief Add the flux term to a local residual.
+     * \brief Returns the storage term for all sub-control volumes of the
+     *        element.
      */
-    void evalFluxes(LocalBlockVector &residual,
-                    const ElementVariables &elemVars) const
-    {
-        PrimaryVariables flux;
-        
-        // calculate the mass flux over the sub-control volume faces
-        for (int scvfIdx = 0; 
-             scvfIdx < elemVars.fvElemGeom().numEdges;
-             scvfIdx++)
-        {
-            int i = elemVars.fvElemGeom().subContVolFace[scvfIdx].i;
-            int j = elemVars.fvElemGeom().subContVolFace[scvfIdx].j;
+    const ElementSolutionVector &storageTerm() const
+    { return storageTerm_; }
 
-            Valgrind::SetUndefined(flux);
-            asImp_().computeFlux(flux, /*context=*/elemVars, scvfIdx);
-            flux *= elemVars.fluxVars(scvfIdx).extrusionFactor();
-            Valgrind::CheckDefined(flux);
+protected:
+    Implementation &asImp_()
+    {
+      assert(static_cast<Implementation*>(this) != 0);
+      return *static_cast<Implementation*>(this);
+    }
 
-            // The balance equation for a finite volume is given by
-            //
-            // dStorage/dt = Flux + Source
-            //
-            // where the 'Flux' and the 'Source' terms represent the
-            // mass per second which _ENTER_ the finite
-            // volume. Re-arranging this, we get
-            //
-            // dStorage/dt - Source - Flux = 0
-            //
-            // Since the mass flux as calculated by computeFlux() goes
-            // _OUT_ of sub-control volume i and _INTO_ sub-control
-            // volume j, we need to add the flux to finite volume i
-            // and subtract it from finite volume j
-            residual[i] += flux;
-            residual[j] -= flux;
-        }
+    const Implementation &asImp_() const
+    {
+      assert(static_cast<const Implementation*>(this) != 0);
+      return *static_cast<const Implementation*>(this);
     }
 
-protected:
     /*!
-     * \brief Evaluate the boundary conditions of an element.
+     * \brief Evaluate the boundary conditions
+     *        of the current element.
      */
-    void evalBoundary_(LocalBlockVector &residual,
-                       LocalBlockVector &storageTerm,
-                       const ElementVariables &elemVars) const
+    void evalBoundary_()
     {
-        if (!elemVars.onBoundary()) {
-            return;
-        }
-        
-        if (elemVars.hasNeumann())
-            asImp_().evalNeumann_(residual, elemVars);
-        
-        if (elemVars.hasDirichlet())
-            asImp_().evalDirichlet_(residual, storageTerm, elemVars);
+        if (bcTypes_().hasNeumann())
+            asImp_().evalNeumann_();
+#if !defined NDEBUG && HAVE_VALGRIND
+        for (int i=0; i < fvElemGeom_().numVertices; i++)
+            Valgrind::CheckDefined(residual_[i]);
+#endif // HAVE_VALGRIND
+
+        if (bcTypes_().hasDirichlet())
+            asImp_().evalDirichlet_();
     }
 
     /*!
      * \brief Set the values of the Dirichlet boundary control volumes
      *        of the current element.
      */
-    void evalDirichlet_(LocalBlockVector &residual,
-                        LocalBlockVector &storageTerm,
-                        const ElementVariables &elemVars) const
+    void evalDirichlet_()
     {
         PrimaryVariables tmp(0);
-        for (int scvIdx = 0; scvIdx < elemVars.numScv(); ++scvIdx) {
-            const BoundaryTypes &bcTypes = elemVars.boundaryTypes(scvIdx);
-            if (!bcTypes.hasDirichlet())
+        for (int i = 0; i < fvElemGeom_().numVertices; ++i) {
+            const BoundaryTypes &bcTypes = bcTypes_(i);
+            if (! bcTypes.hasDirichlet())
                 continue;
-            
-            // ask the problem for the dirichlet values
-            asImp_().computeDirichlet_(tmp, elemVars, scvIdx);
 
-            const PrimaryVariables &priVars = 
-                elemVars.volVars(scvIdx).primaryVars();
+            // ask the problem for the dirichlet values
+            const VertexPointer vPtr = elem_().template subEntity<dim>(i);
+            asImp_().problem_().dirichlet(tmp, *vPtr);
 
             // set the dirichlet conditions
             for (int eqIdx = 0; eqIdx < numEq; ++eqIdx) {
                 if (!bcTypes.isDirichlet(eqIdx))
                     continue;
                 int pvIdx = bcTypes.eqToDirichletIndex(eqIdx);
-                
                 assert(0 <= pvIdx && pvIdx < numEq);
                 Valgrind::CheckDefined(pvIdx);
-                Valgrind::CheckDefined(priVars);
+                Valgrind::CheckDefined(curPrimaryVar_(i, pvIdx));
                 Valgrind::CheckDefined(tmp[pvIdx]);
 
-                residual[scvIdx][eqIdx] = priVars[pvIdx] - tmp[pvIdx];
-                storageTerm[scvIdx][eqIdx] = 0.0;
+                this->residual_[i][eqIdx] =
+                    curPrimaryVar_(i, pvIdx) - tmp[pvIdx];
+
+                this->storageTerm_[i][eqIdx] = 0.0;
             };
         };
     }
@@ -301,16 +411,13 @@ protected:
      * \brief Add all Neumann boundary conditions to the local
      *        residual.
      */
-    void evalNeumann_(LocalBlockVector &residual,
-                      const ElementVariables &elemVars) const
+    void evalNeumann_()
     {
-        const Element &elem = elemVars.element();
-        Dune::GeometryType geoType = elem.geometry().type();
+        Dune::GeometryType geoType = elem_().geometry().type();
         const ReferenceElement &refElem = ReferenceElements::general(geoType);
 
-        const GridView &gridView = elemVars.gridView();
-        IntersectionIterator isIt = gridView.ibegin(elem);
-        const IntersectionIterator &endIt = gridView.iend(elem);
+        IntersectionIterator isIt = gridView_().ibegin(elem_());
+        const IntersectionIterator &endIt = gridView_().iend(elem_());
         for (; isIt != endIt; ++isIt)
         {
             // handle only faces on the boundary
@@ -325,59 +432,112 @@ protected:
                  faceVertIdx < numFaceVerts;
                  ++faceVertIdx)
             {
-                int scvIdx = refElem.subEntity(/*entityIdx=*/faceIdx,
-                                               /*entityCodim=*/1,
-                                               /*subEntityIdx=*/faceVertIdx,
-                                               /*subEntityCodim=*/dim);
-                
+                int elemVertIdx = refElem.subEntity(faceIdx,
+                                                    1,
+                                                    faceVertIdx,
+                                                    dim);
+
                 int boundaryFaceIdx =
-                    elemVars.fvElemGeom().boundaryFaceIndex(faceIdx, faceVertIdx);
+                    fvElemGeom_().boundaryFaceIndex(faceIdx, faceVertIdx);
 
                 // add the residual of all vertices of the boundary
                 // segment
-                evalNeumannSegment_(residual,
-                                    elemVars,
-                                    *isIt,
-                                    scvIdx,
+                evalNeumannSegment_(isIt,
+                                    elemVertIdx,
                                     boundaryFaceIdx);
             }
         }
     }
 
-    void computeDirichlet_(PrimaryVariables &values, 
-                           const ElementVariables &elemVars,
-                           int scvIdx) const
-    { elemVars.problem().dirichlet(values, elemVars, scvIdx); }
-
-
     /*!
      * \brief Add Neumann boundary conditions for a single sub-control
      *        volume face to the local residual.
      */
-    void evalNeumannSegment_(LocalBlockVector &residual,
-                             const ElementVariables &elemVars,
-                             const Intersection &is,
+    void evalNeumannSegment_(const IntersectionIterator &isIt,
                              int scvIdx,
-                             int boundaryFaceIdx) const
+                             int boundaryFaceIdx)
     {
         // temporary vector to store the neumann boundary fluxes
-        const BoundaryTypes &bcTypes = elemVars.boundaryTypes(scvIdx);
-        PrimaryVariables values;
-        
+        PrimaryVariables values(0.0);
+        const BoundaryTypes &bcTypes = bcTypes_(scvIdx);
+
         // deal with neumann boundaries
         if (bcTypes.hasNeumann()) {
-            elemVars.problem().neumann(values,
-                                       elemVars,
-                                       is,
-                                       scvIdx,
-                                       boundaryFaceIdx);
-            Valgrind::CheckDefined(values);
-
+            problem_().boxSDNeumann(values,
+                                    elem_(),
+                                    fvElemGeom_(),
+                                    *isIt,
+                                    scvIdx,
+                                    boundaryFaceIdx,
+                                    curVolVars_());
+            if (!Valgrind::CheckDefined(values))
+                std::cerr << "undefined: " << values << "\n";
             values *= 
-                elemVars.fvElemGeom().boundaryFace[boundaryFaceIdx].area
-                * elemVars.volVars(scvIdx, /*historyIdx*/0).extrusionFactor();
+                fvElemGeom_().boundaryFace[boundaryFaceIdx].area
+                * curVolVars_(scvIdx).extrusionFactor();
             Valgrind::CheckDefined(values);
-            residual[scvIdx] += values;
+            residual_[scvIdx] += values;
+        }
+    }
+
+    /*!
+     * \brief Add the flux terms to the local residual of all
+     *        sub-control volumes of the current element.
+     */
+    void evalFluxes_()
+    {
+        // calculate the mass flux over the faces and subtract
+        // it from the local rates
+        for (int k = 0; k < fvElemGeom_().numEdges; k++)
+        {
+            int i = fvElemGeom_().subContVolFace[k].i;
+            int j = fvElemGeom_().subContVolFace[k].j;
+
+            PrimaryVariables flux;
+            Valgrind::SetUndefined(flux);
+            this->asImp_().computeFlux(flux, k);
+            Scalar extrusionFactor =
+                (curVolVars_(i).extrusionFactor()
+                 + curVolVars_(j).extrusionFactor())
+                / 2;
+            flux *= extrusionFactor;
+            Valgrind::CheckDefined(flux);
+
+            // The balance equation for a finite volume is:
+            //
+            // dStorage/dt = Flux + Source
+            //
+            // where the 'Flux' and the 'Source' terms represent the
+            // mass per second which _ENTER_ the finite
+            // volume. Re-arranging this, we get
+            //
+            // dStorage/dt - Source - Flux = 0
+            //
+            // Since the flux calculated by computeFlux() goes _OUT_
+            // of sub-control volume i and _INTO_ sub-control volume
+            // j, we need to add the flux to finite volume i and
+            // subtract it from finite volume j
+            residual_[i] += flux;
+            residual_[j] -= flux;
+        }
+    }
+
+    /*!
+     * \brief Set the local residual to the storage terms of all
+     *        sub-control volumes of the current element.
+     */
+    void evalStorage_()
+    {
+        storageTerm_.resize(fvElemGeom_().numVertices);
+        storageTerm_ = 0;
+
+        // calculate the amount of conservation each quantity inside
+        // all sub control volumes
+        for (int i=0; i < fvElemGeom_().numVertices; i++) {
+            this->asImp_().computeStorage(storageTerm_[i], i, /*isOldSol=*/false);
+            storageTerm_[i] *= 
+                fvElemGeom_().subContVol[i].volume
+                * curVolVars_(i).extrusionFactor();
         }
     }
 
@@ -386,17 +546,15 @@ protected:
      *        to the local residual of all sub-control volumes of the
      *        current element.
      */
-    void evalVolumeTerms_(LocalBlockVector &residual, 
-                          LocalBlockVector &storageTerm,
-                          const ElementVariables &elemVars) const
+    void evalVolumeTerms_()
     {
-        PrimaryVariables tmp, tmp2;
-
         // evaluate the volume terms (storage + source terms)
-        for (int scvIdx=0; scvIdx < elemVars.numScv(); scvIdx++)
+        for (int i=0; i < fvElemGeom_().numVertices; i++)
         {
             Scalar extrusionFactor =
-                elemVars.volVars(scvIdx, /*historyIdx=*/0).extrusionFactor();          
+                curVolVars_(i).extrusionFactor();
+
+            PrimaryVariables tmp(0);
 
             // mass balance within the element. this is the
             // $\frac{m}{\partial t}$ term if using implicit
@@ -404,51 +562,162 @@ protected:
             //
             // TODO (?): we might need a more explicit way for
             // doing the time discretization...
-            asImp_().computeStorage(tmp2, 
-                                    elemVars,
-                                    scvIdx, 
-                                    /*historyIdx=*/1);
-            asImp_().computeStorage(tmp, 
-                                    elemVars,
-                                    scvIdx,
-                                    /*historyIdx=*/0);
+            this->asImp_().computeStorage(storageTerm_[i], i, false);
+            this->asImp_().computeStorage(tmp, i, true);
 
-            tmp -= tmp2;
-            tmp *=
-                elemVars.fvElemGeom().subContVol[scvIdx].volume
-                / elemVars.problem().timeManager().timeStepSize()
+            storageTerm_[i] -= tmp;
+            storageTerm_[i] *=
+                fvElemGeom_().subContVol[i].volume
+                / problem_().timeManager().timeStepSize()
                 * extrusionFactor;
+            residual_[i] += storageTerm_[i];
 
-            storageTerm[scvIdx] += tmp;
-            residual[scvIdx] += tmp;
-            
-            // subtract the source term from the residual
-            asImp_().computeSource(tmp2, elemVars, scvIdx);
-            tmp2 *= elemVars.fvElemGeom().subContVol[scvIdx].volume * extrusionFactor;
-            residual[scvIdx] -= tmp2;
+            // subtract the source term from the local rate
+            this->asImp_().computeSource(tmp, i);
+            tmp *= fvElemGeom_().subContVol[i].volume * extrusionFactor;
+            residual_[i] -= tmp;
 
             // make sure that only defined quantities were used
             // to calculate the residual.
-            Valgrind::CheckDefined(storageTerm[scvIdx]);
-            Valgrind::CheckDefined(residual[scvIdx]);
+            Valgrind::CheckDefined(residual_[i]);
         }
     }
 
-private:
-    Implementation &asImp_()
+    /*!
+     * \brief Returns a reference to the problem.
+     */
+    const Problem &problem_() const
+    { return *problemPtr_; };
+
+    /*!
+     * \brief Returns a reference to the model.
+     */
+    const Model &model_() const
+    { return problem_().model(); };
+
+    /*!
+     * \brief Returns a reference to the vertex mapper.
+     */
+    const VertexMapper &vertexMapper_() const
+    { return problem_().vertexMapper(); };
+
+    /*!
+     * \brief Returns a reference to the grid view.
+     */
+    const GridView &gridView_() const
+    { return problem_().gridView(); }
+
+    /*!
+     * \brief Returns a reference to the current element.
+     */
+    const Element &elem_() const
     {
-      assert(static_cast<Implementation*>(this) != 0);
-      return *static_cast<Implementation*>(this);
+        Valgrind::CheckDefined(elemPtr_);
+        return *elemPtr_;
     }
 
-    const Implementation &asImp_() const
+    /*!
+     * \brief Returns a reference to the current element's finite
+     *        volume geometry.
+     */
+    const FVElementGeometry &fvElemGeom_() const
     {
-      assert(static_cast<const Implementation*>(this) != 0);
-      return *static_cast<const Implementation*>(this);
+        Valgrind::CheckDefined(fvElemGeomPtr_);
+        return *fvElemGeomPtr_;
+    }
+
+    /*!
+     * \brief Returns a reference to the primary variables of the i'th
+     *        sub-control volume of the current element.
+     */
+    const PrimaryVariables &curPrimaryVars_(int i) const
+    {
+        return curVolVars_(i).primaryVars();
+    }
+
+    /*!
+     * \brief Returns the j'th primary of the i'th sub-control volume
+     *        of the current element.
+     */
+    Scalar curPrimaryVar_(int i, int j) const
+    {
+        return curVolVars_(i).primaryVar(j);
+    }
+
+    /*!
+     * \brief Returns a reference to the current volume variables of
+     *        all sub-control volumes of the current element.
+     */
+    const ElementVolumeVariables &curVolVars_() const
+    {
+        Valgrind::CheckDefined(curVolVarsPtr_);
+        return *curVolVarsPtr_;
+    }
+
+    /*!
+     * \brief Returns a reference to the volume variables of the i-th
+     *        sub-control volume of the current element.
+     */
+    const VolumeVariables &curVolVars_(int i) const
+    {
+        return curVolVars_()[i];
+    }
+
+    /*!
+     * \brief Returns a reference to the previous time step's volume
+     *        variables of all sub-control volumes of the current
+     *        element.
+     */
+    const ElementVolumeVariables &prevVolVars_() const
+    {
+        Valgrind::CheckDefined(prevVolVarsPtr_);
+        return *prevVolVarsPtr_;
+    }
+
+    /*!
+     * \brief Returns a reference to the previous time step's volume
+     *        variables of the i-th sub-control volume of the current
+     *        element.
+     */
+    const VolumeVariables &prevVolVars_(int i) const
+    {
+        return prevVolVars_()[i];
+    }
+
+    /*!
+     * \brief Returns a reference to the boundary types of all
+     *        sub-control volumes of the current element.
+     */
+    const ElementBoundaryTypes &bcTypes_() const
+    {
+        Valgrind::CheckDefined(bcTypesPtr_);
+        return *bcTypesPtr_;
     }
 
-    LocalBlockVector internalResidual_;
-    LocalBlockVector internalStorageTerm_;
+    /*!
+     * \brief Returns a reference to the boundary types of the i-th
+     *        sub-control volume of the current element.
+     */
+    const BoundaryTypes &bcTypes_(int i) const
+    {
+        return bcTypes_()[i];
+    }
+
+protected:
+    ElementSolutionVector storageTerm_;
+    ElementSolutionVector residual_;
+
+    // The problem we would like to solve
+    Problem *problemPtr_;
+
+    const Element *elemPtr_;
+    const FVElementGeometry *fvElemGeomPtr_;
+
+    // current and previous secondary variables for the element
+    const ElementVolumeVariables *prevVolVarsPtr_;
+    const ElementVolumeVariables *curVolVarsPtr_;
+
+    const ElementBoundaryTypes *bcTypesPtr_;
 };
 
 }
diff --git a/dumux/boxmodels/common/boxmodel.hh b/dumux/boxmodels/common/boxmodel.hh
index bfc52156f2a649e628d9a8a89b6d155a824bfb66..63625996a3a98be237fab81f12b0bb6749bf8f40 100644
--- a/dumux/boxmodels/common/boxmodel.hh
+++ b/dumux/boxmodels/common/boxmodel.hh
@@ -72,18 +72,16 @@ class BoxModel
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(PrimaryVariables)) PrimaryVariables;
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(JacobianAssembler)) JacobianAssembler;
 
-    typedef typename GET_PROP_TYPE(TypeTag, PTAG(ElementVariables)) ElementVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(ElementVolumeVariables)) ElementVolumeVariables;
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(VolumeVariables)) VolumeVariables;
 
 
     enum {
         numEq = GET_PROP_VALUE(TypeTag, PTAG(NumEq)),
-        historySize = GET_PROP_VALUE(TypeTag, PTAG(TimeDiscHistorySize)),
         dim = GridView::dimension
     };
 
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(FVElementGeometry)) FVElementGeometry;
-    typedef typename GET_PROP_TYPE(TypeTag, PTAG(BoundaryTypes)) BoundaryTypes;
 
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(LocalJacobian)) LocalJacobian;
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(LocalResidual)) LocalResidual;
@@ -95,7 +93,6 @@ class BoxModel
     typedef typename GridView::template Codim<0>::Iterator ElementIterator;
     typedef typename GridView::IntersectionIterator IntersectionIterator;
     typedef typename GridView::template Codim<dim>::Entity Vertex;
-    typedef typename GridView::template Codim<dim>::EntityPointer VertexPointer;
     typedef typename GridView::template Codim<dim>::Iterator VertexIterator;
 
     typedef typename Dune::GenericReferenceElements<CoordScalar, dim> ReferenceElements;
@@ -109,7 +106,9 @@ public:
      * \brief The constructor.
      */
     BoxModel()
-    { }
+    {
+        enableHints_ = GET_PARAM(TypeTag, bool, EnableHints);
+    }
 
     ~BoxModel()
     { delete jacAsm_;  }
@@ -124,11 +123,9 @@ public:
     {
         problemPtr_ = &prob;
 
-        updateBoundaryTypes_();
-
         int nDofs = asImp_().numDofs();
-        for (int historyIdx = 0; historyIdx < historySize; ++historyIdx)
-            solution_[historyIdx].resize(nDofs);
+        uCur_.resize(nDofs);
+        uPrev_.resize(nDofs);
         boxVolume_.resize(nDofs);
 
         localJacobian_.init(problem_());
@@ -138,10 +135,10 @@ public:
         asImp_().applyInitialSolution_();
 
         // resize the hint vectors
-        if (enableHints_()) {
+        if (enableHints_) {
             int nVerts = gridView_().size(dim);
-            for (int historyIdx = 0; historyIdx < historySize; ++historyIdx)
-                hints_[historyIdx].resize(nVerts);
+            curHints_.resize(nVerts);
+            prevHints_.resize(nVerts);
             hintsUsable_.resize(nVerts);
             std::fill(hintsUsable_.begin(),
                       hintsUsable_.end(),
@@ -150,67 +147,74 @@ public:
 
         // also set the solution of the "previous" time step to the
         // initial solution.
-        solution_[/*historyIdx=*/1] = solution_[/*historyIdx=*/0];
+        uPrev_ = uCur_;
     }
 
-    void setAllHints(ElementVariables &elemVars) const
+    void setHints(const Element &elem,
+                  ElementVolumeVariables &prevVolVars,
+                  ElementVolumeVariables &curVolVars) const
     {
-        if (!enableHints_())
+        if (!enableHints_)
             return;
 
-        for (int historyIdx = 0; historyIdx < historySize; ++historyIdx)
-            setHints(elemVars, historyIdx);
-    }
+        int n = elem.template count<dim>();
+        prevVolVars.resize(n);
+        curVolVars.resize(n);
+        for (int i = 0; i < n; ++i) {
+            int globalIdx = vertexMapper().map(elem, i, dim);
+
+            if (!hintsUsable_[globalIdx]) {
+                curVolVars[i].setHint(NULL);
+                prevVolVars[i].setHint(NULL);
+            }
+            else {
+                curVolVars[i].setHint(&curHints_[globalIdx]);
+                prevVolVars[i].setHint(&prevHints_[globalIdx]);
+            }
+        }
+    };
 
-    void setHints(ElementVariables &elemVars, int historyIdx) const
+    void setHints(const Element &elem,
+                  ElementVolumeVariables &curVolVars) const
     {
-        if (!enableHints_())
+        if (!enableHints_)
             return;
 
-        int numScv = elemVars.numScv();
-        for (int scvIdx = 0; scvIdx < numScv; ++scvIdx) {
-            setHintsScv(elemVars, historyIdx, scvIdx);
-        }
-    }
+        int n = elem.template count<dim>();
+        curVolVars.resize(n);
+        for (int i = 0; i < n; ++i) {
+            int globalIdx = vertexMapper().map(elem, i, dim);
 
-    void setHintsScv(ElementVariables &elemVars, int historyIdx, int scvIdx) const
-    {
-        int globalIdx = vertexMapper().map(elemVars.element(), scvIdx, dim);
-        
-        if (!hintsUsable_[globalIdx])
-            elemVars.volVars(scvIdx, historyIdx).setHint(NULL);
-        else
-            elemVars.volVars(scvIdx, historyIdx)
-                .setHint(&hints_[historyIdx][globalIdx]);
+            if (!hintsUsable_[globalIdx])
+                curVolVars[i].setHint(NULL);
+            else
+                curVolVars[i].setHint(&curHints_[globalIdx]);
+        }
     };
 
-    void updateAllHints(const ElementVariables &elemVars) const
+    void updatePrevHints()
     {
-        if (!enableHints_())
+        if (!enableHints_)
             return;
 
-        for (int historyIdx = 0; historyIdx < historySize; ++historyIdx) {
-            updateHints(elemVars, historyIdx);
-        }
+        prevHints_ = curHints_;
     };
 
-    void updateHints(const ElementVariables &elemVars, int historyIdx) const
+    void updateCurHints(const Element &elem,
+                        const ElementVolumeVariables &ev) const
     {
-        if (!enableHints_())
+        if (!enableHints_)
             return;
-        
-        for (int scvIdx = 0; scvIdx < elemVars.numScv(); ++scvIdx) {
-            int globalIdx = vertexMapper().map(elemVars.element(), scvIdx, dim);
-            hints_[historyIdx][globalIdx] = elemVars.volVars(scvIdx, historyIdx);
+
+        for (int i = 0; i < ev.size(); ++i) {
+            int globalIdx = vertexMapper().map(elem, i, dim);
+            curHints_[globalIdx] = ev[i];
+            if (!hintsUsable_[globalIdx])
+                prevHints_[globalIdx] = ev[i];
             hintsUsable_[globalIdx] = true;
         }
     };
 
-    void shiftHints()
-    {
-        for (int historyIdx = 0; historyIdx < historySize - 1; ++ historyIdx)
-            hints_[historyIdx + 1] = hints_[historyIdx];
-    };
 
     /*!
      * \brief Compute the global residual for an arbitrary solution
@@ -222,10 +226,10 @@ public:
     Scalar globalResidual(SolutionVector &dest,
                           const SolutionVector &u)
     {
-        SolutionVector tmp(solution(/*historyIdx=*/0));
-        solution(/*historyIdx=*/0) = u;
+        SolutionVector tmp(curSol());
+        curSol() = u;
         Scalar res = globalResidual(dest);
-        solution(/*historyIdx=*/0) = tmp;
+        curSol() = tmp;
         return res;
     }
 
@@ -239,16 +243,14 @@ public:
     {
         dest = 0;
 
-        ElementVariables elemVars(this->problem_());
         ElementIterator elemIt = gridView_().template begin<0>();
         const ElementIterator elemEndIt = gridView_().template end<0>();
         for (; elemIt != elemEndIt; ++elemIt) {
-            elemVars.updateAll(*elemIt);
-            localResidual().eval(elemVars);
+            localResidual().eval(*elemIt);
 
-            for (int scvIdx = 0; scvIdx < elemVars.numScv(); ++scvIdx) {
-                int globalI = vertexMapper().map(*elemIt, scvIdx, dim);
-                dest[globalI] += localResidual().residual(scvIdx);
+            for (int i = 0; i < elemIt->template count<dim>(); ++i) {
+                int globalI = vertexMapper().map(*elemIt, i, dim);
+                dest[globalI] += localResidual().residual(i);
             }
         };
 
@@ -277,14 +279,11 @@ public:
     void globalStorage(PrimaryVariables &dest)
     {
         dest = 0;
-        
-        ElementVariables elemVars(this->problem_());
+
         ElementIterator elemIt = gridView_().template begin<0>();
         const ElementIterator elemEndIt = gridView_().template end<0>();
         for (; elemIt != elemEndIt; ++elemIt) {
-            elemVars.updateFVElemGeom(*elemIt);
-            elemVars.updateScvVars(/*historyIdx=*/0);
-            localResidual().evalStorage(elemVars, /*historyIdx=*/0);
+            localResidual().evalStorage(*elemIt);
 
             for (int i = 0; i < elemIt->template count<dim>(); ++i)
                 dest += localResidual().storageTerm()[i];
@@ -303,16 +302,28 @@ public:
     { return boxVolume_[globalIdx][0]; }
 
     /*!
-     * \brief Reference to the solution at a given history index as a block vector.
+     * \brief Reference to the current solution as a block vector.
+     */
+    const SolutionVector &curSol() const
+    { return uCur_; }
+
+    /*!
+     * \brief Reference to the current solution as a block vector.
+     */
+    SolutionVector &curSol()
+    { return uCur_; }
+
+    /*!
+     * \brief Reference to the previous solution as a block vector.
      */
-    const SolutionVector &solution(int historyIdx) const
-    { return solution_[historyIdx]; }
+    const SolutionVector &prevSol() const
+    { return uPrev_; }
 
     /*!
-     * \brief Reference to the solution at a given history index as a block vector.
+     * \brief Reference to the previous solution as a block vector.
      */
-    SolutionVector &solution(int historyIdx)
-    { return solution_[historyIdx]; }
+    SolutionVector &prevSol()
+    { return uPrev_; }
 
     /*!
      * \brief Returns the operator assembler for the global jacobian of
@@ -363,8 +374,7 @@ public:
      */
     Scalar primaryVarWeight(int vertIdx, int pvIdx) const
     {
-        Scalar absPv = std::abs(this->solution(/*historyIdx=*/1)[vertIdx][pvIdx]);
-        return 1.0/std::max(absPv, 1.0);
+        return 1.0/std::max(std::abs(this->prevSol()[vertIdx][pvIdx]), 1.0);
     }
 
     /*!
@@ -409,8 +419,8 @@ public:
                 NewtonController &controller)
     {
 #if HAVE_VALGRIND
-        for (size_t i = 0; i < solution(/*historyIdx=*/0).size(); ++i)
-            Valgrind::CheckDefined(solution(/*historyIdx=*/0)[i]);
+        for (size_t i = 0; i < curSol().size(); ++i)
+            Valgrind::CheckDefined(curSol()[i]);
 #endif // HAVE_VALGRIND
 
         asImp_().updateBegin();
@@ -423,8 +433,8 @@ public:
             asImp_().updateFailed();
 
 #if HAVE_VALGRIND
-        for (size_t i = 0; i < solution(/*historyIdx=*/0).size(); ++i) {
-            Valgrind::CheckDefined(solution(/*historyIdx=*/0)[i]);
+        for (size_t i = 0; i < curSol().size(); ++i) {
+            Valgrind::CheckDefined(curSol()[i]);
         }
 #endif // HAVE_VALGRIND
 
@@ -438,9 +448,7 @@ public:
      *        which the actual model can overload.
      */
     void updateBegin()
-    {
-        updateBoundaryTypes_();
-    }
+    { }
 
 
     /*!
@@ -461,7 +469,8 @@ public:
         // Reset the current solution to the one of the
         // previous time step so that we can start the next
         // update at a physically meaningful solution.
-        hints_[/*historyIdx=*/0] = hints_[/*historyIdx=*/1];
+        uCur_ = uPrev_;
+        curHints_ = prevHints_;
 
         jacAsm_->reassembleAll();
     };
@@ -476,10 +485,10 @@ public:
     void advanceTimeLevel()
     {
         // make the current solution the previous one.
-        solution_[/*historyIdx=*/1] = solution_[/*historyIdx=*/0];
+        uPrev_ = uCur_;
+        prevHints_ = curHints_;
 
-        // shift the hints by one position in the history
-        shiftHints();
+        updatePrevHints();
     }
 
     /*!
@@ -504,7 +513,7 @@ public:
     void deserialize(Restarter &res)
     {
         res.template deserializeEntities<dim>(asImp_(), this->gridView_());
-        solution_[/*historyIdx=*/1] = solution_[/*historyIdx=*/0];
+        prevSol() = curSol();
     }
 
     /*!
@@ -529,7 +538,7 @@ public:
         }
 
         for (int eqIdx = 0; eqIdx < numEq; ++eqIdx) {
-            outstream << solution_[/*historyIdx=*/0][vertIdx][eqIdx] << " ";
+            outstream << curSol()[vertIdx][eqIdx] << " ";
         }
     };
 
@@ -551,7 +560,7 @@ public:
                 DUNE_THROW(Dune::IOError,
                            "Could not deserialize vertex "
                            << vertIdx);
-            instream >> solution_[/*historyIdx=*/0][vertIdx][eqIdx];
+            instream >> curSol()[vertIdx][eqIdx];
         }
     };
 
@@ -593,19 +602,6 @@ public:
         jacAsm_->init(problem_());
     }
 
-    /*!
-     * \brief Return a pointer to the BoundaryTypes for a given global
-     *        vertex index or 0 if the vertex is not on the boundary.
-     */
-    const BoundaryTypes *boundaryTypes(int globalIdx) const
-    {
-        static BoundaryTypes dummy;
-        int bvertIdx = boundaryVertexIndex_[globalIdx];
-        if (bvertIdx < 0)
-            return &dummy;
-        return &boundaryTypes_[bvertIdx];
-    }
-
     /*!
      * \brief Update the weights of all primary variables within an
      *        element given the complete set of volume variables
@@ -613,7 +609,8 @@ public:
      * \param element The DUNE codim 0 entity
      * \param volVars All volume variables for the element
      */
-    void updatePVWeights(const ElementVariables &elemVars) const
+    void updatePVWeights(const Element &element,
+                         const ElementVolumeVariables &volVars) const
     { };
 
     /*!
@@ -644,11 +641,10 @@ public:
         ScalarField* def[numEq];
         ScalarField* delta[numEq];
         ScalarField* x[numEq];
-        ScalarField* relError = writer.allocateManagedBuffer(numVertices);
-        for (int pvIdx = 0; pvIdx < numEq; ++pvIdx) {
-            x[pvIdx] = writer.allocateManagedBuffer(numVertices);
-            delta[pvIdx] = writer.allocateManagedBuffer(numVertices);
-            def[pvIdx] = writer.allocateManagedBuffer(numVertices);
+        for (int i = 0; i < numEq; ++i) {
+            x[i] = writer.allocateManagedBuffer(numVertices);
+            delta[i] = writer.allocateManagedBuffer(numVertices);
+            def[i] = writer.allocateManagedBuffer(numVertices);
         }
 
         VertexIterator vIt = this->gridView_().template begin<dim>();
@@ -656,25 +652,17 @@ public:
         for (; vIt != vEndIt; ++ vIt)
         {
             int globalIdx = vertexMapper().map(*vIt);
-            for (int pvIdx = 0; pvIdx < numEq; ++pvIdx) {
-                (*x[pvIdx])[globalIdx] = u[globalIdx][pvIdx];
-                (*delta[pvIdx])[globalIdx] = 
-                    - deltaU[globalIdx][pvIdx];
-                (*def[pvIdx])[globalIdx] = globalResid[globalIdx][pvIdx];
+            for (int i = 0; i < numEq; ++i) {
+                (*x[i])[globalIdx] = u[globalIdx][i];
+                (*delta[i])[globalIdx] = - deltaU[globalIdx][i];
+                (*def[i])[globalIdx] = globalResid[globalIdx][i];
             }
-
-            PrimaryVariables uOld(u[globalIdx]);
-            PrimaryVariables uNew(uOld - deltaU[globalIdx]);
-            (*relError)[globalIdx] = asImp_().relativeErrorVertex(globalIdx, 
-                                                                  uOld,
-                                                                  uNew);
         }
 
-        writer.attachVertexData(*relError, "relative Error");
-        for (int pvIdx = 0; pvIdx < numEq; ++pvIdx) {
-            writer.attachVertexData(*x[pvIdx], (boost::format("x_%i")%pvIdx).str().c_str());
-            writer.attachVertexData(*delta[pvIdx], (boost::format("delta_%i")%pvIdx).str().c_str());
-            writer.attachVertexData(*def[pvIdx], (boost::format("defect_%i")%pvIdx).str().c_str());
+        for (int i = 0; i < numEq; ++i) {
+            writer.attachVertexData(*x[i], (boost::format("x_%i")%i).str().c_str());
+            writer.attachVertexData(*delta[i], (boost::format("delta_%i")%i).str().c_str());
+            writer.attachVertexData(*def[i], (boost::format("defect_%i")%i).str().c_str());
         }
 
         asImp_().addOutputVtkFields(u, writer);
@@ -696,7 +684,7 @@ public:
     void addOutputVtkFields(const SolutionVector &sol,
                             MultiWriter &writer)
     {
-        typedef Dune::BlockVector<Dune::FieldVector<double, 1> > ScalarField;
+        typedef Dune::BlockVector<Dune::FieldVector<Scalar, 1> > ScalarField;
 
         // create the required scalar fields
         unsigned numVertices = this->gridView_().size(dim);
@@ -728,9 +716,6 @@ public:
     { return problem_().gridView(); }
 
 protected:
-    static bool enableHints_()
-    { return GET_PARAM(TypeTag, bool, EnableHints); }
-
     /*!
      * \brief A reference to the problem on which the model is applied.
      */
@@ -754,83 +739,13 @@ protected:
     LocalResidual &localResidual_()
     { return localJacobian_.localResidual(); }
 
-    /*!
-     * \brief Updates the stuff which determines a vertex' or
-     *        element's boundary type
-     */
-    void updateBoundaryTypes_()
-    {
-        // resize the vectors
-        boundaryVertexIndex_.resize(numDofs());
-        std::fill(boundaryVertexIndex_.begin(),
-                  boundaryVertexIndex_.end(),
-                  -1);
-
-        int numBoundaryVertices = 0;
-        ElementVariables elemVars(problem_());
-
-        // loop over all elements of the grid
-        ElementIterator elemIt = gridView_().template begin<0>();
-        const ElementIterator elemEndIt = gridView_().template end<0>();
-        for (; elemIt != elemEndIt; ++elemIt) {
-            // do nothing if the element does not have boundary intersections
-            if (!elemIt->hasBoundaryIntersections())
-                continue;
-
-            // retrieve the reference element for the current element
-            const Element &elem = *elemIt;
-            Dune::GeometryType geoType = elem.geometry().type();
-            const ReferenceElement &refElem = ReferenceElements::general(geoType);
-            
-            elemVars.updateFVElemGeom(*elemIt);
-
-            // loop over all intersections of the element
-            IntersectionIterator isIt = gridView_().ibegin(elem);
-            const IntersectionIterator &endIt = gridView_().iend(elem);
-            for (; isIt != endIt; ++isIt)
-            {
-                // do nothing if the face is _not_ on the boundary
-                if (!isIt->boundary())
-                    continue;
-                
-                // loop over all vertices of the intersection
-                int faceIdx = isIt->indexInInside();
-                int numFaceVerts = refElem.size(faceIdx, 1, dim);
-                for (int faceVertIdx = 0;
-                     faceVertIdx < numFaceVerts;
-                     ++faceVertIdx)
-                {
-                    // find the local element index of the face's
-                    // vertex
-                    int scvIdx = refElem.subEntity(/*entityIdx=*/faceIdx,
-                                                   /*entityCodim=*/1,
-                                                   /*subEntityIdx=*/faceVertIdx,
-                                                   /*subEntityCodim=*/dim);
-                    int globalIdx = vertexMapper().map(*elemIt, scvIdx, /*codim=*/dim);
-                    if (boundaryVertexIndex_[globalIdx] >= 0)
-                        continue; // vertex has already been visited
-                    
-                    // add a BoundaryTypes object
-                    if (boundaryTypes_.size() <= numBoundaryVertices)
-                        boundaryTypes_.resize(numBoundaryVertices + 1);
-                    BoundaryTypes &bTypes = boundaryTypes_[numBoundaryVertices];
-                    boundaryVertexIndex_[globalIdx] = numBoundaryVertices;
-                    ++numBoundaryVertices;
-
-                    problem_().boundaryTypes(bTypes, elemVars, scvIdx);
-                } // loop over intersection's vertices
-            } // loop over intersections
-        } // loop over elements
-    };
-
     /*!
      * \brief Applies the initial solution for all vertices of the grid.
      */
     void applyInitialSolution_()
     {
         // first set the whole domain to zero
-        SolutionVector &uCur = solution(/*historyIdx=*/0);
-        uCur = Scalar(0.0);
+        uCur_ = Scalar(0.0);
         boxVolume_ = Scalar(0.0);
 
         FVElementGeometry fvElemGeom;
@@ -870,8 +785,8 @@ protected:
                 // will be the arithmetic mean.
                 initVal *= fvElemGeom.subContVol[scvIdx].volume;
                 boxVolume_[globalIdx] += fvElemGeom.subContVol[scvIdx].volume;
-                uCur[globalIdx] += initVal;
-                Valgrind::CheckDefined(uCur[globalIdx]);
+                uCur_[globalIdx] += initVal;
+                Valgrind::CheckDefined(uCur_[globalIdx]);
             }
         }
 
@@ -886,7 +801,7 @@ protected:
                                    Dune::ForwardCommunication);
 
             VertexHandleSum<PrimaryVariables, SolutionVector, VertexMapper>
-                sumPVHandle(uCur, vertexMapper());
+                sumPVHandle(uCur_, vertexMapper());
             gridView().communicate(sumPVHandle,
                                    Dune::InteriorBorder_InteriorBorder_Interface,
                                    Dune::ForwardCommunication);
@@ -895,14 +810,15 @@ protected:
         // divide all primary variables by the volume of their boxes
         int n = gridView_().size(dim);
         for (int i = 0; i < n; ++i) {
-            uCur[i] /= boxVolume(i);
+            uCur_[i] /= boxVolume(i);
         }
     }
 
     // the hint cache for the previous and the current volume
     // variables
     mutable std::vector<bool> hintsUsable_;
-    mutable std::vector<VolumeVariables> hints_[historySize];
+    mutable std::vector<VolumeVariables> curHints_;
+    mutable std::vector<VolumeVariables> prevHints_;
 
     /*!
      * \brief Returns whether messages should be printed
@@ -927,13 +843,13 @@ protected:
 
     // cur is the current iterative solution, prev the converged
     // solution of the previous time step
-    SolutionVector solution_[historySize];
-
-    // all the index of the BoundaryTypes object for a vertex
-    std::vector<int> boundaryVertexIndex_;
-    std::vector<BoundaryTypes> boundaryTypes_;
+    SolutionVector uCur_;
+    SolutionVector uPrev_;
 
     Dune::BlockVector<Dune::FieldVector<Scalar, 1> > boxVolume_;
+
+private:
+    bool enableHints_;
 };
 }
 
diff --git a/dumux/boxmodels/common/boxproblem.hh b/dumux/boxmodels/common/boxproblem.hh
index 9a5fbaab9b1e5e503fcb0e0236ffcad75652af4c..b8284c38f341b1f8a8fc5d49a4c94ea855524ceb 100644
--- a/dumux/boxmodels/common/boxproblem.hh
+++ b/dumux/boxmodels/common/boxproblem.hh
@@ -60,7 +60,7 @@ private:
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(ElementMapper)) ElementMapper;
 
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(PrimaryVariables)) PrimaryVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, PTAG(ElementVariables)) ElementVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(ElementVolumeVariables)) ElementVolumeVariables;
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(FVElementGeometry)) FVElementGeometry;
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(BoundaryTypes)) BoundaryTypes;
 
@@ -139,28 +139,6 @@ public:
         model().init(asImp_());
     }
 
-    /*!
-     * \brief Evaluate the boundary conditions for a dirichlet
-     *        control volume.
-     *
-     * \param values The dirichlet values for the primary variables
-     * \param context The local context. Only the element() and the fvElemGeom() methods are valid at this point
-     * \param localIdx The local index of the entity neighboring the Dirichlet boundary.
-     *
-     * For this method, the \a values parameter stores primary variables.
-     */
-    template <class Context>
-    DUNE_DEPRECATED
-    void boundaryTypes(BoundaryTypes &values,
-                       const Context &context,
-                       int localIdx) const
-    {
-        const auto vPtr = context.element().template subEntity<dim>(localIdx);
-
-        // forward it to the method which only takes the global coordinate
-        asImp_().boundaryTypes(values, *vPtr);
-   }
-    
     /*!
      * \brief Specifies which kind of boundary condition should be
      *        used for which equation on a given boundary segment.
@@ -192,27 +170,6 @@ public:
                    "a boundaryTypes() method.");
     }
 
-    /*!
-     * \brief Evaluate the boundary conditions for a dirichlet
-     *        control volume.
-     *
-     * \param values The dirichlet values for the primary variables
-     * \param context The local context. Only the element() and the fvElemGeom() methods are valid at this point
-     * \param localIdx The local index of the entity neighboring the Dirichlet boundary.
-     *
-     * For this method, the \a values parameter stores primary variables.
-     */
-    template <class Context>
-    DUNE_DEPRECATED
-    void dirichlet(PrimaryVariables &values,
-                   const Context &context,
-                   int localIdx) const
-    {
-        const auto vPtr = context.element().template subEntity<dim>(localIdx);
-        
-        // forward it to the method which only takes the global coordinate
-        asImp_().dirichlet(values, *vPtr);
-    }
 
     /*!
      * \brief Evaluate the boundary conditions for a dirichlet
@@ -223,7 +180,6 @@ public:
      *
      * For this method, the \a values parameter stores primary variables.
      */
-    DUNE_DEPRECATED
     void dirichlet(PrimaryVariables &values,
                    const Vertex &vertex) const
     {
@@ -242,7 +198,6 @@ public:
      *
      * For this method, the \a values parameter stores primary variables.
      */
-    DUNE_DEPRECATED
     void dirichletAtPos(PrimaryVariables &values,
                         const GlobalPosition &pos) const
     {
@@ -254,25 +209,6 @@ public:
                    "a dirichlet() method.");
     }
 
-    template <class Context>
-    DUNE_DEPRECATED
-    // if you get an deprecated warning here, please use context
-    // objects to specify your problem!
-    void neumann(PrimaryVariables &priVars,
-                 const Context &context,
-                 const Intersection &is,
-                 int localIdx,
-                 int boundaryIndex) const
-    {
-        return asImp_().boxSDNeumann(priVars,
-                                     context.element(),
-                                     context.fvElemGeom(),
-                                     is,
-                                     localIdx,
-                                     boundaryIndex,
-                                     context);
-    };
-
     /*!
      * \brief Evaluate the boundary conditions for a neumann
      *        boundary segment.
@@ -298,8 +234,7 @@ public:
                       const Intersection &is,
                       int scvIdx,
                       int boundaryFaceIdx,
-                      const ElementVariables &elemVars) const
-        DUNE_DEPRECATED
+                      const ElementVolumeVariables &elemVolVars) const
     {
         // forward it to the interface without the volume variables
         asImp_().neumann(values,
@@ -330,7 +265,6 @@ public:
                  const Intersection &is,
                  int scvIdx,
                  int boundaryFaceIdx) const
-        DUNE_DEPRECATED
     {
         // forward it to the interface with only the global position
         asImp_().neumannAtPos(values, fvElemGeom.boundaryFace[boundaryFaceIdx].ipGlobal);
@@ -348,7 +282,6 @@ public:
      */
     void neumannAtPos(PrimaryVariables &values,
                       const GlobalPosition &pos) const
-        DUNE_DEPRECATED
     {
         // Throw an exception (there is no reasonable default value
         // for Neumann conditions)
@@ -358,21 +291,6 @@ public:
                    "a neumannAtPos() method.");
     }
 
-    template <class Context>
-    // if you get an deprecated warning here, please use context
-    // objects to specify your problem!
-    DUNE_DEPRECATED
-    void source(PrimaryVariables &priVars,
-                const Context &context,
-                int localIdx) const
-    {
-        return asImp_().boxSDSource(priVars,
-                                    context.element(),
-                                    context.fvElemGeom(),
-                                    localIdx,
-                                    context);
-    };
-
     /*!
      * \brief Evaluate the source term for all phases within a given
      *        sub-control-volume.
@@ -395,11 +313,10 @@ public:
                      const Element &element,
                      const FVElementGeometry &fvElemGeom,
                      int scvIdx,
-                     const ElementVariables &elemVars) const
-        DUNE_DEPRECATED
+                     const ElementVolumeVariables &elemVolVars) const
     {
         // forward to solution independent, box specific interface
-        asImp_().source(values, elemVars, scvIdx);
+        asImp_().source(values, element, fvElemGeom, scvIdx);
     }
 
     /*!
@@ -419,7 +336,6 @@ public:
                 const Element &element,
                 const FVElementGeometry &fvElemGeom,
                 int scvIdx) const
-        DUNE_DEPRECATED
     {
         // forward to generic interface
         asImp_().sourceAtPos(values, fvElemGeom.subContVol[scvIdx].global);
@@ -440,7 +356,6 @@ public:
      */
     void sourceAtPos(PrimaryVariables &values,
                      const GlobalPosition &pos) const
-        DUNE_DEPRECATED
     {
         DUNE_THROW(Dune::InvalidStateException,
                    "The problem does not provide "
@@ -496,28 +411,6 @@ public:
      * thought as pipes with a cross section of 1 m^2 and 2D problems
      * are assumed to extend 1 m to the back.
      */
-    template <class Context>
-    // if you get an deprecated warning here, please use context
-    // objects to specify your problem!
-    DUNE_DEPRECATED
-    Scalar extrusionFactor(const Context &context,
-                           int localIdx) const
-    {
-        return asImp_().boxExtrusionFactor(context.element(),
-                                           context.fvElemGeom(),
-                                           localIdx);
-    };
-
-    /*!
-     * \brief Return how much the domain is extruded at a given sub-control volume.
-     *
-     * This means the factor by which a lower-dimensional (1D or 2D)
-     * entity needs to be expanded to get a full dimensional cell. The
-     * default is 1.0 which means that 1D problems are actually
-     * thought as pipes with a cross section of 1 m^2 and 2D problems
-     * are assumed to extend 1 m to the back.
-     */
-    DUNE_DEPRECATED
     Scalar boxExtrusionFactor(const Element &element,
                               const FVElementGeometry &fvElemGeom,
                               int scvIdx) const
@@ -875,7 +768,7 @@ public:
             Scalar t = timeManager().time() + timeManager().timeStepSize();
             createResultWriter_();
             resultWriter_->beginWrite(t);
-            model().addOutputVtkFields(model().solution(/*historyIdx=*/0), *resultWriter_);
+            model().addOutputVtkFields(model().curSol(), *resultWriter_);
             asImp_().addOutputVtkFields();
             resultWriter_->endWrite();
         }
diff --git a/dumux/boxmodels/common/boxproperties.hh b/dumux/boxmodels/common/boxproperties.hh
index ae75bb159e69f9254a2047f5e42be85f6d10ea81..466a281393a39b24f57f3278fa3ab2e2a0da051d 100644
--- a/dumux/boxmodels/common/boxproperties.hh
+++ b/dumux/boxmodels/common/boxproperties.hh
@@ -74,7 +74,7 @@ NEW_PROP_TAG(SolutionVector); //!< Vector containing all primary variable vector
 NEW_PROP_TAG(ElementSolutionVector); //!< A vector of primary variables within a sub-control volume
 
 NEW_PROP_TAG(VolumeVariables);  //!< The secondary variables within a sub-control volume
-NEW_PROP_TAG(ElementVariables); //!< The secondary variables of all sub-control volumes in an element
+NEW_PROP_TAG(ElementVolumeVariables); //!< The secondary variables of all sub-control volumes in an element
 NEW_PROP_TAG(FluxVariables); //!< Data required to calculate a flux over a face
 NEW_PROP_TAG(BoundaryVariables); //!< Data required to calculate fluxes over boundary faces (outflow)
 
@@ -121,15 +121,12 @@ NEW_PROP_TAG(EnableHints);
 
 // mappers from local to global indices
 
-//! mapper for vertices
+//! maper for vertices
 NEW_PROP_TAG(VertexMapper);
-//! mapper for elements
+//! maper for elements
 NEW_PROP_TAG(ElementMapper);
-//! mapper for degrees of freedom
+//! maper for degrees of freedom
 NEW_PROP_TAG(DofMapper);
-
-//! The history size required by the time discretization
-NEW_PROP_TAG(TimeDiscHistorySize);
 }
 }
 
diff --git a/dumux/boxmodels/common/boxpropertydefaults.hh b/dumux/boxmodels/common/boxpropertydefaults.hh
index c5253660718029c693d3857d5357434224733098..f1517d599b050e9aa01eb02daa6e6af3fc25fcbd 100644
--- a/dumux/boxmodels/common/boxpropertydefaults.hh
+++ b/dumux/boxmodels/common/boxpropertydefaults.hh
@@ -124,7 +124,7 @@ SET_TYPE_PROP(BoxModel, VolumeVariables, Dumux::BoxVolumeVariables<TypeTag>);
 /*!
  * \brief An array of secondary variable containers.
  */
-SET_TYPE_PROP(BoxModel, ElementVariables, Dumux::BoxElementVariables<TypeTag>);
+SET_TYPE_PROP(BoxModel, ElementVolumeVariables, Dumux::BoxElementVolumeVariables<TypeTag>);
 
 /*!
  * \brief Boundary types at a single degree of freedom.
@@ -185,8 +185,6 @@ SET_INT_PROP(BoxModel, LinearSolverMaxIterations, 250);
 //! set number of equations of the mathematical model as default
 SET_INT_PROP(BoxModel, LinearSolverBlockSize, GET_PROP_VALUE(TypeTag, PTAG(NumEq)));
 
-//! Set the history size of the time discretiuation to 2 (for implicit euler)
-SET_INT_PROP(BoxModel, TimeDiscHistorySize, 2);
 } // namespace Properties
 } // namespace Dumux
 
diff --git a/dumux/boxmodels/common/boxvolumevariables.hh b/dumux/boxmodels/common/boxvolumevariables.hh
index cf85043fbc42f154f0837b096f54545d837b37b4..626d7a9801129d1d7e1481966f329650742b52fe 100644
--- a/dumux/boxmodels/common/boxvolumevariables.hh
+++ b/dumux/boxmodels/common/boxvolumevariables.hh
@@ -49,7 +49,6 @@ class BoxVolumeVariables
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(FVElementGeometry)) FVElementGeometry;
 
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(PrimaryVariables)) PrimaryVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, PTAG(ElementVariables)) ElementVariables;
 
 public:
     // default constructor
@@ -119,13 +118,15 @@ public:
      *       phase state in the 2p2c model)
      */
     void update(const PrimaryVariables &priVars,
-                const ElementVariables &elemVars,
+                const Problem &problem,
+                const Element &element,
+                const FVElementGeometry &elemGeom,
                 int scvIdx,
-                int historyIdx)
+                bool isOldSol)
     {
         Valgrind::CheckDefined(priVars);
         primaryVars_ = priVars;
-        extrusionFactor_ = elemVars.problem().extrusionFactor(elemVars, scvIdx);
+        extrusionFactor_ = problem.boxExtrusionFactor(element, elemGeom, scvIdx);
     }
 
     /*!
diff --git a/dumux/common/timemanager.hh b/dumux/common/timemanager.hh
index a7d244a324b8585a0f3e273165420724cd8fec35..1bbf74c58004eb4382ac52ccd333ae44eac5bb05 100644
--- a/dumux/common/timemanager.hh
+++ b/dumux/common/timemanager.hh
@@ -379,7 +379,7 @@ public:
             if (verbose_) {
                 std::cout <<
                     boost::format("Time step %d done. Wall time:%.4g, time:%.4g, time step size:%.4g\n")
-                    %timeStepIndex()%double(timer.elapsed())%double(time())%double(dt);
+                    %timeStepIndex()%timer.elapsed()%time()%dt;
             }
 
             // write restart file if mandated by the problem
diff --git a/dumux/linear/overlappingscalarproduct.hh b/dumux/linear/overlappingscalarproduct.hh
index 71bfaff5048ce2fb088c2219016e48d5802190fc..2f0360e938678d9022f6acc49d9333b37c7880fc 100644
--- a/dumux/linear/overlappingscalarproduct.hh
+++ b/dumux/linear/overlappingscalarproduct.hh
@@ -67,8 +67,8 @@ public:
 
     double norm(const OverlappingBlockVector &x)
     {
-        field_type tmp = std::sqrt(dot(x, x));
-        return tmp;
+        double tmp = dot(x, x);
+        return std::sqrt(tmp);
     };
 
 private:
diff --git a/dumux/material/spatialparameters/boxspatialparameters.hh b/dumux/material/spatialparameters/boxspatialparameters.hh
index 79e4cd8caf27a84114a62bbd492595c6e5969bd1..28cf38036859772409466dfb3bda6bdfefc5868b 100644
--- a/dumux/material/spatialparameters/boxspatialparameters.hh
+++ b/dumux/material/spatialparameters/boxspatialparameters.hh
@@ -72,30 +72,20 @@ public:
      * \brief Function for defining the parameters needed by constitutive relationships (kr-Sw, pc-Sw, etc.).
      *
      * \return the material parameters object
+     * \param element The element
      */
-    template <class Context>
-    DUNE_DEPRECATED
-    const MaterialLawParams& materialLawParams(const Context &context, int localIdx) const
-    {
-        return asImp_().materialLawParams(context.element(),
-                                          context.fvElemGeom(),
-                                          localIdx);
-    }
-
-    DUNE_DEPRECATED
     const MaterialLawParams& materialLawParams(const Element &element,
-                                               const FVElementGeometry &fvElemGeom,
-                                               int localIdx) const
+            const FVElementGeometry &fvElemGeom,
+            int scvIdx) const
     {
-        return asImp_().materialLawParams(fvElemGeom.subContVol[localIdx].global);
+            return asImp_().materialLawParamsAtPos(element.geometry().center());
     }
 
-
     /*!
      * \brief Function for defining the parameters needed by constitutive relationships (kr-Sw, pc-Sw, etc.).
      *
-     * \param globalPos The position of the center of the element
      * \return the material parameters object
+     * \param globalPos The position of the center of the element
      */
     const MaterialLawParams& materialLawParamsAtPos(const GlobalPosition& globalPos) const
     {
diff --git a/dumux/material/spatialparameters/boxspatialparameters1p.hh b/dumux/material/spatialparameters/boxspatialparameters1p.hh
index fe7232fc781a5b104778f6707727c3c33ff0f45f..a70a3a4ae56406a2fc0d5b1e0e99019af536efb1 100644
--- a/dumux/material/spatialparameters/boxspatialparameters1p.hh
+++ b/dumux/material/spatialparameters/boxspatialparameters1p.hh
@@ -66,7 +66,6 @@ class BoxSpatialParametersOneP
     typedef typename GridView::ctype CoordScalar;
     typedef Dune::FieldMatrix<Scalar, dimWorld, dimWorld> Tensor;
     typedef Dune::FieldVector<CoordScalar,dimWorld> GlobalPosition;
-    typedef Dune::FieldVector<Scalar,dimWorld> Vector;
 
 public:
     BoxSpatialParametersOneP(const GridView &gv)
@@ -75,6 +74,53 @@ public:
     ~BoxSpatialParametersOneP()
     {}
 
+    /*!
+     * \brief Returns the factor by which the volume of a sub control
+     *        volume needs to be multiplied in order to get cubic
+     *        meters.
+     *
+     * \param element The current finite element
+     * \param fvElemGeom The current finite volume geometry of the element
+     * \param scvIdx The index sub-control volume face where the
+     *                      factor ought to be calculated.
+     *
+     * By default that's just 1.0
+     */
+    Scalar extrusionFactorScv(const Element &element,
+                              const FVElementGeometry &fvElemGeom,
+                              int scvIdx) const
+    DUNE_DEPRECATED // use the extrusion factor of the volume variables
+    { return 1.0; }
+
+    /*!
+     * \brief Returns the factor by which the area of a sub control
+     *        volume face needs to be multiplied in order to get
+     *        square meters.
+     *
+     * \param element The current finite element
+     * \param fvElemGeom The current finite volume geometry of the element
+     * \param scvfIdx The index sub-control volume face where the
+     *                      factor ought to be calculated.
+     *
+     * By default it is the arithmetic mean of the extrusion factor of
+     * the face's two sub-control volumes.
+     */
+    Scalar extrusionFactorScvf(const Element &element,
+                              const FVElementGeometry &fvElemGeom,
+                              int scvfIdx) const
+    DUNE_DEPRECATED // use the extrusion factor of the volume variables
+    {
+        return
+            0.5 *
+            (asImp_().extrusionFactorScv(element,
+                                         fvElemGeom,
+                                         fvElemGeom.subContVolFace[scvfIdx].i)
+             +
+             asImp_().extrusionFactorScv(element,
+                                         fvElemGeom,
+                                         fvElemGeom.subContVolFace[scvfIdx].j));
+    }
+
     /*!
      * \brief Averages the intrinsic permeability (Scalar).
      * \param result averaged intrinsic permeability
@@ -110,26 +156,15 @@ public:
                 result[i][j] = harmonicMean(K1[i][j], K2[i][j]);
     }
 
-    template <class Context>
-    const Tensor &intrinsicPermeability(const Context &context,
-                                        int localIdx) const
-    {
-        return intrinsicPermeability(context.element(), 
-                                     context.fvElemGeom(),
-                                     localIdx);
-                                     
-    }
-
     /*!
      * \brief Function for defining the intrinsic (absolute) permeability.
      *
      * \return intrinsic (absolute) permeability
      * \param element The element
      */
-    DUNE_DEPRECATED
-    const Tensor &intrinsicPermeability(const Element &element,
-                                        const FVElementGeometry &fvElemGeom,
-                                        int scvIdx) const
+    const Tensor& intrinsicPermeability (const Element &element,
+            const FVElementGeometry &fvElemGeom,
+            int scvIdx) const
     {
         return asImp_().intrinsicPermeabilityAtPos(element.geometry().center());
     }
@@ -140,7 +175,6 @@ public:
      * \return intrinsic (absolute) permeability
      * \param globalPos The position of the center of the element
      */
-    DUNE_DEPRECATED
     const Tensor& intrinsicPermeabilityAtPos (const GlobalPosition& globalPos) const
     {
         DUNE_THROW(Dune::InvalidStateException,
@@ -148,26 +182,15 @@ public:
                    "a intrinsicPermeabilityAtPos() method.");
     }
 
-    template <class Context>
-    Scalar porosity(const Context &context,
-                    int localIdx) const
-    {
-        return porosity(context.element(), 
-                        context.fvElemGeom(),
-                        localIdx);
-                                     
-    }
-
     /*!
      * \brief Function for defining the porosity.
      *
      * \return porosity
      * \param element The element
      */
-    DUNE_DEPRECATED
     Scalar porosity(const Element &element,
-                    const FVElementGeometry &fvElemGeom,
-                    int scvIdx) const
+            const FVElementGeometry &fvElemGeom,
+            int scvIdx) const
     {
         return asImp_().porosityAtPos(element.geometry().center());
     }
@@ -178,7 +201,6 @@ public:
      * \return porosity
      * \param globalPos The position of the center of the element
      */
-    DUNE_DEPRECATED
     Scalar porosityAtPos(const GlobalPosition& globalPos) const
     {
         DUNE_THROW(Dune::InvalidStateException,
diff --git a/dumux/nonlinear/newtonmethod.hh b/dumux/nonlinear/newtonmethod.hh
index 2165c39f8b8f10ad9032585101681148b13e230e..a083ef605c76f3e23f4067e2378b859b1380a60d 100644
--- a/dumux/nonlinear/newtonmethod.hh
+++ b/dumux/nonlinear/newtonmethod.hh
@@ -116,7 +116,7 @@ public:
 protected:
     bool execute_(NewtonController &ctl)
     {
-        SolutionVector &uCurrentIter = model().solution(/*historyIdx=*/0);
+        SolutionVector &uCurrentIter = model().curSol();
         SolutionVector uLastIter(uCurrentIter);
         SolutionVector deltaU(uCurrentIter);
 
diff --git a/test/boxmodels/2p/lensproblem.hh b/test/boxmodels/2p/lensproblem.hh
index d8bc6f25412d514a453bb6b655d306444fda66ec..dab4dc78d7b4ae513a3526ccbcceb3453ff43b77 100644
--- a/test/boxmodels/2p/lensproblem.hh
+++ b/test/boxmodels/2p/lensproblem.hh
@@ -25,11 +25,10 @@
  * \brief Soil contamination problem where DNAPL infiltrates a fully
  *        water saturated medium.
  */
+
 #ifndef DUMUX_LENSPROBLEM_HH
 #define DUMUX_LENSPROBLEM_HH
 
-//#include <dumux/common/quad.hh>
-
 #if HAVE_UG
 #include <dune/grid/uggrid.hh>
 #endif
@@ -58,8 +57,6 @@ namespace Properties
 {
 NEW_TYPE_TAG(LensProblem, INHERITS_FROM(BoxTwoP, LensSpatialParameters));
 
-//SET_TYPE_PROP(LensProblem, Scalar, quad);
-
 // Set the grid type
 #if 0// HAVE_UG
 SET_TYPE_PROP(LensProblem, Grid, Dune::UGGrid<2>);
@@ -246,7 +243,6 @@ public:
      *
      * This problem assumes a uniform temperature of 10 degrees Celsius.
      */
-    using ParentType::temperature;
     Scalar temperature() const
     { return temperature_; };
 
diff --git a/test/boxmodels/2p/lensspatialparameters.hh b/test/boxmodels/2p/lensspatialparameters.hh
index ad82f044eac3d4e8c74eb3815bcbba5b81b07787..d0a34f0f153adba60b1a2aa9e2c56d045399e6de 100644
--- a/test/boxmodels/2p/lensspatialparameters.hh
+++ b/test/boxmodels/2p/lensspatialparameters.hh
@@ -135,24 +135,27 @@ public:
      * \param scvIdx The index sub-control volume face where the
      *                      intrinsic velocity ought to be calculated.
      */
-    template <class Context>
-    Scalar intrinsicPermeability(const Context &context, int localIdx) const
+    Scalar intrinsicPermeability(const Element &element,
+                                 const FVElementGeometry &fvElemGeom,
+                                 int scvIdx) const
     {
-        const GlobalPosition &globalPos = context.pos(localIdx);
+        const GlobalPosition &globalPos = fvElemGeom.subContVol[scvIdx].global;
         if (isInLens_(globalPos))
             return lensK_;
         return outerK_;
     }
 
-    template <class Context>
-    Scalar porosity(const Context &context, int localIdx) const
+    Scalar porosity(const Element &element,
+                    const FVElementGeometry &fvElemGeom,
+                    int scvIdx) const
     { return 0.4; }
 
     // return the parameter object for the Brooks-Corey material law which depends on the position
-    template <class Context>
-    const MaterialLawParams& materialLawParams(const Context &context, int localIdx) const
+    const MaterialLawParams& materialLawParams(const Element &element,
+                                                const FVElementGeometry &fvElemGeom,
+                                                int scvIdx) const
     {
-        const GlobalPosition &globalPos = context.pos(localIdx);
+        const GlobalPosition &globalPos = fvElemGeom.subContVol[scvIdx].global;
 
         if (isInLens_(globalPos))
             return lensMaterialParams_;