diff --git a/dumux/implicit/adaptive/adaptionhelper.hh b/dumux/implicit/adaptive/adaptionhelper.hh
index e88021c201076db895420931d1d93f0edbc1ae75..36ddbb7eec79deb3f05c5bb718fdd4b24df7f679 100644
--- a/dumux/implicit/adaptive/adaptionhelper.hh
+++ b/dumux/implicit/adaptive/adaptionhelper.hh
@@ -37,9 +37,7 @@ namespace Properties
 {
 NEW_PROP_TAG(GridView);
 NEW_PROP_TAG(ImplicitIsBox);
-NEW_PROP_TAG(PrimaryVariables);
 NEW_PROP_TAG(Problem);
-NEW_PROP_TAG(Scalar);
 }
 
 /*!
@@ -51,47 +49,20 @@ class ImplicitAdaptionHelper
 private:
     typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
     typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
-    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef typename GridView::Grid Grid;
 
     enum {
         // Grid and world dimension
         dim = GridView::dimension,
-        dimWorld = GridView::dimensionworld
+        dimWorld = GridView::dimensionworld,
     };
 
     enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) };
     enum { dofCodim = isBox ? dim : 0 };
 
-    typedef typename GridView::Grid Grid;
-    typedef typename Grid::LevelGridView LevelGridView;
     typedef typename GridView::Traits::template Codim<0>::Entity Element;
     typedef typename GridView::Traits::template Codim<dofCodim>::Entity DofEntity;
 
-    typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition;
-    typedef typename GridView::ctype CoordScalar;
-    typedef Dune::FieldVector<CoordScalar, dim> LocalPosition;
-
-    typedef Dune::PQkLocalFiniteElementCache<CoordScalar, Scalar, dim, 1> LocalFiniteElementCache;
-    typedef typename LocalFiniteElementCache::FiniteElementType LocalFiniteElement;
-
-protected:
-    const GridView gridView_;
-    const Grid& grid_;
-
-    struct AdaptedValues
-    {
-        PrimaryVariables u;
-        int count;
-        AdaptedValues()
-        {
-            count = 0;
-        }
-    };
-
-    typedef Dune::PersistentContainer<Grid, AdaptedValues> PersistentContainer;
-    PersistentContainer adaptionMap_;
-
 public:
     //! Constructs an adaptive helper object
     /**
@@ -100,11 +71,9 @@ public:
      *
      *  @param gridView a DUNE gridview object corresponding to diffusion and transport equation
      */
-    ImplicitAdaptionHelper(const GridView& gridView) :
-        gridView_(gridView), grid_(gridView.grid()), adaptionMap_(grid_, dofCodim)
+    ImplicitAdaptionHelper(Problem& problem)
     {}
 
-
     /*!
      * Store primary variables
      *
@@ -118,60 +87,12 @@ public:
      */
     void storePrimVars(Problem& problem)
     {
-        adaptionMap_.resize();
-
-        // loop over all levels of the grid
-        for (int level = grid_.maxLevel(); level >= 0; level--)
-        {
-            //get grid view on level grid
-            LevelGridView levelView = grid_.levelGridView(level);
-
-            if(!isBox)
-            {
-                for (const auto& element : elements(levelView))
-                {
-                    //get your map entry
-                    AdaptedValues &adaptedValues = adaptionMap_[element];
-
-                    // put your value in the map
-                    if (element.isLeaf())
-                    {
-                        // get index
-                        int indexI = this->elementIndex(problem, element);
-
-                        storeAdaptionValues(adaptedValues, problem.model().curSol()[indexI]);
-
-                        adaptedValues.count = 1;
-                    }
-                    //Average in father
-                    if (element.level() > 0)
-                    {
-                        AdaptedValues& adaptedValuesFather = adaptionMap_[element.father()];
-                        adaptedValuesFather.count += 1;
-                        storeAdaptionValues(adaptedValues, adaptedValuesFather);
-                    }
-
-                }
-            }
-            else
-            {
-                for (const auto& entity : entities(levelView, Dune::Codim<dofCodim>()))
-                {
-                    //get your map entry
-                    AdaptedValues &adaptedValues = adaptionMap_[entity];
-
-                    // put your value in the map
-                    int indexI = this->dofIndex(problem, entity);
-
-                    storeAdaptionValues(adaptedValues, problem.model().curSol()[indexI]);
-
-                    adaptedValues.count = 1;
-
-                }
-            }
-        }
+        DUNE_THROW(Dune::InvalidStateException,
+                   "The problem does not provide "
+                   "a storePrimVars method.");
     }
 
+
     /*!
      * Reconstruct missing primary variables (where elements are created/deleted)
      *
@@ -187,207 +108,21 @@ public:
      */
     void reconstructPrimVars(Problem& problem)
     {
-        adaptionMap_.resize();
-
-        for (int level = 0; level <= grid_.maxLevel(); level++)
-        {
-            LevelGridView levelView = grid_.levelGridView(level);
-
-            for (const auto& element : elements(levelView))
-            {
-                // only treat non-ghosts, ghost data is communicated afterwards
-                if (element.partitionType() == Dune::GhostEntity)
-                    continue;
-
-                if (!element.isNew())
-                {
-                    //entry is in map, write in leaf
-                    if (element.isLeaf())
-                    {
-                        if(!isBox)
-                        {
-                            AdaptedValues &adaptedValues = adaptionMap_[element];
-                            int newIdxI = this->elementIndex(problem, element);
-
-                            setAdaptionValues(adaptedValues, problem.model().curSol()[newIdxI]);
-                        }
-                        else
-                        {
-                            unsigned int numSubEntities = element.subEntities(dofCodim);
-
-                            for(unsigned int i = 0; i < numSubEntities; i++)
-                            {
-                                auto subEntity = element.template subEntity <dofCodim>(i);
-                                AdaptedValues &adaptedValues = adaptionMap_[subEntity];
-                                int newIdxI = this->dofIndex(problem, subEntity);
-
-                                setAdaptionValues(adaptedValues, problem.model().curSol()[newIdxI]);
-
-                            }
-                        }
-                    }
-                }
-                else
-                {
-                    // value is not in map, interpolate from father element
-                    if (element.level() > 0 && element.hasFather())
-                    {
-                        auto epFather = element.father();
-
-                        if(!isBox)
-                        {
-                            // create new entry: reconstruct from adaptionMap_[*father] to a new
-                            // adaptionMap_[*son]
-                            reconstructAdaptionValues(adaptionMap_, epFather, element, problem);
-
-                            // access new son
-                            AdaptedValues& adaptedValues = adaptionMap_[element];
-                            adaptedValues.count = 1;
-
-                            // if we are on leaf, store reconstructed values of son in CellData object
-                            if (element.isLeaf())
-                            {
-                                // acess new CellData object
-                                int newIdxI = this->elementIndex(problem, element);
-
-                                setAdaptionValues(adaptedValues, problem.model().curSol()[newIdxI]);
-                            }
-                        }
-                        else
-                        {
-                            unsigned int numSubEntities= element.subEntities(dofCodim);
-                            const auto geometryI = element.geometry();
-
-                            for(unsigned int i = 0; i < numSubEntities; i++)
-                            {
-                                auto subEntity = element.template subEntity <dofCodim>(i);
-                                AdaptedValues &adaptedValues = adaptionMap_[subEntity];
-
-                                if(adaptedValues.count == 0){
-                                    LocalPosition dofCenterPos = geometryI.local(subEntity.geometry().center());
-                                    const LocalFiniteElementCache feCache;
-                                    Dune::GeometryType geomType = epFather.geometry().type();
-
-                                    const LocalFiniteElement &localFiniteElement = feCache.get(geomType);
-                                    std::vector<Dune::FieldVector<Scalar, 1> > shapeVal;
-                                    localFiniteElement.localBasis().evaluateFunction(dofCenterPos, shapeVal);
-                                    PrimaryVariables u(0);
-                                    for (int j = 0; j < shapeVal.size(); ++j)
-                                    {
-                                        AdaptedValues & adaptedValuesFather = adaptionMap_[epFather.template subEntity <dofCodim>(j)];
-                                        u.axpy(shapeVal[j], adaptedValuesFather.u);
-                                    }
-
-                                    adaptedValues.u = u;
-                                    adaptedValues.count = 1;
-                                }
-
-                                if (element.isLeaf())
-                                {
-                                    int newIdxI = this->dofIndex(problem, subEntity);
-                                    setAdaptionValues(adaptedValues, problem.model().curSol()[newIdxI]);
-                                }
-
-                            }
-                        }
-                    }
-
-                }
-            }
-
-        }
-        // reset entries in restrictionmap
-        adaptionMap_.resize( typename PersistentContainer::Value() );
-        adaptionMap_.shrinkToFit();
-        adaptionMap_.fill( typename PersistentContainer::Value() );
-
-//#if HAVE_MPI
-//        // communicate ghost data
-//        typedef typename GET_PROP(TypeTag, SolutionTypes) SolutionTypes;
-//        typedef typename SolutionTypes::ElementMapper ElementMapper;
-//        typedef VectorExchange<ElementMapper, std::vector<CellData> > DataHandle;
-//        DataHandle dataHandle(problem.elementMapper(), this->cellDataGlobal());
-//        problem.gridView().template communicate<DataHandle>(dataHandle,
-//                                                            Dune::InteriorBorder_All_Interface,
-//                                                            Dune::ForwardCommunication);
-//#endif
+        DUNE_THROW(Dune::InvalidStateException,
+                   "The problem does not provide "
+                   "a reconstructPrimVars method.");
     }
 
-    //! Stores values to be adapted in an adaptedValues container
-    /**
-     * Stores values to be adapted from the current CellData objects into
-     * the adaption container in order to be mapped on a new grid.
-     *
-     * \param adaptedValues Container for model-specific values to be adapted
-     * \param u The variables to be stored
-     */
-    static void storeAdaptionValues(AdaptedValues& adaptedValues, const PrimaryVariables& u)
-    {
-        adaptedValues.u = u;
-    }
-    //! Stores sons entries into father element for averaging
-    /**
-     * Sum up the adaptedValues (sons values) into father element. We store from leaf
-     * upwards, so sons are stored first, then cells on the next leaf (=fathers)
-     * can be averaged.
-     *
-     * \param adaptedValues Container for model-specific values to be adapted
-     * \param adaptedValuesFather Values to be adapted of father cell
-     */
-    static void storeAdaptionValues(AdaptedValues& adaptedValues,
-                                    AdaptedValues& adaptedValuesFather)
-    {
-        if(!isBox)
-        {
-            adaptedValuesFather.u += adaptedValues.u;
-            adaptedValuesFather.u /= adaptedValues.count;
-        }
-        else
-        {
-            adaptedValuesFather.u = adaptedValues.u;
-        }
-    }
-    //! Set adapted values in CellData
-    /**
-     * This methods stores reconstructed values into the cellData object, by
-     * this setting a newly mapped solution to the storage container of the
-     * sequential models.
-     *
-     * \param adaptedValues Container for model-specific values to be adapted
-     * \param u The variables to be stored
-     */
-    static void setAdaptionValues(AdaptedValues& adaptedValues, PrimaryVariables& u)
-    {
-        PrimaryVariables uNew = adaptedValues.u;
-        uNew /= adaptedValues.count;
-
-        u = uNew;
-    }
+protected:
 
-    //! Reconstructs sons entries from data of father cell
-    /**
-     * Reconstructs a new solution from a father cell into a newly
-     * generated son cell. New cell is stored into the global
-     * adaptionMap.
-     *
-     * \param adaptionMap Global map storing all values to be adapted
-     * \param father Entity Pointer to the father cell
-     * \param son Entity Pointer to the newly created son cell
-     * \param problem The problem
-     */
-    static void reconstructAdaptionValues(Dune::PersistentContainer<Grid, AdaptedValues>& adaptionMap,
-            const Element& father, const Element& son, const Problem& problem)
+    int dofIndex(const Problem& problem, const DofEntity& entity) const
     {
-        AdaptedValues& adaptedValues = adaptionMap[son];
-        AdaptedValues& adaptedValuesFather = adaptionMap[father];
-
-        adaptedValues.u = adaptedValuesFather.u;
-        adaptedValues.u /= adaptedValuesFather.count;
+                return problem.model().dofMapper().index(entity);
     }
 
-    int dofIndex(const Problem& problem, const DofEntity& entity) const
+    int dofIndex(const Problem& problem, const Element& element, const int scvIdx) const
     {
-                return problem.model().dofMapper().index(entity);
+                return problem.model().dofMapper().subIndex(element, scvIdx, dofCodim);
     }
 
     int elementIndex(const Problem& problem, const Element& element) const
diff --git a/dumux/implicit/adaptive/gridadapt.hh b/dumux/implicit/adaptive/gridadapt.hh
index ccc221d6609df4b478f31c471fdd4bf421770459..2c9f327089401698a42967e7375d0ab50cfb28d5 100644
--- a/dumux/implicit/adaptive/gridadapt.hh
+++ b/dumux/implicit/adaptive/gridadapt.hh
@@ -72,19 +72,19 @@ public:
      */
     ImplicitGridAdapt (Problem& problem)
         : problem_(problem),
-          adaptionHelper_(problem.gridView()),
+          adaptionHelper_(problem),
           adaptionIndicator_(problem),
           marked_(0),
           coarsened_(0)
     {
-        if(isBox)
-        {
-            DUNE_THROW(Dune::NotImplemented,
-                       "Grid adaption is not yet mass conservative for Box method! "
-                        << "Use cell-centered scheme instead!");
-        }
-        else
-        {
+//        if(isBox)
+//        {
+//            DUNE_THROW(Dune::NotImplemented,
+//                       "Grid adaption is not yet mass conservative for Box method! "
+//                        << "Use cell-centered scheme instead!");
+//        }
+//        else
+//        {
             levelMin_ = GET_PARAM_FROM_GROUP(TypeTag, int, GridAdapt, MinLevel);
             levelMax_ = GET_PARAM_FROM_GROUP(TypeTag, int, GridAdapt, MaxLevel);
             adaptionInterval_ = GET_PARAM_FROM_GROUP(TypeTag, int, GridAdapt, AdaptionInterval);
@@ -93,7 +93,7 @@ public:
             {
                 DUNE_THROW(Dune::InvalidStateException, "Coarsening the level 0 entities is not possible! Choose MinLevel >= 0");
             }
-        }
+//        }
     }
 
     /*!
diff --git a/dumux/porousmediumflow/2p/implicit/adaptionhelper.hh b/dumux/porousmediumflow/2p/implicit/adaptionhelper.hh
new file mode 100644
index 0000000000000000000000000000000000000000..1cf2118c1394f56600cb95e71cbf900cb9e8f5fa
--- /dev/null
+++ b/dumux/porousmediumflow/2p/implicit/adaptionhelper.hh
@@ -0,0 +1,539 @@
+// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+// vi: set et ts=4 sw=4 sts=4:
+/*****************************************************************************
+ *   See the file COPYING for full copying permissions.                      *
+ *                                                                           *
+ *   This program is free software: you can redistribute it and/or modify    *
+ *   it under the terms of the GNU General Public License as published by    *
+ *   the Free Software Foundation, either version 2 of the License, or       *
+ *   (at your option) any later version.                                     *
+ *                                                                           *
+ *   This program is distributed in the hope that it will be useful,         *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the            *
+ *   GNU General Public License for more details.                            *
+ *                                                                           *
+ *   You should have received a copy of the GNU General Public License       *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
+ *****************************************************************************/
+#ifndef DUMUX_TWOP_ADAPTIONHELPER_HH
+#define DUMUX_TWOP_ADAPTIONHELPER_HH
+
+#include <dumux/implicit/adaptive/adaptionhelper.hh>
+
+namespace Dumux {
+
+namespace Properties
+{
+NEW_PROP_TAG(PrimaryVariables);
+NEW_PROP_TAG(Scalar);
+}
+
+/*!
+ * \brief Base class holding the variables for implicit models.
+ */
+template<class TypeTag>
+class TwoPAdaptionHelper : public ImplicitAdaptionHelper<TypeTag>
+{
+private:
+    typedef ImplicitAdaptionHelper<TypeTag> ParentType;
+    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
+    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+
+    enum {
+        // Grid and world dimension
+        dim = GridView::dimension,
+        dimWorld = GridView::dimensionworld,
+
+        //indices
+        pressureIdx = Indices::pressureIdx,
+        saturationIdx = Indices::saturationIdx,
+        pwsn = Indices::pwsn,
+        pnsw = Indices::pnsw,
+        formulation = GET_PROP_VALUE(TypeTag, Formulation),
+        wPhaseIdx = Indices::wPhaseIdx,
+        nPhaseIdx = Indices::nPhaseIdx
+    };
+
+    enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) };
+    enum { dofCodim = isBox ? dim : 0 };
+
+    typedef typename GridView::Grid Grid;
+    typedef typename Grid::LevelGridView LevelGridView;
+    typedef typename GridView::Traits::template Codim<0>::Entity Element;
+    typedef typename GridView::Traits::template Codim<dofCodim>::Entity DofEntity;
+
+    typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition;
+    typedef typename GridView::ctype CoordScalar;
+    typedef Dune::FieldVector<CoordScalar, dim> LocalPosition;
+
+    typedef Dune::PQkLocalFiniteElementCache<CoordScalar, Scalar, dim, 1> LocalFiniteElementCache;
+    typedef typename LocalFiniteElementCache::FiniteElementType LocalFiniteElement;
+
+    struct AdaptedValues
+    {
+        std::vector<PrimaryVariables> u;
+        int count;
+        PrimaryVariables associatedMass;
+        AdaptedValues(): associatedMass(0)
+        {
+            count = 0;
+        }
+    };
+
+    typedef Dune::PersistentContainer<Grid, AdaptedValues> PersistentContainer;
+    PersistentContainer adaptionMap_;
+
+public:
+    //! Constructs an adaption helper object
+    /**
+     *  @param gridView a DUNE gridview object
+     */
+    TwoPAdaptionHelper(Problem& problem) : ParentType(problem), adaptionMap_(problem.grid(), 0)
+    {}
+
+    /*!
+     * Store primary variables
+     *
+     * To reconstruct the solution in father elements, problem properties might
+     * need to be accessed.
+     * From upper level on downwards, the old solution is stored into an container
+     * object, before the grid is adapted. Father elements hold averaged information
+     * from the son cells for the case of the sons being coarsened.
+     *
+     * @param problem The current problem
+     */
+    void storePrimVars(Problem& problem)
+    {
+        adaptionMap_.resize();
+
+        // loop over all levels of the grid
+        for (int level = problem.grid().maxLevel(); level >= 0; level--)
+        {
+            //get grid view on level grid
+            LevelGridView levelView = problem.grid().levelGridView(level);
+
+            for (const auto& element : elements(levelView))
+            {
+                //get your map entry
+                AdaptedValues &adaptedValues = adaptionMap_[element];
+
+                // put your value in the map
+                if (element.isLeaf())
+                {
+                    FVElementGeometry fvGeometry;
+                    fvGeometry.update(problem.gridView(), element);
+
+                    for (int scvIdx = 0; scvIdx < fvGeometry.numScv; ++scvIdx)
+                    {
+                        // get index
+                        auto subEntity = element.template subEntity <dofCodim>(scvIdx);
+                        int dofIdx = this->dofIndex(problem, subEntity);
+
+                        adaptedValues.u.push_back(problem.model().curSol()[dofIdx]);
+
+                        VolumeVariables volVars;
+                        volVars.update(adaptedValues.u[scvIdx],
+                                      problem,
+                                      element,
+                                      fvGeometry,
+                                      scvIdx,
+                                      false);
+
+                        Scalar volume = fvGeometry.subContVol[scvIdx].volume;
+
+                        adaptedValues.associatedMass[nPhaseIdx] += volume*volVars.density(nPhaseIdx)
+                                            * volVars.porosity() * volVars.saturation(nPhaseIdx);
+                        adaptedValues.associatedMass[wPhaseIdx] += volume*volVars.density(wPhaseIdx)
+                                            * volVars.porosity() * volVars.saturation(wPhaseIdx);
+                    }
+                    adaptedValues.count = 1;
+                }
+                //Average in father
+                if (element.level() > 0)
+                {
+                    AdaptedValues& adaptedValuesFather = adaptionMap_[element.father()];
+                    adaptedValuesFather.count += 1;
+                    storeAdaptionValues(adaptedValues, adaptedValuesFather);
+                }
+
+                if(isBox && !element.isLeaf())
+                {
+                    FVElementGeometry fvGeometry;
+                    fvGeometry.update(problem.gridView(), element);
+
+                    for (int scvIdx = 0; scvIdx < fvGeometry.numScv; ++scvIdx)
+                    {
+                        auto subEntity = element.template subEntity <dofCodim>(scvIdx);
+                        int dofIdx = this->dofIndex(problem, subEntity);
+
+                        adaptedValues.u.push_back(problem.model().curSol()[dofIdx]);
+                    }
+                }
+
+            }
+        }
+    }
+
+    void dataOutput(Problem& problem)
+    {
+        // loop over all levels of the grid
+        for (int level = problem.grid().maxLevel(); level >= 0; level--)
+        {
+            //get grid view on level grid
+            LevelGridView levelView = problem.grid().levelGridView(level);
+
+            for (const auto& element : elements(levelView))
+            {
+                AdaptedValues &adaptedValues = adaptionMap_[element];
+                if (element.level() > 0 && !element.isNew())
+                {
+                    AdaptedValues& adaptedValuesFather = adaptionMap_[element.father()];
+                    for(int i=0; i<adaptedValues.u.size(); i++)
+                    {
+                        auto subEntity = element.template subEntity <dofCodim>(i);
+                        int dofIdx = this->dofIndex(problem, subEntity);
+                        std::cout << "SonValues:" << std::endl;
+                        std::cout << "u: " << dofIdx <<"___" << adaptedValues.u[i] << std::endl;
+                    }
+                    for(int i=0; i<adaptedValuesFather.u.size(); i++)
+                    {
+                        auto subEntity = element.father().template subEntity <dofCodim>(i);
+                        int dofIdx = this->dofIndex(problem, subEntity);
+                        std::cout << "FatherValues:" << std::endl;
+                        std::cout << "u: " << dofIdx <<"___" << adaptedValuesFather.u[i] << std::endl;
+                    }
+                }
+
+            }
+        }
+    }
+
+    /*!
+     * Reconstruct missing primary variables (where elements are created/deleted)
+     *
+     * To reconstruct the solution in father elements, problem properties might
+     * need to be accessed.
+     * Starting from the lowest level, the old solution is mapped on the new grid:
+     * Where coarsened, new cells get information from old father element.
+     * Where refined, a new solution is reconstructed from the old father cell,
+     * and then a new son is created. That is then stored into the general data
+     * structure (CellData).
+     *
+     * @param problem The current problem
+     */
+    void reconstructPrimVars(Problem& problem)
+    {
+        adaptionMap_.resize();
+        std::vector<Scalar> massCoeff;
+        std::vector<Scalar> associatedMass;
+
+        if(isBox)
+        {
+            massCoeff.resize(problem.model().numDofs(),0.0);
+            associatedMass.resize(problem.model().numDofs(),0.0);
+        }
+
+        for (int level = 0; level <= problem.grid().maxLevel(); level++)
+        {
+            LevelGridView levelView = problem.grid().levelGridView(level);
+
+            for (const auto& element : elements(levelView))
+            {
+                // only treat non-ghosts, ghost data is communicated afterwards
+                if (element.partitionType() == Dune::GhostEntity)
+                    continue;
+
+                if (!element.isNew())
+                {
+                    //entry is in map, write in leaf
+                    if (element.isLeaf())
+                    {
+                        AdaptedValues &adaptedValues = adaptionMap_[element];
+
+                        FVElementGeometry fvGeometry;
+                        fvGeometry.update(problem.gridView(), element);
+
+                        for (int scvIdx = 0; scvIdx < fvGeometry.numScv; ++scvIdx)
+                        {
+                            // get index
+                            auto subEntity = element.template subEntity <dofCodim>(scvIdx);
+                            int dofIdx = problem.model().dofMapper().subIndex(element,scvIdx,dofCodim);
+
+                            this->setAdaptionValues(adaptedValues, problem.model().curSol()[dofIdx],scvIdx);
+
+                            if(isBox)
+                            {
+                                VolumeVariables volVars;
+                                volVars.update(adaptedValues.u[scvIdx],
+                                              problem,
+                                              element,
+                                              fvGeometry,
+                                              scvIdx,
+                                              false);
+
+                                Scalar volume = fvGeometry.subContVol[scvIdx].volume;
+                                Scalar volumeElement = fvGeometry.elementVolume;
+
+                                if (int(formulation) == pwsn)
+                                {
+                                    massCoeff[dofIdx] += volume * volVars.density(nPhaseIdx) * volVars.porosity();
+                                    associatedMass[dofIdx] += volume/volumeElement*adaptedValues.associatedMass[nPhaseIdx];
+                                }
+                                else if (int(formulation) == pnsw)
+                                {
+                                    massCoeff[dofIdx] += volume * volVars.density(wPhaseIdx) * volVars.porosity();
+                                    associatedMass[dofIdx] += volume/volumeElement*adaptedValues.associatedMass[wPhaseIdx];
+                                }
+                            }
+
+                        }
+
+                    }
+                }
+                else
+                {
+                    // value is not in map, interpolate from father element
+                    if (element.level() > 0 && element.hasFather())
+                    {
+                        auto eFather = element.father();
+                        FVElementGeometry fvGeometryFather;
+                        fvGeometryFather.update(problem.gridView(), eFather);
+                        Scalar massFather = 0.0;
+
+                        if(!isBox)
+                        {
+                            // create new entry: reconstruct from adaptionMap_[*father] to a new
+                            // adaptionMap_[*son]
+                            //this->reconstructAdaptionValues(this->adaptionMap_, eFather, element, problem);
+
+                            AdaptedValues& adaptedValuesFather = adaptionMap_[eFather];
+
+                            if (int(formulation) == pwsn)
+                            {
+                                massFather = adaptedValuesFather.associatedMass[nPhaseIdx];
+                            }
+                            else if (int(formulation) == pnsw)
+                            {
+                                massFather = adaptedValuesFather.associatedMass[wPhaseIdx];
+                            }
+
+                            // access new son
+                            AdaptedValues& adaptedValues = adaptionMap_[element];
+                            adaptedValues.count = 1;
+
+                            FVElementGeometry fvGeometry;
+                            fvGeometry.update(problem.gridView(), element);
+
+                            adaptedValues.u.push_back(adaptedValuesFather.u[0]);
+
+                            VolumeVariables volVars;
+                            volVars.update(adaptedValues.u[0],
+                                          problem,
+                                          element,
+                                          fvGeometry,
+                                          /*scvIdx=*/0,
+                                          false);
+
+                            Scalar volume = fvGeometry.subContVol[0].volume;
+                            Scalar massCoeffSon = 0.0;
+                            if (int(formulation) == pwsn)
+                            {
+                                massCoeffSon = volume * volVars.density(nPhaseIdx) * volVars.porosity();
+                            }
+                            else if (int(formulation) == pnsw)
+                            {
+                                massCoeffSon = volume * volVars.density(wPhaseIdx) * volVars.porosity();
+                            }
+                            Scalar volumeFather = eFather.geometry().volume();
+                            adaptedValues.u[0][saturationIdx] = volume/volumeFather*massFather/massCoeffSon;
+
+                            // if we are on leaf, store reconstructed values of son in CellData object
+                            if (element.isLeaf())
+                            {
+                                // acess new CellData object
+                                int newIdxI = this->elementIndex(problem, element);
+
+                                this->setAdaptionValues(adaptedValues, problem.model().curSol()[newIdxI],0);
+                            }
+                        }
+                        else
+                        {
+                            AdaptedValues& adaptedValuesFather = adaptionMap_[eFather];
+                            // access new son
+                            AdaptedValues& adaptedValues = adaptionMap_[element];
+                            adaptedValues.u.clear();
+                            adaptedValues.count = 1;
+
+                            const auto geometryI = element.geometry();
+
+                            FVElementGeometry fvGeometry;
+                            fvGeometry.update(problem.gridView(), element);
+
+                            for (int scvIdx = 0; scvIdx < fvGeometry.numScv; ++scvIdx)
+                            {
+                                auto subEntity = element.template subEntity <dofCodim>(scvIdx);
+
+                                LocalPosition dofCenterPos = geometryI.local(subEntity.geometry().center());
+                                const LocalFiniteElementCache feCache;
+                                Dune::GeometryType geomType = eFather.geometry().type();
+
+                                const LocalFiniteElement &localFiniteElement = feCache.get(geomType);
+                                std::vector<Dune::FieldVector<Scalar, 1> > shapeVal;
+                                localFiniteElement.localBasis().evaluateFunction(dofCenterPos, shapeVal);
+                                PrimaryVariables u(0);
+                                for (int j = 0; j < shapeVal.size(); ++j)
+                                {
+                                    u.axpy(shapeVal[j], adaptedValuesFather.u[j]);
+                                }
+
+                                adaptedValues.u.push_back(u);
+                                adaptedValues.count = 1;
+
+                                if (element.isLeaf())
+                                {
+                                    VolumeVariables volVars;
+                                    volVars.update(adaptedValues.u[scvIdx],
+                                                  problem,
+                                                  element,
+                                                  fvGeometry,
+                                                  scvIdx,
+                                                  false);
+
+                                    Scalar volume = fvGeometry.subContVol[scvIdx].volume;
+                                    Scalar volumeFather = eFather.geometry().volume();
+
+                                    //int dofIdx = this->dofIndex(problem, subEntity);
+                                    int dofIdx = problem.model().dofMapper().subIndex(element,scvIdx,dofCodim);
+                                    if (int(formulation) == pwsn)
+                                    {
+                                        massCoeff[dofIdx] += volume * volVars.density(nPhaseIdx) * volVars.porosity();
+                                        associatedMass[dofIdx] += volume/volumeFather*adaptedValuesFather.associatedMass[nPhaseIdx];
+                                    }
+                                    else if (int(formulation) == pnsw)
+                                    {
+                                        massCoeff[dofIdx] += volume * volVars.density(wPhaseIdx) * volVars.porosity();
+                                        associatedMass[dofIdx] += volume/volumeFather*adaptedValuesFather.associatedMass[wPhaseIdx];
+                                    }
+
+                                    this->setAdaptionValues(adaptedValues, problem.model().curSol()[dofIdx],scvIdx);
+                                }
+
+                            }
+                        }
+                    }
+
+                }
+            }
+
+        }
+
+        std::cout << "End of reconstructon" << std::endl;
+        if(isBox)
+        {
+            for(int dofIdx = 0; dofIdx < problem.model().numDofs(); dofIdx++)
+            {
+                problem.model().curSol()[dofIdx][saturationIdx] = associatedMass[dofIdx]/massCoeff[dofIdx];
+            }
+        }
+
+
+        // reset entries in restrictionmap
+        adaptionMap_.resize( typename PersistentContainer::Value() );
+        adaptionMap_.shrinkToFit();
+        adaptionMap_.fill( typename PersistentContainer::Value() );
+
+//#if HAVE_MPI
+//        // communicate ghost data
+//        typedef typename GET_PROP(TypeTag, SolutionTypes) SolutionTypes;
+//        typedef typename SolutionTypes::ElementMapper ElementMapper;
+//        typedef VectorExchange<ElementMapper, std::vector<CellData> > DataHandle;
+//        DataHandle dataHandle(problem.elementMapper(), this->cellDataGlobal());
+//        problem.gridView().template communicate<DataHandle>(dataHandle,
+//                                                            Dune::InteriorBorder_All_Interface,
+//                                                            Dune::ForwardCommunication);
+//#endif
+    }
+
+    //! Stores sons entries into father element for averaging
+    /**
+     * Sum up the adaptedValues (sons values) into father element. We store from leaf
+     * upwards, so sons are stored first, then cells on the next leaf (=fathers)
+     * can be averaged.
+     *
+     * \param adaptedValues Container for model-specific values to be adapted
+     * \param adaptedValuesFather Values to be adapted of father cell
+     */
+    static void storeAdaptionValues(AdaptedValues& adaptedValues,
+                                    AdaptedValues& adaptedValuesFather)
+    {
+        if(!isBox)
+        {
+            if(adaptedValuesFather.u.size() == 0) adaptedValuesFather.u.resize(1);
+
+            adaptedValuesFather.u[0] += adaptedValues.u[0];
+            adaptedValuesFather.u[0] /= adaptedValues.count;
+            adaptedValuesFather.associatedMass += adaptedValues.associatedMass;
+        }
+        else
+        {
+            //adaptedValuesFather.u = adaptedValues.u;
+            adaptedValuesFather.associatedMass += adaptedValues.associatedMass;
+        }
+    }
+    //! Set adapted values in CellData
+    /**
+     * This methods stores reconstructed values into the cellData object, by
+     * this setting a newly mapped solution to the storage container of the
+     * sequential models.
+     *
+     * \param adaptedValues Container for model-specific values to be adapted
+     * \param u The variables to be stored
+     */
+    static void setAdaptionValues(AdaptedValues& adaptedValues, PrimaryVariables& u, int scvIdx)
+    {
+        PrimaryVariables uNew(0);
+        if(!isBox)
+        {
+            uNew = adaptedValues.u[scvIdx];
+            uNew /= adaptedValues.count;
+        }
+        else
+        {
+            uNew = adaptedValues.u[scvIdx];
+        }
+
+        u = uNew;
+    }
+
+    //! Reconstructs sons entries from data of father cell
+    /**
+     * Reconstructs a new solution from a father cell into a newly
+     * generated son cell. New cell is stored into the global
+     * adaptionMap.
+     *
+     * \param adaptionMap Global map storing all values to be adapted
+     * \param father Entity Pointer to the father cell
+     * \param son Entity Pointer to the newly created son cell
+     * \param problem The problem
+     */
+    static void reconstructAdaptionValues(Dune::PersistentContainer<Grid, AdaptedValues>& adaptionMap,
+            const Element& father, const Element& son, const Problem& problem)
+    {
+        AdaptedValues& adaptedValues = adaptionMap[son];
+        AdaptedValues& adaptedValuesFather = adaptionMap[father];
+
+        adaptedValues.u = adaptedValuesFather.u;
+        adaptedValues.u /= adaptedValuesFather.count;
+    }
+
+
+
+};
+}
+#endif