From 2b21b18402945dad764b9370ea0ff1091c805bd0 Mon Sep 17 00:00:00 2001
From: Bernd Flemisch <bernd@iws.uni-stuttgart.de>
Date: Wed, 20 Jan 2016 14:12:50 +0100
Subject: [PATCH] [folder structure] rename and move files from
 implicit/1p2c,2p2c,2pnc,2pncmin,3p3c, adapt includes

---
 .../el1p2c/el1p2cfluxvariables.hh             |    2 +-
 dumux/geomechanics/el1p2c/el1p2cindices.hh    |    2 +-
 dumux/geomechanics/el1p2c/el1p2cproperties.hh |    2 +-
 .../el1p2c/el1p2cvolumevariables.hh           |    2 +-
 dumux/implicit/1p2c/1p2cfluxvariables.hh      |  525 +--------
 dumux/implicit/1p2c/1p2cindices.hh            |   63 +-
 dumux/implicit/1p2c/1p2clocalresidual.hh      |  265 +----
 dumux/implicit/1p2c/1p2cmodel.hh              |  194 +---
 dumux/implicit/1p2c/1p2cproperties.hh         |   82 +-
 dumux/implicit/1p2c/1p2cpropertydefaults.hh   |  159 +--
 dumux/implicit/1p2c/1p2cvolumevariables.hh    |  287 +----
 dumux/implicit/2p2c/2p2cfluxvariables.hh      |  255 +----
 dumux/implicit/2p2c/2p2cindices.hh            |  145 +--
 dumux/implicit/2p2c/2p2clocalresidual.hh      |  507 +-------
 dumux/implicit/2p2c/2p2cmodel.hh              |  725 +-----------
 dumux/implicit/2p2c/2p2cnewtoncontroller.hh   |  104 +-
 dumux/implicit/2p2c/2p2cproperties.hh         |   85 +-
 dumux/implicit/2p2c/2p2cpropertydefaults.hh   |  232 +---
 dumux/implicit/2p2c/2p2cvolumevariables.hh    |  621 +---------
 dumux/implicit/2pnc/2pncfluxvariables.hh      |  415 +------
 dumux/implicit/2pnc/2pncindices.hh            |   80 +-
 dumux/implicit/2pnc/2pnclocalresidual.hh      |  349 +-----
 dumux/implicit/2pnc/2pncmodel.hh              |  741 +-----------
 dumux/implicit/2pnc/2pncnewtoncontroller.hh   |  105 +-
 dumux/implicit/2pnc/2pncproperties.hh         |   82 +-
 dumux/implicit/2pnc/2pncpropertydefaults.hh   |  226 +---
 dumux/implicit/2pnc/2pncvolumevariables.hh    |  529 +--------
 .../implicit/2pncmin/2pncminfluxvariables.hh  |  162 +--
 dumux/implicit/2pncmin/2pncminindices.hh      |   48 +-
 .../implicit/2pncmin/2pncminlocalresidual.hh  |  140 +--
 dumux/implicit/2pncmin/2pncminmodel.hh        |  551 +--------
 dumux/implicit/2pncmin/2pncminproperties.hh   |   65 +-
 .../2pncmin/2pncminpropertydefaults.hh        |  143 +--
 .../2pncmin/2pncminvolumevariables.hh         |  549 +--------
 dumux/implicit/3p3c/3p3cfluxvariables.hh      |  386 +------
 dumux/implicit/3p3c/3p3cindices.hh            |   90 +-
 dumux/implicit/3p3c/3p3clocalresidual.hh      |  238 +---
 dumux/implicit/3p3c/3p3cmodel.hh              | 1020 +----------------
 dumux/implicit/3p3c/3p3cnewtoncontroller.hh   |   86 +-
 dumux/implicit/3p3c/3p3cproperties.hh         |   82 +-
 dumux/implicit/3p3c/3p3cpropertydefaults.hh   |  211 +---
 dumux/implicit/3p3c/3p3cvolumevariables.hh    |  750 +-----------
 dumux/implicit/co2/co2model.hh                |    2 +-
 dumux/implicit/co2/co2volumevariables.hh      |    2 +-
 .../2p2cnicouplinglocalresidual.hh            |    2 +-
 .../2cstokes2p2c/2cstokes2p2clocaloperator.hh |    2 +-
 .../2cstokes2p2c/2p2ccouplinglocalresidual.hh |    4 +-
 .../1p2c/implicit/fluxvariables.hh            |  525 +++++++++
 .../porousmediumflow/1p2c/implicit/indices.hh |   63 +
 .../1p2c/implicit/localresidual.hh            |  265 +++++
 dumux/porousmediumflow/1p2c/implicit/model.hh |  194 ++++
 .../1p2c/implicit/properties.hh               |   81 ++
 .../1p2c/implicit/propertydefaults.hh         |  158 +++
 .../1p2c/implicit/volumevariables.hh          |  287 +++++
 .../2p2c/implicit/fluxvariables.hh            |  255 +++++
 .../porousmediumflow/2p2c/implicit/indices.hh |  145 +++
 .../2p2c/implicit/localresidual.hh            |  507 ++++++++
 dumux/porousmediumflow/2p2c/implicit/model.hh |  725 ++++++++++++
 .../2p2c/implicit/newtoncontroller.hh         |  104 ++
 .../2p2c/implicit/properties.hh               |   85 ++
 .../2p2c/implicit/propertydefaults.hh         |  232 ++++
 .../2p2c/implicit/volumevariables.hh          |  621 ++++++++++
 .../2pnc/implicit/fluxvariables.hh            |  415 +++++++
 .../porousmediumflow/2pnc/implicit/indices.hh |   80 ++
 .../2pnc/implicit/localresidual.hh            |  349 ++++++
 dumux/porousmediumflow/2pnc/implicit/model.hh |  741 ++++++++++++
 .../2pnc/implicit/newtoncontroller.hh         |  105 ++
 .../2pnc/implicit/properties.hh               |   82 ++
 .../2pnc/implicit/propertydefaults.hh         |  225 ++++
 .../2pnc/implicit/volumevariables.hh          |  529 +++++++++
 .../2pncmin/implicit/fluxvariables.hh         |  162 +++
 .../2pncmin/implicit/indices.hh               |   48 +
 .../2pncmin/implicit/localresidual.hh         |  140 +++
 .../2pncmin/implicit/model.hh                 |  551 +++++++++
 .../2pncmin/implicit/properties.hh            |   65 ++
 .../2pncmin/implicit/propertydefaults.hh      |  143 +++
 .../2pncmin/implicit/volumevariables.hh       |  549 +++++++++
 .../3p3c/implicit/fluxvariables.hh            |  386 +++++++
 .../porousmediumflow/3p3c/implicit/indices.hh |   90 ++
 .../3p3c/implicit/localresidual.hh            |  238 ++++
 dumux/porousmediumflow/3p3c/implicit/model.hh | 1020 +++++++++++++++++
 .../3p3c/implicit/newtoncontroller.hh         |   86 ++
 .../3p3c/implicit/properties.hh               |   82 ++
 .../3p3c/implicit/propertydefaults.hh         |  210 ++++
 .../3p3c/implicit/volumevariables.hh          |  750 ++++++++++++
 .../2p/thermalconductivityjohansenproblem.hh  |    2 +-
 .../2p/thermalconductivitysomertonproblem.hh  |    2 +-
 .../2p/thermalconductivityspatialparams.hh    |    2 +-
 .../effectivediffusivityconstanttauproblem.hh |    2 +-
 ...ectivediffusivitymillingtonquirkproblem.hh |    2 +-
 .../effectivediffusivityspatialparams.hh      |    2 +-
 .../2cnistokes2p2cni/2p2cnisubproblem.hh      |    2 +-
 .../2cnizeroeq2p2cni/2p2cnisubproblem.hh      |    2 +-
 .../2cstokes2p2c/2p2csubproblem.hh            |    2 +-
 .../2czeroeq2p2c/2p2csubproblem.hh            |    2 +-
 .../1p2c/implicit/1p2cniconductionproblem.hh  |    2 +-
 .../1p2c/implicit/1p2cniconvectionproblem.hh  |    2 +-
 .../1p2c/implicit/1p2coutflowproblem.hh       |    2 +-
 .../2p2c/implicit/injectionproblem.hh         |    2 +-
 .../2p2c/implicit/injectionspatialparams.hh   |    2 +-
 .../2p2c/implicit/waterairproblem.hh          |    2 +-
 .../2p2c/implicit/waterairspatialparams.hh    |    2 +-
 .../2pnc/implicit/fuelcellproblem.hh          |    2 +-
 .../2pnc/implicit/fuelcellspatialparams.hh    |    2 +-
 .../2pncmin/implicit/dissolutionproblem.hh    |    2 +-
 .../implicit/dissolutionspatialparams.hh      |    2 +-
 .../3p/implicit/3pnispatialparams.hh          |    2 +-
 .../implicit/infiltration3pspatialparams.hh   |    2 +-
 .../3p3c/implicit/columnxylolproblem.hh       |    2 +-
 .../3p3c/implicit/columnxylolspatialparams.hh |    2 +-
 .../3p3c/implicit/infiltrationproblem.hh      |    2 +-
 .../implicit/infiltrationspatialparameters.hh |    2 +-
 .../3p3c/implicit/kuevetteproblem.hh          |    2 +-
 .../3p3c/implicit/kuevettespatialparams.hh    |    2 +-
 114 files changed, 11484 insertions(+), 11184 deletions(-)
 create mode 100644 dumux/porousmediumflow/1p2c/implicit/fluxvariables.hh
 create mode 100644 dumux/porousmediumflow/1p2c/implicit/indices.hh
 create mode 100644 dumux/porousmediumflow/1p2c/implicit/localresidual.hh
 create mode 100644 dumux/porousmediumflow/1p2c/implicit/model.hh
 create mode 100644 dumux/porousmediumflow/1p2c/implicit/properties.hh
 create mode 100644 dumux/porousmediumflow/1p2c/implicit/propertydefaults.hh
 create mode 100644 dumux/porousmediumflow/1p2c/implicit/volumevariables.hh
 create mode 100644 dumux/porousmediumflow/2p2c/implicit/fluxvariables.hh
 create mode 100644 dumux/porousmediumflow/2p2c/implicit/indices.hh
 create mode 100644 dumux/porousmediumflow/2p2c/implicit/localresidual.hh
 create mode 100644 dumux/porousmediumflow/2p2c/implicit/model.hh
 create mode 100644 dumux/porousmediumflow/2p2c/implicit/newtoncontroller.hh
 create mode 100644 dumux/porousmediumflow/2p2c/implicit/properties.hh
 create mode 100644 dumux/porousmediumflow/2p2c/implicit/propertydefaults.hh
 create mode 100644 dumux/porousmediumflow/2p2c/implicit/volumevariables.hh
 create mode 100644 dumux/porousmediumflow/2pnc/implicit/fluxvariables.hh
 create mode 100644 dumux/porousmediumflow/2pnc/implicit/indices.hh
 create mode 100644 dumux/porousmediumflow/2pnc/implicit/localresidual.hh
 create mode 100644 dumux/porousmediumflow/2pnc/implicit/model.hh
 create mode 100644 dumux/porousmediumflow/2pnc/implicit/newtoncontroller.hh
 create mode 100644 dumux/porousmediumflow/2pnc/implicit/properties.hh
 create mode 100644 dumux/porousmediumflow/2pnc/implicit/propertydefaults.hh
 create mode 100644 dumux/porousmediumflow/2pnc/implicit/volumevariables.hh
 create mode 100644 dumux/porousmediumflow/2pncmin/implicit/fluxvariables.hh
 create mode 100644 dumux/porousmediumflow/2pncmin/implicit/indices.hh
 create mode 100644 dumux/porousmediumflow/2pncmin/implicit/localresidual.hh
 create mode 100644 dumux/porousmediumflow/2pncmin/implicit/model.hh
 create mode 100644 dumux/porousmediumflow/2pncmin/implicit/properties.hh
 create mode 100644 dumux/porousmediumflow/2pncmin/implicit/propertydefaults.hh
 create mode 100644 dumux/porousmediumflow/2pncmin/implicit/volumevariables.hh
 create mode 100644 dumux/porousmediumflow/3p3c/implicit/fluxvariables.hh
 create mode 100644 dumux/porousmediumflow/3p3c/implicit/indices.hh
 create mode 100644 dumux/porousmediumflow/3p3c/implicit/localresidual.hh
 create mode 100644 dumux/porousmediumflow/3p3c/implicit/model.hh
 create mode 100644 dumux/porousmediumflow/3p3c/implicit/newtoncontroller.hh
 create mode 100644 dumux/porousmediumflow/3p3c/implicit/properties.hh
 create mode 100644 dumux/porousmediumflow/3p3c/implicit/propertydefaults.hh
 create mode 100644 dumux/porousmediumflow/3p3c/implicit/volumevariables.hh

diff --git a/dumux/geomechanics/el1p2c/el1p2cfluxvariables.hh b/dumux/geomechanics/el1p2c/el1p2cfluxvariables.hh
index f63352f585..29c4ac9a35 100644
--- a/dumux/geomechanics/el1p2c/el1p2cfluxvariables.hh
+++ b/dumux/geomechanics/el1p2c/el1p2cfluxvariables.hh
@@ -33,7 +33,7 @@
 #define DUMUX_ELASTIC1P2C_FLUX_VARIABLES_HH
 
 #include <dumux/geomechanics/elastic/elasticfluxvariables.hh>
-#include <dumux/implicit/1p2c/1p2cfluxvariables.hh>
+#include <dumux/porousmediumflow/1p2c/implicit/fluxvariables.hh>
 
 namespace Dumux
 {
diff --git a/dumux/geomechanics/el1p2c/el1p2cindices.hh b/dumux/geomechanics/el1p2c/el1p2cindices.hh
index 4d82313029..25346a73ee 100644
--- a/dumux/geomechanics/el1p2c/el1p2cindices.hh
+++ b/dumux/geomechanics/el1p2c/el1p2cindices.hh
@@ -27,7 +27,7 @@
 #define DUMUX_ELASTIC1P2C_INDICES_HH
 
 #include <dumux/geomechanics/elastic/elasticindices.hh>
-#include <dumux/implicit/1p2c/1p2cindices.hh>
+#include <dumux/porousmediumflow/1p2c/implicit/indices.hh>
 
 namespace Dumux
 {
diff --git a/dumux/geomechanics/el1p2c/el1p2cproperties.hh b/dumux/geomechanics/el1p2c/el1p2cproperties.hh
index cb913fd953..735524c243 100644
--- a/dumux/geomechanics/el1p2c/el1p2cproperties.hh
+++ b/dumux/geomechanics/el1p2c/el1p2cproperties.hh
@@ -32,7 +32,7 @@
 #ifndef DUMUX_ELASTIC1P2C_PROPERTIES_HH
 #define DUMUX_ELASTIC1P2C_PROPERTIES_HH
 
-#include <dumux/implicit/1p2c/1p2cproperties.hh>
+#include <dumux/porousmediumflow/1p2c/implicit/properties.hh>
 #include <dumux/geomechanics/elastic/elasticproperties.hh>
 
 
diff --git a/dumux/geomechanics/el1p2c/el1p2cvolumevariables.hh b/dumux/geomechanics/el1p2c/el1p2cvolumevariables.hh
index 8556e55a2b..b8d6017559 100644
--- a/dumux/geomechanics/el1p2c/el1p2cvolumevariables.hh
+++ b/dumux/geomechanics/el1p2c/el1p2cvolumevariables.hh
@@ -26,7 +26,7 @@
 #define DUMUX_ELASTIC1P2C_VOLUME_VARIABLES_HH
 
 
-#include <dumux/implicit/1p2c/1p2cvolumevariables.hh>
+#include <dumux/porousmediumflow/1p2c/implicit/volumevariables.hh>
 #include <dumux/implicit/volumevariables.hh>
 
 #include "el1p2cproperties.hh"
diff --git a/dumux/implicit/1p2c/1p2cfluxvariables.hh b/dumux/implicit/1p2c/1p2cfluxvariables.hh
index 641d9db8ff..496b22b6c1 100644
--- a/dumux/implicit/1p2c/1p2cfluxvariables.hh
+++ b/dumux/implicit/1p2c/1p2cfluxvariables.hh
@@ -1,525 +1,8 @@
-// -*- 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/>.   *
- *****************************************************************************/
-/*!
- * \file
- * \brief This file contains the data which is required to calculate
- *        all fluxes of fluid phases over a face of a finite volume.
- *
- * This means pressure and mole-fraction gradients, phase densities at
- * the integration point, etc.
- *
- */
-#ifndef DUMUX_1P2C_FLUX_VARIABLES_HH
-#define DUMUX_1P2C_FLUX_VARIABLES_HH
+#ifndef DUMUX_1P2C_FLUX_VARIABLES_HH_OLD
+#define DUMUX_1P2C_FLUX_VARIABLES_HH_OLD
 
-#include "1p2cproperties.hh"
+#warning this header is deprecated, use dumux/porousmediumflow/1p2c/implicit/fluxvariables.hh instead
 
-#include <dumux/common/math.hh>
-#include <dumux/common/valgrind.hh>
-
-namespace Dumux
-{
-
-/*!
- * \ingroup OnePTwoCModel
- * \ingroup ImplicitFluxVariables
- * \brief This template class contains the data which is required to
- *        calculate the fluxes of the fluid phases over a face of a
- *        finite volume for the one-phase, two-component model.
- *
- * This means pressure and mole-fraction gradients, phase densities at
- * the intergration point, etc.
- */
-template <class TypeTag>
-class OnePTwoCFluxVariables
-{
-    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
-    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, SpatialParams) SpatialParams;
-    typedef typename GET_PROP_TYPE(TypeTag, EffectiveDiffusivityModel) EffectiveDiffusivityModel;
-
-    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
-    enum {
-        transportCompIdx = Indices::transportCompIdx
-    };
-
-    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
-    typedef typename GridView::template Codim<0>::Entity Element;
-    enum {
-        dim = GridView::dimension,
-        dimWorld = GridView::dimensionworld
-    };
-
-    typedef typename GridView::ctype CoordScalar;
-    typedef Dune::FieldVector<CoordScalar, dimWorld> GlobalPosition;
-    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
-    typedef Dune::FieldVector<Scalar, dim> DimVector;
-    typedef Dune::FieldMatrix<Scalar, dim, dim> DimMatrix;
-    typedef Dune::FieldMatrix<Scalar, dimWorld, dimWorld> DimWorldMatrix;
-
-    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
-    typedef typename FVElementGeometry::SubControlVolumeFace SCVFace;
-
-public:
-    /*
-     * \brief The constructor
-     *
-     * \param problem The problem
-     * \param element The finite element
-     * \param fvGeometry The finite-volume geometry in the fully implicit scheme
-     * \param scvfIdx The local index of the SCV (sub-control-volume) face
-     * \param elemVolVars The volume variables of the current element
-     * \param onBoundary A boolean variable to specify whether the flux variables
-     * are calculated for interior SCV faces or boundary faces, default=false
-     */
-    OnePTwoCFluxVariables(const Problem &problem,
-                          const Element &element,
-                          const FVElementGeometry &fvGeometry,
-                          const int fIdx,
-                          const ElementVolumeVariables &elemVolVars,
-                          const bool onBoundary = false)
-        : fvGeometry_(fvGeometry), faceIdx_(fIdx), onBoundary_(onBoundary)
-    {
-        mobilityUpwindWeight_ = GET_PARAM_FROM_GROUP(TypeTag, Scalar, Implicit, MobilityUpwindWeight);
-
-        viscosity_ = Scalar(0);
-        molarDensity_ = Scalar(0);
-        density_ = Scalar(0);
-        potentialGrad_ = Scalar(0);
-        moleFractionGrad_ = Scalar(0);
-
-        calculateGradients_(problem, element, elemVolVars);
-        calculateK_(problem, element, elemVolVars);
-        calculateVelocities_(problem, element, elemVolVars);
-        calculatePorousDiffCoeff_(problem, element, elemVolVars);
-        calculateDispersionTensor_(problem, element, elemVolVars);
-    };
-
-public:
-    /*!
-    * \brief Return the pressure potential multiplied with the
-    *        intrinsic permeability  and the face normal which
-    *        goes from vertex i to vertex j.
-    *
-    * Note that the length of the face's normal is the area of the
-    * phase, so this is not the actual velocity but the integral of
-    * the velocity over the face's area. Also note that the phase
-    * mobility is not yet included here since this would require a
-    * decision on the upwinding approach (which is done in the
-    * actual model).
-    */
-   Scalar KmvpNormal() const
-   { return KmvpNormal_; }
-
-   /*!
-    * \brief Return the pressure potential multiplied with the
-    *        intrinsic permeability as vector (for velocity output).
-    */
-   GlobalPosition Kmvp() const
-   { return Kmvp_; }
-
-   /*!
-    * \brief The face of the current sub-control volume. This may be either
-    *        an inner sub-control-volume face or a SCV face on the boundary.
-    */
-   const SCVFace &face() const
-   {
-       if (onBoundary_)
-           return fvGeometry_.boundaryFace[faceIdx_];
-       else
-           return fvGeometry_.subContVolFace[faceIdx_];
-   }
-
-    /*!
-     * \brief Return the intrinsic permeability tensor \f$\mathrm{[m^2]}\f$.
-     */
-    const DimWorldMatrix &intrinsicPermeability() const
-    { return K_; }
-
-    /*!
-     * \brief Return the dispersion tensor \f$\mathrm{[m^2/s]}\f$.
-     */
-    const DimWorldMatrix &dispersionTensor() const
-    { return dispersionTensor_; }
-
-    /*!
-     * \brief Return the pressure potential gradient \f$\mathrm{[Pa/m]}\f$.
-     */
-    const GlobalPosition &potentialGrad() const
-    { return potentialGrad_; }
-
-
-    /*!
-     * \brief Return the mole-fraction gradient of a component in a phase \f$\mathrm{[mol/mol/m)]}\f$.
-     *
-     * \param compIdx The index of the considered component
-     */
-    const GlobalPosition &moleFractionGrad(int compIdx) const
-    {
-       if (compIdx != 1)
-       { DUNE_THROW(Dune::InvalidStateException,
-                "The 1p2c model is supposed to need "
-                "only the concentration gradient of "
-                "the second component!"); }
-       return moleFractionGrad_;
-    };
-
-    /*!
-    * \brief The binary diffusion coefficient for each fluid phase in the porous medium \f$\mathrm{[m^2/s]}\f$.
-    */
-    Scalar porousDiffCoeff() const
-    {
-        // TODO: tensorial porousDiffCoeff_usion coefficients
-        return porousDiffCoeff_;
-    };
-
-    /*!
-    * \brief Return viscosity \f$\mathrm{[Pa s]}\f$ of a phase at the integration
-    *        point.
-    */
-    Scalar viscosity() const
-    { return viscosity_;}
-
-    /*!
-     * \brief Return molar density \f$\mathrm{[mol/m^3]}\f$ of a phase at the integration
-     *        point.
-     */
-    Scalar molarDensity() const
-    { return molarDensity_; }
-
-    /*!
-     * \brief Return density \f$\mathrm{[kg/m^3]}\f$ of a phase at the integration
-     *        point.
-     */
-    Scalar density() const
-    { return density_; }
-
-    /*!
-     * \brief Given the intrinsic permeability times the pressure
-     *        potential gradient and SCV face normal for a phase,
-     *        return the local index of the upstream control volume
-     *        for a given phase.
-     *
-     *        \param normalFlux The flux over a face of the sub-control volume
-     */
-    int upstreamIdx(Scalar normalFlux) const
-    { return (normalFlux >= 0)?face().i:face().j; }
-
-    /*!
-     * \brief Given the intrinsic permeability times the pressure
-     *        potential gradient and SCV face normal for a phase,
-     *        return the local index of the downstream control volume
-     *        for a given phase.
-     *
-     *        \param normalFlux The flux over a face of the sub-control volume
-     */
-    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.
-    */
-    int upstreamIdx() const
-    { return upstreamIdx_; }
-
-    /*!
-     * \brief Return the local index of the downstream control volume
-     *        for a given phase.
-     */
-    int downstreamIdx() const
-    { return downstreamIdx_; }
-
-    /*!
-    * \brief Return the local index of the upstream control volume
-    *        for a given phase.
-    */
-    int upstreamIdx(int phaseIdx) const
-    { return upstreamIdx_; }
-
-    /*!
-     * \brief Return the local index of the downstream control volume
-     *        for a given phase.
-     */
-    int downstreamIdx(int phaseIdx) const
-    { return downstreamIdx_; }
-
-    /*!
-     * \brief Return the volumetric flux over a face of a given phase.
-     *
-     *        This is the calculated velocity multiplied by the unit normal
-     *        and the area of the face.
-     *        face().normal
-     *        has already the magnitude of the area.
-     *
-     * \param phaseIdx index of the phase
-     */
-    Scalar volumeFlux(const unsigned int phaseIdx) const
-    {
-        assert (phaseIdx == Indices::phaseIdx);
-        return volumeFlux_;
-    }
-
-protected:
-
-    /*!
-     * \brief Calculation of the pressure and mole-/mass-fraction gradients.
-     *
-     *        \param problem The considered problem file
-     *        \param element The considered element of the grid
-     *        \param elemVolVars The parameters stored in the considered element
-     */
-    void calculateGradients_(const Problem &problem,
-                             const Element &element,
-                             const ElementVolumeVariables &elemVolVars)
-    {
-        // loop over flux approximation points
-        for (unsigned int idx = 0; idx < face().numFap; idx++)
-        {
-            // FE gradient at vertex idx
-            const GlobalPosition &feGrad = face().grad[idx];
-
-            // index for the element volume variables
-            int volVarsIdx = face().fapIndices[idx];
-
-            // the pressure gradient
-            GlobalPosition tmp = feGrad;
-            tmp *= elemVolVars[volVarsIdx].pressure();
-            potentialGrad_ += tmp;
-
-            // the mole-fraction gradient
-            tmp = feGrad;
-            tmp *= elemVolVars[volVarsIdx].moleFraction(transportCompIdx);
-            moleFractionGrad_ += tmp;
-
-            // phase viscosity
-            viscosity_ += elemVolVars[volVarsIdx].viscosity()*face().shapeValue[idx];
-
-            //phase molar density
-            molarDensity_ += elemVolVars[volVarsIdx].molarDensity()*face().shapeValue[idx];
-
-            //phase density
-            density_ += elemVolVars[volVarsIdx].density()*face().shapeValue[idx];
-        }
-
-
-        ///////////////
-        // correct the pressure gradients by the gravitational acceleration
-        ///////////////
-        if (GET_PARAM_FROM_GROUP(TypeTag, bool, Problem, EnableGravity)) {
-            // calculate the phase density at the integration point. we
-            // only do this if the wetting phase is present in both cells
-            Scalar rhoI = elemVolVars[face().i].density();
-            Scalar rhoJ = elemVolVars[face().j].density();
-            Scalar density = (rhoI + rhoJ)/2;
-
-            // ask for the gravitational acceleration at the given SCV face
-            GlobalPosition g(problem.gravityAtPos(face().ipGlobal));
-
-            // make it a force
-            g *= density;
-
-            // calculate the final potential gradient
-            potentialGrad_ -= g;
-        }
-    }
-
-    /*!
-    * \brief Calculation of the harmonic mean of the intrinsic permeability
-    *        uses the meanK function in the boxspatialparameters.hh file in the folder
-    *        material/spatialparameters
-    *
-    *        \param problem The considered problem file
-    *        \param element The considered element of the grid
-    *        \param elemVolVars The parameters stored in the considered element
-    */
-    void calculateK_(const Problem &problem,
-                     const Element &element,
-                     const ElementVolumeVariables &elemVolVars)
-    {
-        const SpatialParams &sp = problem.spatialParams();
-        if (GET_PROP_VALUE(TypeTag, ImplicitIsBox))
-        {
-            sp.meanK(K_,
-                     sp.intrinsicPermeability(element,
-                                              fvGeometry_,
-                                              face().i),
-                     sp.intrinsicPermeability(element,
-                                              fvGeometry_,
-                                              face().j));
-        }
-        else
-        {
-            const Element& elementI = fvGeometry_.neighbors[face().i];
-            FVElementGeometry fvGeometryI;
-            fvGeometryI.subContVol[0].global = elementI.geometry().center();
-
-            const Element& elementJ = fvGeometry_.neighbors[face().j];
-            FVElementGeometry fvGeometryJ;
-            fvGeometryJ.subContVol[0].global = elementJ.geometry().center();
-
-            sp.meanK(K_,
-                     sp.intrinsicPermeability(elementI, fvGeometryI, 0),
-                     sp.intrinsicPermeability(elementJ, fvGeometryJ, 0));
-        }
-    }
-
-    /*!
-      * \brief Calculation of the velocity normal to face using Darcy's law.
-      *     Tensorial permeability is multiplied with the potential gradient and the face normal.
-      *     Identify upstream node of face.
-      *
-      *        \param problem The considered problem file
-      *        \param element The considered element of the grid
-      *        \param elemVolVars The parameters stored in the considered element
-      */
-    void calculateVelocities_(const Problem &problem,
-                              const Element &element,
-                              const ElementVolumeVariables &elemVolVars)
-    {
-        K_.mv(potentialGrad_, Kmvp_);
-        KmvpNormal_ = -(Kmvp_*face().normal);
-
-        // set the upstream and downstream vertices
-        upstreamIdx_ = face().i;
-        downstreamIdx_ = face().j;
-
-        if (KmvpNormal_ < 0)
-        {
-            std::swap(upstreamIdx_,
-                      downstreamIdx_);
-        }
-
-        volumeFlux_ = KmvpNormal_;
-        volumeFlux_ *= mobilityUpwindWeight_/elemVolVars[upstreamIdx_].viscosity()
-                    + (1.0 - mobilityUpwindWeight_)/elemVolVars[downstreamIdx_].viscosity();
-    }
-    /*!
-    * \brief Calculation of the effective diffusion coefficient.
-    *
-    *        \param problem The considered problem file
-    *        \param element The considered element of the grid
-    *        \param elemVolVars The parameters stored in the considered element
-    */
-    void calculatePorousDiffCoeff_(const Problem &problem,
-                                   const Element &element,
-                                   const ElementVolumeVariables &elemVolVars)
-    {
-        const VolumeVariables &volVarsI = elemVolVars[face().i];
-        const VolumeVariables &volVarsJ = elemVolVars[face().j];
-
-        const Scalar diffCoeffI = EffectiveDiffusivityModel::effectiveDiffusivity(volVarsI.porosity(),
-                                                                     /*sat=*/1.0,
-                                                                     volVarsI.diffCoeff());
-
-        const Scalar diffCoeffJ = EffectiveDiffusivityModel::effectiveDiffusivity(volVarsJ.porosity(),
-                                                                     /*sat=*/1.0,
-                                                                     volVarsJ.diffCoeff());
-
-        // -> harmonic mean
-        porousDiffCoeff_ = harmonicMean(diffCoeffI, diffCoeffJ);
-    }
-
-    /*!
-    * \brief Calculation of the dispersion.
-    *
-    *        \param problem The considered problem file
-    *        \param element The considered element of the grid
-    *        \param elemVolVars The parameters stored in the considered element
-    */
-    void calculateDispersionTensor_(const Problem &problem,
-                                    const Element &element,
-                                    const ElementVolumeVariables &elemVolVars)
-    {
-        const VolumeVariables &volVarsI = elemVolVars[face().i];
-        const VolumeVariables &volVarsJ = elemVolVars[face().j];
-
-        //calculate dispersivity at the interface: [0]: alphaL = longitudinal disp. [m], [1] alphaT = transverse disp. [m]
-        Scalar dispersivity[2];
-        dispersivity[0] = 0.5 * (volVarsI.dispersivity()[0] +  volVarsJ.dispersivity()[0]);
-        dispersivity[1] = 0.5 * (volVarsI.dispersivity()[1] +  volVarsJ.dispersivity()[1]);
-
-        //calculate velocity at interface: v = -1/mu * vDarcy = -1/mu * K * grad(p)
-        GlobalPosition velocity;
-        Valgrind::CheckDefined(potentialGrad());
-        Valgrind::CheckDefined(K_);
-        K_.mv(potentialGrad(), velocity);
-        velocity /= - 0.5 * (volVarsI.viscosity() + volVarsJ.viscosity());
-
-        //matrix multiplication of the velocity at the interface: vv^T
-        dispersionTensor_ = 0;
-        for (int i=0; i<dim; i++)
-            for (int j = 0; j<dim; j++)
-                dispersionTensor_[i][j] = velocity[i]*velocity[j];
-
-        //normalize velocity product --> vv^T/||v||, [m/s]
-        Scalar vNorm = velocity.two_norm();
-
-        dispersionTensor_ /= vNorm;
-        if (vNorm < 1e-20)
-            dispersionTensor_ = 0;
-
-        //multiply with dispersivity difference: vv^T/||v||*(alphaL - alphaT), [m^2/s] --> alphaL = longitudinal disp., alphaT = transverse disp.
-        dispersionTensor_ *= (dispersivity[0] - dispersivity[1]);
-
-        //add ||v||*alphaT to the main diagonal:vv^T/||v||*(alphaL - alphaT) + ||v||*alphaT, [m^2/s]
-        for (int i = 0; i<dim; i++)
-            dispersionTensor_[i][i] += vNorm*dispersivity[1];
-    }
-
-    const FVElementGeometry &fvGeometry_;
-    const int faceIdx_;
-    const bool onBoundary_;
-
-    //! pressure potential gradient
-    GlobalPosition potentialGrad_;
-    //! mole-fraction gradient
-    GlobalPosition moleFractionGrad_;
-    //! the effective diffusion coefficent in the porous medium
-    Scalar porousDiffCoeff_;
-
-    //! the dispersion tensor in the porous medium
-    DimWorldMatrix dispersionTensor_;
-
-    //! the intrinsic permeability tensor
-    DimWorldMatrix K_;
-    // intrinsic permeability times pressure potential gradient
-    GlobalPosition Kmvp_;
-    // projected on the face normal
-    Scalar KmvpNormal_;
-
-    // local index of the upwind vertex for each phase
-    int upstreamIdx_;
-    // local index of the downwind vertex for each phase
-    int downstreamIdx_;
-
-    //! viscosity of the fluid at the integration point
-    Scalar viscosity_;
-
-    //! molar densities of the fluid at the integration point
-    Scalar molarDensity_, density_;
-
-    Scalar volumeFlux_; //!< Velocity multiplied with normal (magnitude=area)
-    Scalar mobilityUpwindWeight_; //!< Upwind weight for mobility. Set to one for full upstream weighting
-};
-
-} // end namespace
+#include <dumux/porousmediumflow/1p2c/implicit/fluxvariables.hh>
 
 #endif
diff --git a/dumux/implicit/1p2c/1p2cindices.hh b/dumux/implicit/1p2c/1p2cindices.hh
index 8286d90dab..6c9fbe18d8 100644
--- a/dumux/implicit/1p2c/1p2cindices.hh
+++ b/dumux/implicit/1p2c/1p2cindices.hh
@@ -1,63 +1,8 @@
-// -*- 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/>.   *
- *****************************************************************************/
-/*!
- * \file
- * \brief Defines the primary variable and equation indices used by
- *        the 1p2c model
- */
+#ifndef DUMUX_1P2C_INDICES_HH_OLD
+#define DUMUX_1P2C_INDICES_HH_OLD
 
-#ifndef DUMUX_1P2C_INDICES_HH
-#define DUMUX_1P2C_INDICES_HH
+#warning this header is deprecated, use dumux/porousmediumflow/1p2c/implicit/indices.hh instead
 
-#include "1p2cproperties.hh"
-
-namespace Dumux
-{
-// \{
-
-/*!
- * \ingroup OnePTwoCModel
- * \ingroup ImplicitIndices
- * \brief The indices for the isothermal single-phase, two-component model.
- */
-template <class TypeTag, int PVOffset = 0>
-struct OnePTwoCIndices
-{
-
-    //! Set the default phase used by the fluid system to the first one
-    static const int phaseIdx = GET_PROP_VALUE(TypeTag, PhaseIdx);
-
-    //! Component indices
-    static const int phaseCompIdx = phaseIdx;//!< The index of the main component of the considered phase
-    //! The index of the transported (minor) component; ASSUMES phase indices of 0 and 1
-    static const int transportCompIdx = (unsigned int)(1-phaseIdx);
-
-    // Equation indices
-   static const int conti0EqIdx = PVOffset + 0; //!< continuity equation index
-   static const int transportEqIdx = PVOffset + 1; //!< transport equation index
-
-    // primary variable indices
-    static const int pressureIdx = PVOffset + 0; //!< pressure
-    static const int massOrMoleFracIdx = PVOffset + 1; //!< mole fraction of the second component
-};
-
-// \}
-}
+#include <dumux/porousmediumflow/1p2c/implicit/indices.hh>
 
 #endif
diff --git a/dumux/implicit/1p2c/1p2clocalresidual.hh b/dumux/implicit/1p2c/1p2clocalresidual.hh
index a2436001a0..d5e9917cdd 100644
--- a/dumux/implicit/1p2c/1p2clocalresidual.hh
+++ b/dumux/implicit/1p2c/1p2clocalresidual.hh
@@ -1,265 +1,8 @@
-// -*- 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/>.   *
- *****************************************************************************/
-/*!
- * \file
- *
- * \brief Element-wise calculation the local Jacobian for the single-phase,
- *        two-component model in the fully implicit scheme.
- */
+#ifndef DUMUX_ONEP_TWOC_LOCAL_RESIDUAL_HH_OLD
+#define DUMUX_ONEP_TWOC_LOCAL_RESIDUAL_HH_OLD
 
-#ifndef DUMUX_ONEP_TWOC_LOCAL_RESIDUAL_HH
-#define DUMUX_ONEP_TWOC_LOCAL_RESIDUAL_HH
+#warning this header is deprecated, use dumux/porousmediumflow/1p2c/implicit/localresidual.hh instead
 
-#include "1p2cproperties.hh"
-
-namespace Dumux
-{
-/*!
- *
- * \ingroup OnePTwoCModel
- * \ingroup ImplicitLocalResidual
- * \brief Calculate the local Jacobian for the single-phase,
- *        two-component model in the fully implicit scheme.
- *
- *  This class is used to fill the gaps in BoxLocalResidual for the 1p2c flow and transport.
- */
-template<class TypeTag>
-class OnePTwoCLocalResidual : public GET_PROP_TYPE(TypeTag, BaseLocalResidual)
-{
-protected:
-    typedef typename GET_PROP_TYPE(TypeTag, LocalResidual) Implementation;
-
-    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
-    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
-
-    enum { dim = GridView::dimension };
-    enum { dimWorld = GridView::dimensionworld };
-    typedef Dune::FieldVector<Scalar, dim> DimVector;
-    typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition;
-
-    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
-    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
-
-    enum {
-        //phase index
-        phaseIdx = Indices::phaseIdx,
-        transportCompIdx = Indices::transportCompIdx
-    };
-    // indices of the equations
-    enum {
-        conti0EqIdx = Indices::conti0EqIdx,
-        transportEqIdx = Indices::transportEqIdx
-    };
-
-    //! property that defines whether mole or mass fractions are used
-    static const bool useMoles = GET_PROP_VALUE(TypeTag, UseMoles);
-
-
-
-public:
-    /*!
-     * \brief Constructor. Sets the upwind weight.
-     */
-    OnePTwoCLocalResidual()
-    {
-        // retrieve the upwind weight for the mass conservation equations. Use the value
-        // specified via the property system as default, and overwrite
-        // it by the run-time parameter from the Dune::ParameterTree
-        upwindWeight_ = GET_PARAM_FROM_GROUP(TypeTag, Scalar, Implicit, MassUpwindWeight);
-    };
-
-    /*!
-     * \brief Evaluate the amount of all conservation quantities
-     *        (e.g. phase mass) within a finite volume.
-     *
-     *        \param storage The mass of the component within the sub-control volume
-     *        \param scvIdx The index of the considered face of the sub-control volume
-     *        \param usePrevSol Evaluate function with solution of current or previous time step
-     */
-    void computeStorage(PrimaryVariables &storage, const int scvIdx, const bool usePrevSol) const
-    {
-        // 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 &elemVolVars = usePrevSol ? this->prevVolVars_() : this->curVolVars_();
-        const VolumeVariables &volVars = elemVolVars[scvIdx];
-
-        storage = 0;
-        if(useMoles) // mole-fraction formulation
-        {
-            // storage term of continuity equation- molefractions
-            //careful: molarDensity changes with moleFrac!
-            storage[conti0EqIdx] += volVars.molarDensity()*volVars.porosity();
-            // storage term of the transport equation - molefractions
-            storage[transportEqIdx] +=
-                volVars.molarDensity()*volVars.moleFraction(transportCompIdx) *
-                volVars.porosity();
-        }
-        else // mass-fraction formulation
-        {
-            // storage term of continuity equation - massfractions
-            storage[conti0EqIdx] +=
-                volVars.density()*volVars.porosity();
-            //storage term of the transport equation - massfractions
-            storage[transportEqIdx] +=
-                volVars.density() * volVars.massFraction(transportCompIdx) * volVars.porosity();
-        }
-    }
-
-    /*!
-     * \brief Evaluate the mass flux over a face of a sub-control
-     *        volume.
-     *
-     *        \param flux The flux over the SCV (sub-control-volume) face for each component
-     *        \param fIdx The index of the considered face of the sub control volume
-     *        \param onBoundary A boolean variable to specify whether the flux variables
-     *               are calculated for interior SCV faces or boundary faces, default=false
-     */
-    void computeFlux(PrimaryVariables &flux, const int fIdx, const bool onBoundary=false) const
-    {
-        flux = 0;
-        FluxVariables fluxVars(this->problem_(),
-                               this->element_(),
-                               this->fvGeometry_(),
-                               fIdx,
-                               this->curVolVars_(),
-                               onBoundary);
-
-        asImp_()->computeAdvectiveFlux(flux, fluxVars);
-        asImp_()->computeDiffusiveFlux(flux, fluxVars);
-    }
-
-    /*!
-     * \brief Evaluate the advective mass flux of all components over
-     *        a face of a sub-control volume.
-     *
-     * \param flux The advective flux over the sub-control-volume face for each component
-     * \param fluxVars The flux variables at the current SCV
-     */
-    void computeAdvectiveFlux(PrimaryVariables &flux, const FluxVariables &fluxVars) const
-    {
-        ////////
-        // advective fluxes of all components in all phases
-        ////////
-
-        // data attached to upstream and the downstream vertices
-        // of the current phase
-        const VolumeVariables &up =
-            this->curVolVars_(fluxVars.upstreamIdx());
-        const VolumeVariables &dn =
-            this->curVolVars_(fluxVars.downstreamIdx());
-
-        if(!useMoles) //mass-fraction formulation
-        {
-            // total mass flux - massfraction
-            //KmvpNormal is the Darcy velocity multiplied with the normal vector, calculated in 1p2cfluxvariables.hh
-            flux[conti0EqIdx] +=
-                fluxVars.KmvpNormal() *
-                ((     upwindWeight_)*up.density()/up.viscosity()
-                 +
-                 ((1 - upwindWeight_)*dn.density()/dn.viscosity()));
-
-            // advective flux of the second component - massfraction
-            flux[transportEqIdx] +=
-                fluxVars.KmvpNormal() *
-                ((    upwindWeight_)*up.density() * up.massFraction(transportCompIdx)/up.viscosity()
-                 +
-                 (1 - upwindWeight_)*dn.density()*dn.massFraction(transportCompIdx)/dn.viscosity());
-        }
-        else //mole-fraction formulation
-        {
-            // total mass flux - molefraction
-            //KmvpNormal is the Darcy velocity multiplied with the normal vector, calculated in 1p2cfluxvariables.hh
-            flux[conti0EqIdx] +=
-                fluxVars.KmvpNormal() *
-                ((     upwindWeight_)*up.molarDensity()/up.viscosity()
-                 +
-                 ((1 - upwindWeight_)*dn.molarDensity()/dn.viscosity()));
-
-            // advective flux of the second component -molefraction
-            flux[transportEqIdx] +=
-                fluxVars.KmvpNormal() *
-                ((    upwindWeight_)*up.molarDensity() * up.moleFraction(transportCompIdx)/up.viscosity()
-                 +
-                 (1 - upwindWeight_)*dn.molarDensity() * dn.moleFraction(transportCompIdx)/dn.viscosity());
-        }
-
-    }
-
-    /*!
-     * \brief Adds the diffusive mass flux of all components over
-     *        a face of a sub-control volume.
-     *
-     * \param flux The diffusive flux over the sub-control-volume face for each component
-     * \param fluxVars The flux variables at the current SCV
-     */
-    void computeDiffusiveFlux(PrimaryVariables &flux, const FluxVariables &fluxVars) const
-    {
-        Scalar tmp(0);
-
-        // diffusive flux of second component
-        if(useMoles) // mole-fraction formulation
-        {
-            // diffusive flux of the second component - molefraction
-            tmp = -(fluxVars.moleFractionGrad(transportCompIdx)*fluxVars.face().normal);
-            tmp *= fluxVars.porousDiffCoeff() * fluxVars.molarDensity();
-
-            // dispersive flux of second component - molefraction
-                        GlobalPosition normalDisp;
-                        fluxVars.dispersionTensor().mv(fluxVars.face().normal, normalDisp);
-                        tmp -= fluxVars.molarDensity()*
-                            (normalDisp * fluxVars.moleFractionGrad(transportCompIdx));
-
-            flux[transportEqIdx] += tmp;
-        }
-        else // mass-fraction formulation
-        {
-            // diffusive flux of the second component - massfraction
-            tmp = -(fluxVars.moleFractionGrad(transportCompIdx)*fluxVars.face().normal);
-            tmp *= fluxVars.porousDiffCoeff() * fluxVars.molarDensity();
-
-            // dispersive flux of second component - massfraction
-                       GlobalPosition normalDisp;
-                       fluxVars.dispersionTensor().mv(fluxVars.face().normal, normalDisp);
-                       tmp -= fluxVars.molarDensity()*
-                       (normalDisp * fluxVars.moleFractionGrad(transportCompIdx));
-
-            // convert it to a mass flux and add it
-            flux[transportEqIdx] += tmp * FluidSystem::molarMass(transportCompIdx);
-        }
-    }
-
-    Implementation *asImp_()
-    { return static_cast<Implementation *> (this); }
-    const Implementation *asImp_() const
-    { return static_cast<const Implementation *> (this); }
-
-private:
-    Scalar upwindWeight_;
-};
-
-}
+#include <dumux/porousmediumflow/1p2c/implicit/localresidual.hh>
 
 #endif
diff --git a/dumux/implicit/1p2c/1p2cmodel.hh b/dumux/implicit/1p2c/1p2cmodel.hh
index be109ff96e..b3f56c7ac8 100644
--- a/dumux/implicit/1p2c/1p2cmodel.hh
+++ b/dumux/implicit/1p2c/1p2cmodel.hh
@@ -1,194 +1,8 @@
-// -*- 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/>.   *
- *****************************************************************************/
-/*!
- * \file
- *
- * \brief Base class for all models which use the single-phase,
- *        two-component fully implicit model.
- *        Adaption of the fully implicit scheme to the one-phase two-component flow model.
- */
+#ifndef DUMUX_ONEP_TWOC_MODEL_HH_OLD
+#define DUMUX_ONEP_TWOC_MODEL_HH_OLD
 
-#ifndef DUMUX_ONEP_TWOC_MODEL_HH
-#define DUMUX_ONEP_TWOC_MODEL_HH
+#warning this header is deprecated, use dumux/porousmediumflow/1p2c/implicit/model.hh instead
 
-#include <dumux/porousmediumflow/implicit/velocityoutput.hh>
-#include "1p2cproperties.hh"
-
-namespace Dumux
-{
-
-/*!
- * \ingroup OnePTwoCModel
- * \brief Adaption of the fully implicit scheme to the one-phase two-component flow model.
- *
- * This model implements a one-phase flow of a compressible fluid, that consists of two components,
- * using a standard Darcy
- * approach as the equation for the conservation of momentum:
- \f[
- v = - \frac{\textbf K}{\mu}
- \left(\textbf{grad}\, p - \varrho {\textbf g} \right)
- \f]
- *
- * Gravity can be enabled or disabled via the property system.
- * By inserting this into the continuity equation, one gets
- \f[
- \phi\frac{\partial \varrho}{\partial t} - \text{div} \left\{
-   \varrho \frac{\textbf K}{\mu}  \left(\textbf{grad}\, p - \varrho {\textbf g} \right)
- \right\} = q \;,
- \f]
- *
- * The transport of the components \f$\kappa \in \{ w, a \}\f$ is described by the following equation:
- \f[
- \phi \frac{ \partial \varrho X^\kappa}{\partial t}
- - \text{div} \left\lbrace \varrho X^\kappa \frac{{\textbf K}}{\mu} \left( \textbf{grad}\, p -
- \varrho {\textbf g} \right)
- + \varrho D^\kappa_\text{pm} \frac{M^\kappa}{M_\alpha} \textbf{grad} x^\kappa \right\rbrace = q.
- \f]
- *
- * All equations are discretized using a vertex-centered finite volume (box)
- * or cell-centered finite volume scheme as spatial
- * and the implicit Euler method as time discretization.
- * The model is able to use either mole or mass fractions. The property useMoles can be set to either true or false in the
- * problem file. Make sure that the according units are used in the problem setup. useMoles is set to true by default.
- *
- * The primary variables are the pressure \f$p\f$ and the mole or mass fraction of dissolved component \f$x\f$.
- */
-
-template<class TypeTag >
-class OnePTwoCModel : public GET_PROP_TYPE(TypeTag, BaseModel)
-{
-    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
-    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
-    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector;
-
-    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
-    enum { dim = GridView::dimension };
-    enum { dimWorld = GridView::dimensionworld };
-
-    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
-    enum { phaseIdx = Indices::phaseIdx };
-
-    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
-
-    enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) };
-    enum { dofCodim = isBox ? dim : 0 };
-
-public:
-    /*!
-     * \brief \copybrief ImplicitModel::addOutputVtkFields
-     *
-     * Specialization for the OnePTwoCModel, adding pressure,
-     * mass and mole fractions, and the process rank to the VTK writer.
-     */
-    template<class MultiWriter>
-    void addOutputVtkFields(const SolutionVector &sol,
-                            MultiWriter &writer)
-    {
-        typedef Dune::BlockVector<Dune::FieldVector<double, 1> > ScalarField;
-        typedef Dune::BlockVector<Dune::FieldVector<double, dimWorld> > VectorField;
-
-        // create the required scalar fields
-        unsigned numDofs = this->numDofs();
-        ScalarField &pressure = *writer.allocateManagedBuffer(numDofs);
-        ScalarField &delp = *writer.allocateManagedBuffer(numDofs);
-        ScalarField &moleFraction0 = *writer.allocateManagedBuffer(numDofs);
-        ScalarField &moleFraction1 = *writer.allocateManagedBuffer(numDofs);
-        ScalarField &massFraction0 = *writer.allocateManagedBuffer(numDofs);
-        ScalarField &massFraction1 = *writer.allocateManagedBuffer(numDofs);
-        ScalarField &rho = *writer.allocateManagedBuffer(numDofs);
-        ScalarField &mu = *writer.allocateManagedBuffer(numDofs);
-        VectorField *velocity = writer.template allocateManagedBuffer<double, dimWorld>(numDofs);
-        ImplicitVelocityOutput<TypeTag> velocityOutput(this->problem_());
-
-        if (velocityOutput.enableOutput())
-        {
-            // initialize velocity field
-            for (unsigned int i = 0; i < numDofs; ++i)
-            {
-                (*velocity)[i] = Scalar(0);
-            }
-        }
-
-        unsigned numElements = this->gridView_().size(0);
-        ScalarField &rank = *writer.allocateManagedBuffer(numElements);
-
-        for (const auto& element : Dune::elements(this->gridView_()))
-        {
-            if(element.partitionType() == Dune::InteriorEntity)
-            {
-                int eIdx = this->problem_().model().elementMapper().index(element);
-
-                rank[eIdx] = this->gridView_().comm().rank();
-
-                FVElementGeometry fvGeometry;
-                fvGeometry.update(this->gridView_(), element);
-
-                ElementVolumeVariables elemVolVars;
-                elemVolVars.update(this->problem_(),
-                                   element,
-                                   fvGeometry,
-                                   false /* oldSol? */);
-
-                for (int scvIdx = 0; scvIdx < fvGeometry.numScv; ++scvIdx)
-                {
-                    int dofIdxGlobal = this->dofMapper().subIndex(element, scvIdx, dofCodim);
-
-                    pressure[dofIdxGlobal] = elemVolVars[scvIdx].pressure();
-                    delp[dofIdxGlobal] = elemVolVars[scvIdx].pressure() - 1e5;
-                    moleFraction0[dofIdxGlobal] = elemVolVars[scvIdx].moleFraction(0);
-                    moleFraction1[dofIdxGlobal] = elemVolVars[scvIdx].moleFraction(1);
-                    massFraction0[dofIdxGlobal] = elemVolVars[scvIdx].massFraction(0);
-                    massFraction1[dofIdxGlobal] = elemVolVars[scvIdx].massFraction(1);
-                    rho[dofIdxGlobal] = elemVolVars[scvIdx].density();
-                    mu[dofIdxGlobal] = elemVolVars[scvIdx].viscosity();
-                }
-
-                // velocity output
-                velocityOutput.calculateVelocity(*velocity, elemVolVars, fvGeometry, element, phaseIdx);
-            }
-        }
-
-        writer.attachDofData(pressure, "P", isBox);
-        writer.attachDofData(delp, "delp", isBox);
-        if (velocityOutput.enableOutput())
-        {
-            writer.attachDofData(*velocity,  "velocity", isBox, dim);
-        }
-        char nameMoleFraction0[42], nameMoleFraction1[42];
-        snprintf(nameMoleFraction0, 42, "x_%s", FluidSystem::componentName(0));
-        snprintf(nameMoleFraction1, 42, "x_%s", FluidSystem::componentName(1));
-        writer.attachDofData(moleFraction0, nameMoleFraction0, isBox);
-        writer.attachDofData(moleFraction1, nameMoleFraction1, isBox);
-
-        char nameMassFraction0[42], nameMassFraction1[42];
-        snprintf(nameMassFraction0, 42, "X_%s", FluidSystem::componentName(0));
-        snprintf(nameMassFraction1, 42, "X_%s", FluidSystem::componentName(1));
-        writer.attachDofData(massFraction0, nameMassFraction0, isBox);
-        writer.attachDofData(massFraction1, nameMassFraction1, isBox);
-        writer.attachDofData(rho, "rho", isBox);
-        writer.attachDofData(mu, "mu", isBox);
-        writer.attachCellData(rank, "process rank");
-    }
-};
-}
-
-#include "1p2cpropertydefaults.hh"
+#include <dumux/porousmediumflow/1p2c/implicit/model.hh>
 
 #endif
diff --git a/dumux/implicit/1p2c/1p2cproperties.hh b/dumux/implicit/1p2c/1p2cproperties.hh
index 5f511818b8..2d5a957ee5 100644
--- a/dumux/implicit/1p2c/1p2cproperties.hh
+++ b/dumux/implicit/1p2c/1p2cproperties.hh
@@ -1,82 +1,8 @@
-// -*- 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/>.   *
- *****************************************************************************/
-/*!
- * \ingroup Properties
- * \ingroup ImplicitProperties
- * \ingroup OnePTwoCModel
- * \file
- *
- * \brief Defines the properties required for the single-phase,
- *        two-component fully implicit model.
- */
+#ifndef DUMUX_1P2C_PROPERTIES_HH_OLD
+#define DUMUX_1P2C_PROPERTIES_HH_OLD
 
-#ifndef DUMUX_1P2C_PROPERTIES_HH
-#define DUMUX_1P2C_PROPERTIES_HH
+#warning this header is deprecated, use dumux/porousmediumflow/1p2c/implicit/properties.hh instead
 
-
-#include <dumux/implicit/box/properties.hh>
-#include <dumux/implicit/cellcentered/properties.hh>
-#include <dumux/porousmediumflow/nonisothermal/implicit/properties.hh>
-
-namespace Dumux
-{
-// \{
-namespace Properties
-{
-
-//////////////////////////////////////////////////////////////////
-// Type tags
-//////////////////////////////////////////////////////////////////
-
-//! The type tags for the implicit isothermal one-phase two-component problems
-NEW_TYPE_TAG(OnePTwoC);
-NEW_TYPE_TAG(BoxOnePTwoC, INHERITS_FROM(BoxModel, OnePTwoC));
-NEW_TYPE_TAG(CCOnePTwoC, INHERITS_FROM(CCModel, OnePTwoC));
-
-//! The type tags for the corresponding non-isothermal problems
-NEW_TYPE_TAG(OnePTwoCNI, INHERITS_FROM(OnePTwoC, NonIsothermal));
-NEW_TYPE_TAG(BoxOnePTwoCNI, INHERITS_FROM(BoxModel, OnePTwoCNI));
-NEW_TYPE_TAG(CCOnePTwoCNI, INHERITS_FROM(CCModel, OnePTwoCNI));
-
-//////////////////////////////////////////////////////////////////
-// Property tags
-//////////////////////////////////////////////////////////////////
-
-NEW_PROP_TAG(NumPhases);   //!< Number of fluid phases in the system
-NEW_PROP_TAG(PhaseIdx); //!< A phase index in to allow that a two-phase fluidsystem is used
-NEW_PROP_TAG(NumComponents);   //!< Number of fluid components in the system
-NEW_PROP_TAG(Indices); //!< Enumerations for the model
-NEW_PROP_TAG(SpatialParams); //!< The type of the spatial parameters
-NEW_PROP_TAG(EffectiveDiffusivityModel); //!< The employed model for the computation of the effective diffusivity
-NEW_PROP_TAG(FluidSystem); //!< Type of the multi-component relations
-NEW_PROP_TAG(FluidState); //!< Type of the fluid state to be used
-NEW_PROP_TAG(ImplicitMassUpwindWeight);   //!< The default value of the upwind weight
-NEW_PROP_TAG(ImplicitMobilityUpwindWeight); //!< Weight for the upwind mobility in the velocity calculation
-NEW_PROP_TAG(ProblemEnableGravity); //!< Returns whether gravity is considered in the problem
-NEW_PROP_TAG(UseMoles); //!< Defines whether mole (true) or mass (false) fractions are used
-NEW_PROP_TAG(Scaling); //!< Defines Scaling of the model
-NEW_PROP_TAG(SpatialParamsForchCoeff); //!< Property for the forchheimer coefficient
-NEW_PROP_TAG(VtkAddVelocity); //!< Returns whether velocity vectors are written into the vtk output
-
-}
-// \}
-}
+#include <dumux/porousmediumflow/1p2c/implicit/properties.hh>
 
 #endif
-
diff --git a/dumux/implicit/1p2c/1p2cpropertydefaults.hh b/dumux/implicit/1p2c/1p2cpropertydefaults.hh
index 7ce6e1294c..4561396de6 100644
--- a/dumux/implicit/1p2c/1p2cpropertydefaults.hh
+++ b/dumux/implicit/1p2c/1p2cpropertydefaults.hh
@@ -1,159 +1,8 @@
-// -*- 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/>.   *
- *****************************************************************************/
-/*!
- * \ingroup Properties
- * \ingroup ImplicitProperties
- * \ingroup OnePTwoCModel
- * \file
- *
- * \brief Defines some default values for the properties of the the
- *        single-phase, two-component fully implicit model.
- */
+#ifndef DUMUX_1P2C_PROPERTY_DEFAULTS_HH_OLD
+#define DUMUX_1P2C_PROPERTY_DEFAULTS_HH_OLD
 
-#ifndef DUMUX_1P2C_PROPERTY_DEFAULTS_HH
-#define DUMUX_1P2C_PROPERTY_DEFAULTS_HH
+#warning this header is deprecated, use dumux/porousmediumflow/1p2c/implicit/propertydefaults.hh instead
 
-#include "1p2cproperties.hh"
-#include "1p2cmodel.hh"
-#include "1p2clocalresidual.hh"
-#include "1p2cvolumevariables.hh"
-#include "1p2cfluxvariables.hh"
-#include "1p2cindices.hh"
-
-#include <dumux/porousmediumflow/nonisothermal/implicit/propertydefaults.hh>
-#include <dumux/material/spatialparams/implicitspatialparams1p.hh>
-#include <dumux/material/fluidmatrixinteractions/diffusivitymillingtonquirk.hh>
-#include <dumux/material/fluidmatrixinteractions/1p/thermalconductivityaverage.hh>
-#include <dumux/material/fluidstates/compositionalfluidstate.hh>
-
-namespace Dumux
-{
-// \{
-namespace Properties
-{
-//////////////////////////////////////////////////////////////////
-// Property values
-//////////////////////////////////////////////////////////////////
-
-
-SET_INT_PROP(OnePTwoC, NumEq, 2); //!< set the number of equations to 2
-SET_INT_PROP(OnePTwoC, NumPhases, 1); //!< The number of phases in the 1p2c model is 1
-SET_INT_PROP(OnePTwoC, NumComponents, 2); //!< The number of components in the 1p2c model is 2
-SET_SCALAR_PROP(OnePTwoC, Scaling, 1); //!< Scaling of the model is set to 1 by default
-SET_BOOL_PROP(OnePTwoC, UseMoles, true); //!< Define that mole fractions are used in the balance equations
-
-//! Use the 1p2c local residual function for the 1p2c model
-SET_TYPE_PROP(OnePTwoC, LocalResidual, OnePTwoCLocalResidual<TypeTag>);
-
-//! define the model
-SET_TYPE_PROP(OnePTwoC, Model, OnePTwoCModel<TypeTag>);
-
-//! define the VolumeVariables
-SET_TYPE_PROP(OnePTwoC, VolumeVariables, OnePTwoCVolumeVariables<TypeTag>);
-
-//! define the FluxVariables
-SET_TYPE_PROP(OnePTwoC, FluxVariables, OnePTwoCFluxVariables<TypeTag>);
-
-/*!
- * \brief The fluid state which is used by the volume variables to
- *        store the thermodynamic state. This should be chosen
- *        appropriately for the model ((non-)isothermal, equilibrium, ...).
- *        This can be done in the problem.
- */
-SET_PROP(OnePTwoC, FluidState){
-    private:
-        typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
-        typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
-    public:
-        typedef Dumux::CompositionalFluidState<Scalar, FluidSystem> type;
-};
-
-//! set default upwind weight to 1.0, i.e. fully upwind
-SET_SCALAR_PROP(OnePTwoC, ImplicitMassUpwindWeight, 1.0);
-
-//! weight for the upwind mobility in the velocity calculation
-SET_SCALAR_PROP(OnePTwoC, ImplicitMobilityUpwindWeight, 1.0);
-
-//! Set the indices used by the 1p2c model
-SET_TYPE_PROP(OnePTwoC, Indices, OnePTwoCIndices<TypeTag>);
-//! The spatial parameters to be employed.
-//! Use ImplicitSpatialParamsOneP by default.
-SET_TYPE_PROP(OnePTwoC, SpatialParams, ImplicitSpatialParamsOneP<TypeTag>);
-
-//! The model after Millington (1961) is used for the effective diffusivity
-SET_PROP(OnePTwoC, EffectiveDiffusivityModel)
-{ private :
-    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
- public:
-    typedef DiffusivityMillingtonQuirk<Scalar> type;
-};
-
-//! Set the phaseIndex per default to zero (important for two-phase fluidsystems).
-SET_INT_PROP(OnePTwoC, PhaseIdx, 0);
-
-// disable velocity output by default
-SET_BOOL_PROP(OnePTwoC, VtkAddVelocity, false);
-
-// enable gravity by default
-SET_BOOL_PROP(OnePTwoC, ProblemEnableGravity, true);
-
-//! default value for the forchheimer coefficient
-// Source: Ward, J.C. 1964 Turbulent flow in porous media. ASCE J. Hydraul. Div 90.
-//        Actually the Forchheimer coefficient is also a function of the dimensions of the
-//        porous medium. Taking it as a constant is only a first approximation
-//        (Nield, Bejan, Convection in porous media, 2006, p. 10)
-SET_SCALAR_PROP(OnePTwoC, SpatialParamsForchCoeff, 0.55);
-
-//! average is used as default model to compute the effective thermal heat conductivity
-SET_PROP(OnePTwoCNI, ThermalConductivityModel)
-{ private :
-    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
-  public:
-    typedef ThermalConductivityAverage<Scalar> type;
-};
-
-//////////////////////////////////////////////////////////////////
-// Property values for isothermal model required for the general non-isothermal model
-//////////////////////////////////////////////////////////////////
-
-// set isothermal Model
-SET_TYPE_PROP(OnePTwoCNI, IsothermalModel, OnePTwoCModel<TypeTag>);
-
-// set isothermal FluxVariables
-SET_TYPE_PROP(OnePTwoCNI, IsothermalFluxVariables, OnePTwoCFluxVariables<TypeTag>);
-
-//set isothermal VolumeVariables
-SET_TYPE_PROP(OnePTwoCNI, IsothermalVolumeVariables, OnePTwoCVolumeVariables<TypeTag>);
-
-//set isothermal LocalResidual
-SET_TYPE_PROP(OnePTwoCNI, IsothermalLocalResidual, OnePTwoCLocalResidual<TypeTag>);
-
-//set isothermal Indices
-SET_TYPE_PROP(OnePTwoCNI, IsothermalIndices, OnePTwoCIndices<TypeTag>);
-
-//set isothermal NumEq
-SET_INT_PROP(OnePTwoCNI, IsothermalNumEq, 2);
-
-
-}
-// \}
-}
+#include <dumux/porousmediumflow/1p2c/implicit/propertydefaults.hh>
 
 #endif
-
diff --git a/dumux/implicit/1p2c/1p2cvolumevariables.hh b/dumux/implicit/1p2c/1p2cvolumevariables.hh
index f056c80b52..df0103b0d2 100644
--- a/dumux/implicit/1p2c/1p2cvolumevariables.hh
+++ b/dumux/implicit/1p2c/1p2cvolumevariables.hh
@@ -1,287 +1,8 @@
-// -*- 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/>.   *
- *****************************************************************************/
-/*!
- * \file
- * \brief Quantities required by the single-phase, two-component box
- *        model defined on a vertex.
- */
-#ifndef DUMUX_1P2C_VOLUME_VARIABLES_HH
-#define DUMUX_1P2C_VOLUME_VARIABLES_HH
+#ifndef DUMUX_1P2C_VOLUME_VARIABLES_HH_OLD
+#define DUMUX_1P2C_VOLUME_VARIABLES_HH_OLD
 
-#include <dumux/implicit/volumevariables.hh>
+#warning this header is deprecated, use dumux/porousmediumflow/1p2c/implicit/volumevariables.hh instead
 
-#include "1p2cproperties.hh"
-
-namespace Dumux
-{
-
-/*!
- * \ingroup OnePTwoCModel
- * \ingroup ImplicitVolumeVariables
- * \brief Contains the quantities which are constant within a
- *        finite volume in the single-phase, two-component model.
- */
-template <class TypeTag>
-class OnePTwoCVolumeVariables : public ImplicitVolumeVariables<TypeTag>
-{
-    typedef ImplicitVolumeVariables<TypeTag> ParentType;
-
-    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
-    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) Implementation;
-    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
-    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
-    static const bool useMoles = GET_PROP_VALUE(TypeTag, UseMoles);
-
-    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
-    enum {
-        phaseIdx = Indices::phaseIdx,
-        phaseCompIdx = Indices::phaseCompIdx,
-        transportCompIdx = Indices::transportCompIdx
-    };
-    //indices of primary variables
-    enum{
-        pressureIdx = Indices::pressureIdx,
-        massOrMoleFracIdx = Indices::massOrMoleFracIdx
-    };
-
-    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
-    typedef typename GridView::template Codim<0>::Entity Element;
-    enum { dim = GridView::dimension };
-    enum { dimWorld = GridView::dimensionworld };
-
-    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
-    typedef Dune::FieldVector<Scalar,dim> DimVector;
-    typedef Dune::FieldVector<Scalar,dimWorld> GlobalPosition;
-
-public:
-
-    typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState;
-
-    /*!
-     * \copydoc ImplicitVolumeVariables::update
-     */
-    void update(const PrimaryVariables &priVars,
-                const Problem &problem,
-                const Element &element,
-                const FVElementGeometry &fvGeometry,
-                const int scvIdx,
-                const bool isOldSol)
-    {
-        ParentType::update(priVars, problem, element, fvGeometry, scvIdx, isOldSol);
-
-        //calculate all secondary variables from the primary variables and store results in fluidstate
-        completeFluidState(priVars, problem, element, fvGeometry, scvIdx, fluidState_);
-
-        porosity_ = problem.spatialParams().porosity(element, fvGeometry, scvIdx);
-
-        dispersivity_ = problem.spatialParams().dispersivity(element, fvGeometry, scvIdx);
-
-        // Second instance of a parameter cache.
-        // Could be avoided if diffusion coefficients also
-        // became part of the fluid state.
-        typename FluidSystem::ParameterCache paramCache;
-        paramCache.updatePhase(fluidState_, phaseIdx);
-
-        diffCoeff_ = FluidSystem::binaryDiffusionCoefficient(fluidState_,
-                                                             paramCache,
-                                                             phaseIdx,
-                                                             phaseCompIdx,
-                                                             transportCompIdx);
-
-        Valgrind::CheckDefined(porosity_);
-        Valgrind::CheckDefined(dispersivity_);
-        Valgrind::CheckDefined(diffCoeff_);
-
-        // energy related quantities not contained in the fluid state
-        asImp_().updateEnergy_(priVars, problem, element, fvGeometry, scvIdx, isOldSol);
-    }
-
-    /*!
-     * \copydoc ImplicitModel::completeFluidState
-     */
-    static void completeFluidState(const PrimaryVariables& priVars,
-                                   const Problem& problem,
-                                   const Element& element,
-                                   const FVElementGeometry& fvGeometry,
-                                   const int scvIdx,
-                                   FluidState& fluidState)
-    {
-        Scalar t = Implementation::temperature_(priVars, problem, element,
-                                                fvGeometry, scvIdx);
-        fluidState.setTemperature(t);
-        fluidState.setSaturation(phaseIdx, 1.);
-
-        fluidState.setPressure(phaseIdx, priVars[pressureIdx]);
-
-        if(useMoles)
-        {
-            fluidState.setMoleFraction(phaseIdx, phaseCompIdx, 1 - priVars[massOrMoleFracIdx]);
-            fluidState.setMoleFraction(phaseIdx, transportCompIdx, priVars[massOrMoleFracIdx]);
-        }
-        else
-        {
-            // setMassFraction() has only to be called 1-numComponents times
-            fluidState.setMassFraction(phaseIdx, transportCompIdx, priVars[massOrMoleFracIdx]);
-        }
-
-        typename FluidSystem::ParameterCache paramCache;
-        paramCache.updatePhase(fluidState, phaseIdx);
-
-        Scalar value;
-        value = FluidSystem::density(fluidState, paramCache, phaseIdx);
-        fluidState.setDensity(phaseIdx, value);
-        value = FluidSystem::viscosity(fluidState, paramCache, phaseIdx);
-        fluidState.setViscosity(phaseIdx, value);
-
-        // compute and set the enthalpy
-        Scalar h = Implementation::enthalpy_(fluidState, paramCache, phaseIdx);
-        fluidState.setEnthalpy(phaseIdx, h);
-    }
-
-    /*!
-     * \brief Return the fluid configuration at the given primary
-     *        variables
-     */
-    const FluidState &fluidState() const
-    { return fluidState_; }
-
-    /*!
-     * \brief Return density \f$\mathrm{[kg/m^3]}\f$ the of the fluid phase.
-     */
-    Scalar density() const
-    { return fluidState_.density(phaseIdx); }
-
-    /*!
-     * \brief Return molar density \f$\mathrm{[mol/m^3]}\f$ the of the fluid phase.
-     */
-    Scalar molarDensity() const
-    { return fluidState_.molarDensity(phaseIdx);}
-
-    /*!
-     * \brief Return mole fraction \f$\mathrm{[mol/mol]}\f$ of a component in the phase.
-     *
-     * \param compIdx The index of the component
-     */
-    Scalar moleFraction(int compIdx) const
-    { return fluidState_.moleFraction(phaseIdx, (compIdx==0)?phaseCompIdx:transportCompIdx); }
-
-    /*!
-     * \brief Return mass fraction \f$\mathrm{[kg/kg]}\f$ of a component in the phase.
-     *
-     * \param compIdx The index of the component
-     */
-    Scalar massFraction(int compIdx) const
-    { return fluidState_.massFraction(phaseIdx, (compIdx==0)?phaseCompIdx:transportCompIdx); }
-
-    /*!
-     * \brief Return concentration \f$\mathrm{[mol/m^3]}\f$  of a component in the phase.
-     *
-     * \param compIdx The index of the component
-     */
-    Scalar molarity(int compIdx) const
-    { return fluidState_.molarity(phaseIdx, (compIdx==0)?phaseCompIdx:transportCompIdx); }
-
-    /*!
-     * \brief Return the effective pressure \f$\mathrm{[Pa]}\f$ of a given phase within
-     *        the control volume.
-     */
-    Scalar pressure() const
-    { return fluidState_.pressure(phaseIdx); }
-
-    /*!
-     * \brief Return the binary diffusion coefficient \f$\mathrm{[m^2/s]}\f$ in the fluid.
-     */
-    Scalar diffCoeff() const
-    { return diffCoeff_; }
-
-    /*!
-     * \brief Returns the dispersivity of the fluid's streamlines.
-     */
-    const GlobalPosition &dispersivity() const
-    { return dispersivity_; }
-
-    /*!
-     * \brief Return temperature \f$\mathrm{[K]}\f$ inside the sub-control volume.
-     *
-     * Note that we assume thermodynamic equilibrium, i.e. the
-     * temperature of the rock matrix and of all fluid phases are
-     * identical.
-     */
-    Scalar temperature() const
-    { return fluidState_.temperature(phaseIdx); }
-
-    /*!
-     * \brief Return the dynamic viscosity \f$\mathrm{[Pa*s]}\f$ of a given phase
-     *        within the control volume.
-     */
-    Scalar viscosity() const
-    { return fluidState_.viscosity(phaseIdx); }
-
-    /*!
-     * \brief Return the average porosity \f$\mathrm{[-]}\f$ within the control volume.
-     */
-    Scalar porosity() const
-    { return porosity_; }
-
-protected:
-    static Scalar temperature_(const PrimaryVariables &priVars,
-                               const Problem& problem,
-                               const Element &element,
-                               const FVElementGeometry &fvGeometry,
-                               const int scvIdx)
-    {
-        return problem.temperatureAtPos(fvGeometry.subContVol[scvIdx].global);
-    }
-
-    template<class ParameterCache>
-    static Scalar enthalpy_(const FluidState& fluidState,
-                            const ParameterCache& paramCache,
-                            const int phaseIdx)
-    {
-        return 0;
-    }
-
-    /*!
-     * \brief Called by update() to compute the energy related quantities.
-     */
-    void updateEnergy_(const PrimaryVariables &priVars,
-                       const Problem &problem,
-                       const Element &element,
-                       const FVElementGeometry &fvGeometry,
-                       const int scvIdx,
-                       const bool isOldSol)
-    { }
-
-    Scalar porosity_;    //!< Effective porosity within the control volume
-    GlobalPosition dispersivity_;
-    Scalar diffCoeff_;
-    FluidState fluidState_;
-
-private:
-    Implementation &asImp_()
-    { return *static_cast<Implementation*>(this); }
-
-    const Implementation &asImp_() const
-    { return *static_cast<const Implementation*>(this); }
-};
-
-}// end namespace
+#include <dumux/porousmediumflow/1p2c/implicit/volumevariables.hh>
 
 #endif
diff --git a/dumux/implicit/2p2c/2p2cfluxvariables.hh b/dumux/implicit/2p2c/2p2cfluxvariables.hh
index 8f0487eb25..7adf5ca5a5 100644
--- a/dumux/implicit/2p2c/2p2cfluxvariables.hh
+++ b/dumux/implicit/2p2c/2p2cfluxvariables.hh
@@ -1,255 +1,8 @@
-// -*- 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/>.   *
- *****************************************************************************/
-/*!
- * \file
- * \brief Contains the data which is required to calculate
- *        all fluxes of components over a face of a finite volume for
- *        the two-phase two-component model fully implicit model.
- */
-#ifndef DUMUX_2P2C_FLUX_VARIABLES_HH
-#define DUMUX_2P2C_FLUX_VARIABLES_HH
+#ifndef DUMUX_2P2C_FLUX_VARIABLES_HH_OLD
+#define DUMUX_2P2C_FLUX_VARIABLES_HH_OLD
 
-#include <dumux/common/math.hh>
-#include <dumux/common/spline.hh>
+#warning this header is deprecated, use dumux/porousmediumflow/2p2c/implicit/fluxvariables.hh instead
 
-#include "2p2cproperties.hh"
-
-namespace Dumux
-{
-
-/*!
- * \ingroup TwoPTwoCModel
- * \ingroup ImplicitFluxVariables
- * \brief Contains the data which is required to calculate
- *        all fluxes of components over a face of a finite volume for
- *        the two-phase two-component model fully implicit model.
- *
- * This means pressure and concentration gradients, phase densities at
- * the integration point, etc.
- */
-template <class TypeTag>
-class TwoPTwoCFluxVariables : public GET_PROP_TYPE(TypeTag, BaseFluxVariables)
-{
-    typedef typename GET_PROP_TYPE(TypeTag, BaseFluxVariables) BaseFluxVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
-    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, EffectiveDiffusivityModel) EffectiveDiffusivityModel;
-    enum { numPhases = GET_PROP_VALUE(TypeTag, NumPhases) };
-
-    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
-    enum {
-        wPhaseIdx = Indices::wPhaseIdx,
-        nPhaseIdx = Indices::nPhaseIdx,
-        wCompIdx = Indices::wCompIdx,
-        nCompIdx = Indices::nCompIdx
-    };
-
-    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
-    typedef typename GridView::template Codim<0>::Entity Element;
-    enum { dim = GridView::dimension };
-    enum { dimWorld = GridView::dimensionworld} ;
-
-    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
-    typedef Dune::FieldVector<Scalar, dim> DimVector;
-    typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition;
-
-    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
-
- public:
-    /*!
-     * \brief The constructor
-     *
-     * \param problem The problem
-     * \param element The finite element
-     * \param fvGeometry The finite-volume geometry in the fully implicit scheme
-     * \param fIdx The local index of the sub-control-volume face
-     * \param elemVolVars The volume variables of the current element
-     * \param onBoundary Evaluate flux at inner sub-control-volume face or on a boundary face
-     */
-    TwoPTwoCFluxVariables(const Problem &problem,
-                          const Element &element,
-                          const FVElementGeometry &fvGeometry,
-                          const int fIdx,
-                          const ElementVolumeVariables &elemVolVars,
-                          const bool onBoundary = false)
-        : BaseFluxVariables(problem, element, fvGeometry, fIdx, elemVolVars, onBoundary)
-    {
-        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
-            density_[phaseIdx] = Scalar(0);
-            molarDensity_[phaseIdx] = Scalar(0);
-            moleFractionGrad_[phaseIdx] = Scalar(0);
-        }
-
-        calculateValues_(problem, element, elemVolVars);
-    }
-
- protected:
-    void calculateValues_(const Problem &problem,
-                          const Element &element,
-                          const ElementVolumeVariables &elemVolVars)
-    {
-        // calculate densities at the integration points of the face
-        GlobalPosition tmp(0.0);
-        for (unsigned int idx = 0;
-             idx < this->face().numFap;
-             idx++) // loop over adjacent vertices
-        {
-            // index for the element volume variables
-            int volVarsIdx = this->face().fapIndices[idx];
-
-            for (int phaseIdx = 0; phaseIdx < numPhases; phaseIdx++)
-            {
-                density_[phaseIdx] += elemVolVars[volVarsIdx].density(phaseIdx)*
-                    this->face().shapeValue[idx];
-                molarDensity_[phaseIdx] += elemVolVars[volVarsIdx].molarDensity(phaseIdx)*
-                    this->face().shapeValue[idx];
-            }
-        }
-
-        calculateGradients_(problem, element, elemVolVars);
-        calculatePorousDiffCoeff_(problem, element, elemVolVars);
-    }
-
-    void calculateGradients_(const Problem &problem,
-                             const Element &element,
-                             const ElementVolumeVariables &elemVolVars)
-    {
-        // calculate gradients
-        GlobalPosition tmp(0.0);
-        for (unsigned int idx = 0;
-             idx < this->face().numFap;
-             idx++) // loop over adjacent vertices
-        {
-            // FE gradient at vertex idx
-            const GlobalPosition &feGrad = this->face().grad[idx];
-
-            // index for the element volume variables
-            int volVarsIdx = this->face().fapIndices[idx];
-
-            // the mole fraction gradient of the wetting phase
-            tmp = feGrad;
-            tmp *= elemVolVars[volVarsIdx].moleFraction(wPhaseIdx, nCompIdx);
-            moleFractionGrad_[wPhaseIdx] += tmp;
-
-            // the mole fraction gradient of the non-wetting phase
-            tmp = feGrad;
-            tmp *= elemVolVars[volVarsIdx].moleFraction(nPhaseIdx, wCompIdx);
-            moleFractionGrad_[nPhaseIdx] += tmp;
-        }
-    }
-
-    Scalar rhoFactor_(int phaseIdx, int scvIdx, const ElementVolumeVariables &vDat)
-    {
-        static const Scalar eps = 1e-2;
-        const Scalar sat = vDat[scvIdx].density(phaseIdx);
-        if (sat > eps)
-            return 0.5;
-        if (sat <= 0)
-            return 0;
-
-        static const Dumux::Spline<Scalar> sp(0, eps, // x0, x1
-                                              0, 0.5, // y0, y1
-                                              0, 0); // m0, m1
-        return sp.eval(sat);
-    }
-
-    void calculatePorousDiffCoeff_(const Problem &problem,
-                                   const Element &element,
-                                   const ElementVolumeVariables &elemVolVars)
-    {
-        const VolumeVariables &volVarsI = elemVolVars[this->face().i];
-        const VolumeVariables &volVarsJ = elemVolVars[this->face().j];
-
-        // the effective diffusion coefficients at vertex i and j
-        Scalar diffCoeffI;
-        Scalar diffCoeffJ;
-
-        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
-        {
-            // make sure to only calculate diffusion coefficients
-            // for phases which exist in both finite volumes
-            if (volVarsI.saturation(phaseIdx) <= 0 || volVarsJ.saturation(phaseIdx) <= 0)
-            {
-                porousDiffCoeff_[phaseIdx] = 0.0;
-                continue;
-            }
-
-            diffCoeffI = EffectiveDiffusivityModel::effectiveDiffusivity(volVarsI.porosity(),
-                                                                         volVarsI.saturation(phaseIdx),
-                                                                         volVarsI.diffCoeff(phaseIdx));
-
-            diffCoeffJ = EffectiveDiffusivityModel::effectiveDiffusivity(volVarsJ.porosity(),
-                                                                         volVarsJ.saturation(phaseIdx),
-                                                                         volVarsJ.diffCoeff(phaseIdx));
-
-            // -> harmonic mean
-            porousDiffCoeff_[phaseIdx] = harmonicMean(diffCoeffI, diffCoeffJ);
-        }
-    }
-
- public:
-    /*!
-     * \brief Returns the effective diffusion coefficient \f$\mathrm{[m^2/s]}\f$
-     *        for each fluid phase in the porous medium.
-     *
-     * \param phaseIdx The phase index
-     */
-    Scalar porousDiffCoeff(int phaseIdx) const
-    { return porousDiffCoeff_[phaseIdx]; };
-
-    /*!
-     * \brief Returns the density \f$\mathrm{[kg/m^3]}\f$ of a phase.
-     *
-     * \param phaseIdx The phase index
-     */
-    Scalar density(int phaseIdx) const
-    { return density_[phaseIdx]; }
-
-    /*!
-     * \brief Returns the molar density \f$\mathrm{[mol/m^3]}\f$ of a phase.
-     *
-     * \param phaseIdx The phase index
-     */
-    Scalar molarDensity(int phaseIdx) const
-    { return molarDensity_[phaseIdx]; }
-
-    /*!
-     * \brief Returns the mole fraction gradient \f$\mathrm{[1/m]}\f$
-     *        of the dissolved component in a phase.
-     *
-     * \param phaseIdx The phase index
-     */
-    const GlobalPosition &moleFractionGrad(int phaseIdx) const
-    { return moleFractionGrad_[phaseIdx]; };
-
- protected:
-    // mole fraction gradients
-    GlobalPosition moleFractionGrad_[numPhases];
-
-    // density of each face at the integration point
-    Scalar density_[numPhases], molarDensity_[numPhases];
-
-    // the diffusion coefficient for the porous medium
-    Scalar porousDiffCoeff_[numPhases];
-};
-
-} // end namespace
+#include <dumux/porousmediumflow/2p2c/implicit/fluxvariables.hh>
 
 #endif
diff --git a/dumux/implicit/2p2c/2p2cindices.hh b/dumux/implicit/2p2c/2p2cindices.hh
index c38f751efa..78016b2c91 100644
--- a/dumux/implicit/2p2c/2p2cindices.hh
+++ b/dumux/implicit/2p2c/2p2cindices.hh
@@ -1,145 +1,8 @@
-// -*- 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_2P2C_INDICES_HH_OLD
+#define DUMUX_2P2C_INDICES_HH_OLD
 
-/*!
- * \file
- * \brief Defines the indices required for the two-phase two-component
- *        fully implicit model.
- */
-#ifndef DUMUX_2P2C_INDICES_HH
-#define DUMUX_2P2C_INDICES_HH
+#warning this header is deprecated, use dumux/porousmediumflow/2p2c/implicit/indices.hh instead
 
-#include "2p2cproperties.hh"
-
-namespace Dumux
-{
-// \{
-
-/*!
- * \ingroup TwoPTwoCModel
- * \ingroup ImplicitIndices
- * \brief Enumerates the formulations which the two-phase two-component model accepts.
- */
-struct TwoPTwoCFormulation
-{
-    static const int pwsn = 0; //!< pw and sn as primary variables
-    static const int pnsw = 1; //!< pn and sw as primary variables
-};
-
-/*!
- * \ingroup TwoPTwoCModel
- * \ingroup ImplicitIndices
- * \brief The indices for the isothermal two-phase two-component model.
- *
- * \tparam formulation The formulation, either pwsn or pnsw.
- * \tparam PVOffset The first index in a primary variable vector.
- */
-template <class TypeTag,
-          int formulation = TwoPTwoCFormulation::pwsn,
-          int PVOffset = 0>
-class TwoPTwoCIndices
-{
-    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
-
-public:
-    // Phase indices
-    static const int wPhaseIdx = FluidSystem::wPhaseIdx; //!< Index of the wetting phase
-    static const int nPhaseIdx = FluidSystem::nPhaseIdx; //!< Index of the non-wetting phase
-
-    // Component indices
-    static const int wCompIdx = FluidSystem::wCompIdx; //!< Index of the primary component of the wetting phase
-    static const int nCompIdx = FluidSystem::nCompIdx; //!< Index of the primary component of the non-wetting phase
-
-    // present phases (-> 'pseudo' primary variable)
-    static const int wPhaseOnly = 1; //!< Only the wetting phase is present
-    static const int nPhaseOnly = 0; //!< Only the non-wetting phase is present
-    static const int bothPhases = 2; //!< Both phases are present
-
-    // Primary variable indices
-    //! Index for wetting/non-wetting phase pressure (depending on the formulation) in a solution vector
-    static const int pressureIdx = PVOffset + 0;
-    //! Index of either the saturation or the mass fraction of the non-wetting/wetting phase
-    static const int switchIdx = PVOffset + 1;
-
-    //! Index for wetting phase pressure in a solution vector
-    static const int pwIdx = pressureIdx;
-    //! Index of either the saturation of the non-wetting phase or the mass fraction secondary component in the only phase
-    static const int snOrXIdx = switchIdx;
-
-    // equation indices
-    //! Index of the mass conservation equation for the first component
-    static const int conti0EqIdx = PVOffset;
-    //! Index of the mass conservation equation for the primary component of the wetting phase
-    static const int contiWEqIdx = conti0EqIdx + wCompIdx;
-    //! Index of the mass conservation equation for the primary component of the non-wetting phase
-    static const int contiNEqIdx = conti0EqIdx + nCompIdx;
-};
-
-/*!
- * \ingroup TwoPTwoCModel
- * \ingroup ImplicitIndices
- * \brief The indices for the isothermal two-phase two-component model in the pn-sw
- *        formulation.
- *
- * \tparam PVOffset The first index in a primary variable vector.
- */
-template <class TypeTag, int PVOffset>
-class TwoPTwoCIndices<TypeTag, TwoPTwoCFormulation::pnsw, PVOffset>
-{
-    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
-
-public:
-    // Phase indices
-    static const int wPhaseIdx = FluidSystem::wPhaseIdx; //!< Index of the wetting phase
-    static const int nPhaseIdx = FluidSystem::nPhaseIdx; //!< Index of the non-wetting phase
-
-    // Component indices
-    static const int wCompIdx = FluidSystem::wCompIdx; //!< Index of the primary component of the wetting phase
-    static const int nCompIdx = FluidSystem::nCompIdx; //!< Index of the primary component of the non-wetting phase
-
-    // present phases (-> 'pseudo' primary variable)
-    static const int wPhaseOnly = 1; //!< Only the wetting phase is present
-    static const int nPhaseOnly = 2; //!< Only the non-wetting phase is present
-    static const int bothPhases = 3; //!< Both phases are present
-
-    // Primary variable indices
-    //! Index for wetting/non-wetting phase pressure (depending on the formulation) in a solution vector
-    static const int pressureIdx = PVOffset + 0;
-    //! Index of either the saturation or the mass fraction of the non-wetting/wetting phase
-    static const int switchIdx = PVOffset + 1;
-
-    //! Index for non-wetting phase pressure in a solution vector
-    static const int pnIdx = pressureIdx;
-    //! Index of either the saturation of the liquid phase or the mass fraction of the secondary component in the only phase
-    static const int swOrXIdx = switchIdx;
-
-    // Equation indices
-    //! Index of the mass conservation equation for the first component
-    static const int conti0EqIdx = PVOffset;
-    //! Index of the mass conservation equation for the primary component of the wetting phase
-    static const int contiWEqIdx = conti0EqIdx + wCompIdx;
-    //! Index of the mass conservation equation for the primary component of the non-wetting phase
-    static const int contiNEqIdx = conti0EqIdx + nCompIdx;
-};
-
-// \}
-
-}
+#include <dumux/porousmediumflow/2p2c/implicit/indices.hh>
 
 #endif
diff --git a/dumux/implicit/2p2c/2p2clocalresidual.hh b/dumux/implicit/2p2c/2p2clocalresidual.hh
index 3a5dcfcfd2..42750ec567 100644
--- a/dumux/implicit/2p2c/2p2clocalresidual.hh
+++ b/dumux/implicit/2p2c/2p2clocalresidual.hh
@@ -1,507 +1,8 @@
-// -*- 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/>.   *
- *****************************************************************************/
-/*!
- * \file
- *
- * \brief Element-wise calculation of the Jacobian matrix for problems
- *        using the two-phase two-component fully implicit model.
- */
+#ifndef DUMUX_2P2C_LOCAL_RESIDUAL_BASE_HH_OLD
+#define DUMUX_2P2C_LOCAL_RESIDUAL_BASE_HH_OLD
 
-#ifndef DUMUX_2P2C_LOCAL_RESIDUAL_BASE_HH
-#define DUMUX_2P2C_LOCAL_RESIDUAL_BASE_HH
+#warning this header is deprecated, use dumux/porousmediumflow/2p2c/implicit/localresidual.hh instead
 
-#include "2p2cproperties.hh"
-
-namespace Dumux
-{
-/*!
- * \ingroup TwoPTwoCModel
- * \ingroup ImplicitLocalResidual
- * \brief Element-wise calculation of the Jacobian matrix for problems
- *        using the two-phase two-component fully implicit model.
- *
- * This class is used to fill the gaps in ImplicitLocalResidual for the
- * two-phase two-component flow.
- */
-template<class TypeTag>
-class TwoPTwoCLocalResidual: public GET_PROP_TYPE(TypeTag, BaseLocalResidual)
-{
- protected:
-    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
-    typedef typename GET_PROP_TYPE(TypeTag, LocalResidual) Implementation;
-    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
-    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
-    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, ElementBoundaryTypes) ElementBoundaryTypes;
-    typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables;
-    enum
-    {
-        numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
-        numComponents = GET_PROP_VALUE(TypeTag, NumComponents)
-    };
-
-    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
-    enum
-    {
-        contiWEqIdx = Indices::contiWEqIdx,
-        contiNEqIdx = Indices::contiNEqIdx,
-        wPhaseIdx = Indices::wPhaseIdx,
-        nPhaseIdx = Indices::nPhaseIdx,
-        wCompIdx = Indices::wCompIdx,
-        nCompIdx = Indices::nCompIdx
-    };
-
-    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
-    typedef typename GridView::template Codim<0>::Entity Element;
-
-    static constexpr unsigned int replaceCompEqIdx =
-        GET_PROP_VALUE(TypeTag, ReplaceCompEqIdx);
-
-    //! Property that defines whether mole or mass fractions are used
-    static const bool useMoles = GET_PROP_VALUE(TypeTag, UseMoles);
-
- public:
-    /*!
-     * \brief Constructor
-     *
-     * Sets the mass upwind weight.
-     */
-    TwoPTwoCLocalResidual()
-    {
-        // retrieve the upwind weight for the mass conservation equations. Use the value
-        // specified via the property system as default, and overwrite
-        // it by the run-time parameter from the Dune::ParameterTree
-        massUpwindWeight_ = GET_PARAM_FROM_GROUP(TypeTag, Scalar, Implicit, MassUpwindWeight);
-    }
-
-    /*!
-     * \brief Evaluate the storage term of the current solution in a
-     *        single phase.
-     *
-     * \param element The element
-     * \param phaseIdx The index of the fluid phase
-     */
-    void evalPhaseStorage(const Element &element, const int phaseIdx)
-    {
-        FVElementGeometry fvGeometry;
-        fvGeometry.update(this->gridView_(), element);
-        ElementBoundaryTypes bcTypes;
-        bcTypes.update(this->problem_(), element, fvGeometry);
-        ElementVolumeVariables elemVolVars;
-        elemVolVars.update(this->problem_(), element, fvGeometry, false);
-
-        this->storageTerm_.resize(fvGeometry.numScv);
-        this->storageTerm_ = 0;
-
-        this->elemPtr_ = &element;
-        this->fvElemGeomPtr_ = &fvGeometry;
-        this->bcTypesPtr_ = &bcTypes;
-        this->prevVolVarsPtr_ = 0;
-        this->curVolVarsPtr_ = &elemVolVars;
-        evalPhaseStorage_(phaseIdx);
-    }
-
-    /*!
-     * \brief Evaluate the amount of all conservation quantities
-     *        (e.g. phase mass) within a sub-control volume.
-     *
-     *  \param storage The mass of the component within the sub-control volume
-     *  \param scvIdx The sub-control-volume index
-     *  \param usePrevSol Based on usePrevSol solution of current or previous time step is used
-     *
-     * The result should be averaged over the volume (e.g. phase mass
-     * inside a sub-control volume divided by the volume)
-     */
-    void computeStorage(PrimaryVariables &storage, const int scvIdx, bool usePrevSol) const
-    {
-        // 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 &elemVolVars = usePrevSol ? this->prevVolVars_()
-            : this->curVolVars_();
-        const VolumeVariables &volVars = elemVolVars[scvIdx];
-
-        // compute storage term of all components within all phases
-        storage = 0;
-        if(useMoles) // mole-fraction formulation
-        {
-            for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
-            {
-                for (unsigned int compIdx = contiCompIdx1_(); compIdx <= contiCompIdx2_(); ++compIdx)
-                {
-                    unsigned int eqIdx = (compIdx == wCompIdx) ? contiWEqIdx : contiNEqIdx;
-                    storage[eqIdx] += volVars.molarDensity(phaseIdx)
-                        * volVars.saturation(phaseIdx)
-                        * volVars.moleFraction(phaseIdx, compIdx);
-                 }
-                 // this is only processed if one component mass balance equation
-                 // is replaced by the total mass balance equation
-                 if (replaceCompEqIdx < numComponents)
-                     storage[replaceCompEqIdx] +=
-                         volVars.molarDensity(phaseIdx)
-                         * volVars.saturation(phaseIdx);
-            }
-            storage *= volVars.porosity();
-        }
-        else // mass-fraction formulation
-        {
-            for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
-            {
-                for (unsigned int compIdx = contiCompIdx1_(); compIdx <= contiCompIdx2_(); ++compIdx)
-                {
-                    unsigned int eqIdx = (compIdx == wCompIdx) ? contiWEqIdx : contiNEqIdx;
-                    storage[eqIdx] += volVars.density(phaseIdx)
-                        * volVars.saturation(phaseIdx)
-                        * volVars.massFraction(phaseIdx, compIdx);
-                }
-                // this is only processed if one component mass balance equation
-                // is replaced by the total mass balance equation
-                if (replaceCompEqIdx < numComponents)
-                    storage[replaceCompEqIdx] +=
-                        volVars.density(phaseIdx)
-                        * volVars.saturation(phaseIdx);
-            }
-            storage *= volVars.porosity();
-        }
-    }
-
-    /*!
-     * \brief Evaluates the total flux of all conservation quantities
-     *        over a face of a sub-control volume.
-     *
-     * \param flux The flux over the sub-control-volume face for each component
-     * \param fIdx The index of the sub-control-volume face
-     * \param onBoundary Evaluate flux at inner sub-control-volume face or on a boundary face
-     */
-    void computeFlux(PrimaryVariables &flux, const int fIdx, bool onBoundary=false) const
-    {
-        FluxVariables fluxVars(this->problem_(),
-                               this->element_(),
-                               this->fvGeometry_(),
-                               fIdx,
-                               this->curVolVars_(),
-                               onBoundary);
-
-        flux = 0;
-        asImp_()->computeAdvectiveFlux(flux, fluxVars);
-        Valgrind::CheckDefined(flux);
-        asImp_()->computeDiffusiveFlux(flux, fluxVars);
-        Valgrind::CheckDefined(flux);
-    }
-
-    /*!
-     * \brief Evaluates the advective mass flux of all components over
-     *        a face of a sub-control volume.
-     *
-     * \param flux The flux over the sub-control-volume face for each component
-     * \param fluxVars The flux variables at the current sub-control-volume face
-     */
-    void computeAdvectiveFlux(PrimaryVariables &flux, const FluxVariables &fluxVars) const
-    {
-        ////////
-        // advective fluxes of all components in all phases
-        ////////
-
-        if(useMoles) // mole-fraction formulation
-        {
-            for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
-            {
-                // data attached to upstream and the downstream vertices
-                // of the current phase
-                const VolumeVariables &up =
-                    this->curVolVars_(fluxVars.upstreamIdx(phaseIdx));
-                const VolumeVariables &dn =
-                    this->curVolVars_(fluxVars.downstreamIdx(phaseIdx));
-
-                for (unsigned int compIdx = contiCompIdx1_(); compIdx <= contiCompIdx2_(); ++compIdx)
-                {
-                    unsigned int eqIdx = (compIdx == wCompIdx) ? contiWEqIdx : contiNEqIdx;
-                    // add advective flux of current component in current
-                    // phase
-                    if (massUpwindWeight_ > 0.0)
-                        // upstream vertex
-                        flux[eqIdx] +=
-                            fluxVars.volumeFlux(phaseIdx)
-                            * massUpwindWeight_
-                            * up.molarDensity(phaseIdx)
-                            * up.moleFraction(phaseIdx, compIdx);
-                    if (massUpwindWeight_ < 1.0)
-                        // downstream vertex
-                        flux[eqIdx] +=
-                            fluxVars.volumeFlux(phaseIdx)
-                            * (1 - massUpwindWeight_)
-                            * dn.molarDensity(phaseIdx)
-                            * dn.moleFraction(phaseIdx, compIdx);
-
-                    Valgrind::CheckDefined(fluxVars.volumeFlux(phaseIdx));
-                    Valgrind::CheckDefined(up.molarDensity(phaseIdx));
-                    Valgrind::CheckDefined(up.moleFraction(phaseIdx, compIdx));
-                    Valgrind::CheckDefined(dn.molarDensity(phaseIdx));
-                    Valgrind::CheckDefined(dn.moleFraction(phaseIdx, compIdx));
-                }
-                // flux of the total mass balance;
-                // this is only processed if one component mass balance equation
-                // is replaced by a total mass balance equation
-                if (replaceCompEqIdx < numComponents)
-                {
-                    // upstream vertex
-                    if (massUpwindWeight_ > 0.0)
-                        flux[replaceCompEqIdx] +=
-                            fluxVars.volumeFlux(phaseIdx)
-                            * massUpwindWeight_
-                            * up.molarDensity(phaseIdx);
-                    // downstream vertex
-                    if (massUpwindWeight_ < 1.0)
-                        flux[replaceCompEqIdx] +=
-                            fluxVars.volumeFlux(phaseIdx)
-                            * (1 - massUpwindWeight_)
-                            * dn.molarDensity(phaseIdx);
-                    Valgrind::CheckDefined(fluxVars.volumeFlux(phaseIdx));
-                    Valgrind::CheckDefined(up.molarDensity(phaseIdx));
-                    Valgrind::CheckDefined(dn.molarDensity(phaseIdx));
-
-                }
-
-            }
-        }
-        else // mass-fraction formulation
-        {
-            for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
-            {
-                // data attached to upstream and downstream vertices
-                // of the current phase
-                const VolumeVariables &up =
-                    this->curVolVars_(fluxVars.upstreamIdx(phaseIdx));
-                const VolumeVariables &dn =
-                    this->curVolVars_(fluxVars.downstreamIdx(phaseIdx));
-
-                for (unsigned int compIdx = contiCompIdx1_(); compIdx <= contiCompIdx2_(); ++compIdx)
-                {
-                    unsigned int eqIdx = (compIdx == wCompIdx) ? contiWEqIdx : contiNEqIdx;
-                    // add advective flux of current component in current
-                    // phase
-                    if (massUpwindWeight_ > 0.0)
-                        // upstream vertex
-                        flux[eqIdx] +=
-                            fluxVars.volumeFlux(phaseIdx)
-                            * massUpwindWeight_
-                            * up.density(phaseIdx)
-                            * up.massFraction(phaseIdx, compIdx);
-                    if (massUpwindWeight_ < 1.0)
-                        // downstream vertex
-                        flux[eqIdx] +=
-                            fluxVars.volumeFlux(phaseIdx)
-                            * (1 - massUpwindWeight_)
-                            * dn.density(phaseIdx)
-                            * dn.massFraction(phaseIdx, compIdx);
-
-                    Valgrind::CheckDefined(fluxVars.volumeFlux(phaseIdx));
-                    Valgrind::CheckDefined(up.density(phaseIdx));
-                    Valgrind::CheckDefined(up.massFraction(phaseIdx, compIdx));
-                    Valgrind::CheckDefined(dn.density(phaseIdx));
-                    Valgrind::CheckDefined(dn.massFraction(phaseIdx, compIdx));
-                }
-                // flux of the total mass balance;
-                // this is only processed if one component mass balance equation
-                // is replaced by a total mass balance equation
-                if (replaceCompEqIdx < numComponents)
-                {
-                    // upstream vertex
-                    if (massUpwindWeight_ > 0.0)
-                        flux[replaceCompEqIdx] +=
-                            fluxVars.volumeFlux(phaseIdx)
-                            * massUpwindWeight_
-                            * up.density(phaseIdx);
-                    // downstream vertex
-                    if (massUpwindWeight_ < 1.0)
-                        flux[replaceCompEqIdx] +=
-                            fluxVars.volumeFlux(phaseIdx)
-                            * (1 - massUpwindWeight_)
-                            * dn.density(phaseIdx);
-                    Valgrind::CheckDefined(fluxVars.volumeFlux(phaseIdx));
-                    Valgrind::CheckDefined(up.density(phaseIdx));
-                    Valgrind::CheckDefined(dn.density(phaseIdx));
-
-                }
-
-            }
-        }
-    }
-
-    /*!
-     * \brief Evaluates the diffusive mass flux of all components over
-     *        a face of a sub-control volume.
-     *
-     * \param flux The flux over the sub-control-volume face for each component
-     * \param fluxVars The flux variables at the current sub-control-volume face
-     */
-    void computeDiffusiveFlux(PrimaryVariables &flux, const FluxVariables &fluxVars) const
-
-    {
-        if(useMoles) // mole-fraction formulation
-        {
-            // add diffusive flux of gas component in liquid phase
-            Scalar tmp = - (fluxVars.moleFractionGrad(wPhaseIdx)*fluxVars.face().normal);
-            tmp *=
-                fluxVars.porousDiffCoeff(wPhaseIdx) *
-                fluxVars.molarDensity(wPhaseIdx);
-            // add the diffusive fluxes only to the component mass balance
-            if (replaceCompEqIdx != contiNEqIdx)
-                flux[contiNEqIdx] += tmp;
-            if (replaceCompEqIdx != contiWEqIdx)
-                flux[contiWEqIdx] -= tmp;
-
-            // add diffusive flux of liquid component in non-wetting phase
-            tmp = -(fluxVars.moleFractionGrad(nPhaseIdx)*fluxVars.face().normal);
-            tmp *=
-                fluxVars.porousDiffCoeff(nPhaseIdx) *
-                fluxVars.molarDensity(nPhaseIdx);
-            // add the diffusive fluxes only to the component mass balance
-            if (replaceCompEqIdx != contiWEqIdx)
-                flux[contiWEqIdx] += tmp;
-            if (replaceCompEqIdx != contiNEqIdx)
-                flux[contiNEqIdx] -= tmp;
-        }
-        else // mass-fraction formulation
-        {
-            // add diffusive flux of gas component in liquid phase
-            Scalar tmp = - (fluxVars.moleFractionGrad(wPhaseIdx)*fluxVars.face().normal);
-            tmp *=
-                fluxVars.porousDiffCoeff(wPhaseIdx) *
-                fluxVars.molarDensity(wPhaseIdx);
-            // add the diffusive fluxes only to the component mass balance
-            if (replaceCompEqIdx != contiNEqIdx)
-                flux[contiNEqIdx] += tmp * FluidSystem::molarMass(nCompIdx);
-            if (replaceCompEqIdx != contiWEqIdx)
-                flux[contiWEqIdx] -= tmp * FluidSystem::molarMass(wCompIdx);
-
-            // add diffusive flux of liquid component in non-wetting phase
-            tmp = -(fluxVars.moleFractionGrad(nPhaseIdx)*fluxVars.face().normal);
-            tmp *=
-                fluxVars.porousDiffCoeff(nPhaseIdx) *
-                fluxVars.molarDensity(nPhaseIdx);
-            // add the diffusive fluxes only to the component mass balance
-            if (replaceCompEqIdx != contiWEqIdx)
-                flux[contiWEqIdx] += tmp * FluidSystem::molarMass(wCompIdx);
-            if (replaceCompEqIdx != contiNEqIdx)
-                flux[contiNEqIdx] -= tmp * FluidSystem::molarMass(nCompIdx);
-        }
-    }
-
- protected:
-    void evalPhaseStorage_(const int phaseIdx)
-    {
-        if(useMoles) // mole-fraction formulation
-        {
-            // evaluate the storage terms of a single phase
-            for (int i=0; i < this->fvGeometry_().numScv; i++) {
-                PrimaryVariables &storage = this->storageTerm_[i];
-                const ElementVolumeVariables &elemVolVars = this->curVolVars_();
-                const VolumeVariables &volVars = elemVolVars[i];
-
-                // compute storage term of all components within all phases
-                storage = 0;
-                for (int compIdx = 0; compIdx < numComponents; ++compIdx)
-                {
-                    int eqIdx = (compIdx == wCompIdx) ? contiWEqIdx : contiNEqIdx;
-                    storage[eqIdx] += volVars.molarDensity(phaseIdx)
-                        * volVars.saturation(phaseIdx)
-                        * volVars.moleFraction(phaseIdx, compIdx);
-                }
-
-                storage *= volVars.porosity();
-                storage *= this->fvGeometry_().subContVol[i].volume;
-            }
-        }
-        else // mass-fraction formulation
-        {
-            // evaluate the storage terms of a single phase
-            for (int i=0; i < this->fvGeometry_().numScv; i++) {
-                PrimaryVariables &storage = this->storageTerm_[i];
-                const ElementVolumeVariables &elemVolVars = this->curVolVars_();
-                const VolumeVariables &volVars = elemVolVars[i];
-
-                // compute storage term of all components within all phases
-                storage = 0;
-                for (int compIdx = 0; compIdx < numComponents; ++compIdx)
-                {
-                    int eqIdx = (compIdx == wCompIdx) ? contiWEqIdx : contiNEqIdx;
-                    storage[eqIdx] += volVars.density(phaseIdx)
-                        * volVars.saturation(phaseIdx)
-                        * volVars.massFraction(phaseIdx, compIdx);
-                }
-
-                storage *= volVars.porosity();
-                storage *= this->fvGeometry_().subContVol[i].volume;
-            }
-        }
-    }
-
-    /*!
-     * \brief Returns the equation index of the first mass-balance equation
-     *        of the component (used for loops)
-     *
-     * Returns the equation index of the first mass-balance equation
-     * of the component (used for loops) if one component mass balance
-     * is replaced by the total mass balance, this is the index
-     * of the remaining component mass-balance equation.
-     */
-    unsigned int contiCompIdx1_() const {
-        switch (replaceCompEqIdx)
-        {
-        case contiWEqIdx: return contiNEqIdx;
-        case contiNEqIdx: return contiWEqIdx;
-        default:          return 0;
-        }
-    }
-
-    /*!
-     * \brief Returns the equation index of the second mass balance
-     *        of the component (used for loops)
-     *
-     * Returns the equation index of the second mass balance
-     * of the component (used for loops)
-     * if one component mass balance is replaced by the total mass balance
-     * (replaceCompEqIdx < 2), this index is the same as contiCompIdx1().
-     */
-    unsigned int contiCompIdx2_() const {
-        switch (replaceCompEqIdx)
-        {
-        case contiWEqIdx: return contiNEqIdx;
-        case contiNEqIdx: return contiWEqIdx;
-        default:          return numComponents-1;
-        }
-    }
-
-    Implementation *asImp_()
-    { return static_cast<Implementation *> (this); }
-    const Implementation *asImp_() const
-    { return static_cast<const Implementation *> (this); }
-
- private:
-    Scalar massUpwindWeight_;
-};
-
-} // end namespace
+#include <dumux/porousmediumflow/2p2c/implicit/localresidual.hh>
 
 #endif
diff --git a/dumux/implicit/2p2c/2p2cmodel.hh b/dumux/implicit/2p2c/2p2cmodel.hh
index 552fd4092c..bf4ab0d68c 100644
--- a/dumux/implicit/2p2c/2p2cmodel.hh
+++ b/dumux/implicit/2p2c/2p2cmodel.hh
@@ -1,725 +1,8 @@
-// -*- 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/>.   *
- *****************************************************************************/
-/*!
- * \file
- *
- * \brief Adaption of the fully implicit scheme to the
- *        two-phase two-component fully implicit model.
- */
-#ifndef DUMUX_2P2C_MODEL_HH
-#define DUMUX_2P2C_MODEL_HH
+#ifndef DUMUX_2P2C_MODEL_HH_OLD
+#define DUMUX_2P2C_MODEL_HH_OLD
 
-#include "2p2cproperties.hh"
-#include "2p2cindices.hh"
-#include <dumux/porousmediumflow/implicit/velocityoutput.hh>
+#warning this header is deprecated, use dumux/porousmediumflow/2p2c/implicit/model.hh instead
 
-namespace Dumux
-{
-/*!
- * \ingroup TwoPTwoCModel
- * \brief Adaption of the fully implicit scheme to the
- *        two-phase two-component fully implicit model.
- *
- * This model implements two-phase two-component flow of two compressible and
- * partially miscible fluids \f$\alpha \in \{ w, n \}\f$ composed of the two components
- * \f$\kappa \in \{ w, a \}\f$. The standard multiphase Darcy
- * approach is used as the equation for the conservation of momentum:
- * \f[
- v_\alpha = - \frac{k_{r\alpha}}{\mu_\alpha} \mathbf{K}
- \left(\textbf{grad}\, p_\alpha - \varrho_{\alpha} \mbox{\bf g} \right)
- * \f]
- *
- * By inserting this into the equations for the conservation of the
- * components, one gets one transport equation for each component
- * \f{eqnarray*}
- && \phi \frac{\partial (\sum_\alpha \varrho_\alpha \frac{M^\kappa}{M_\alpha} x_\alpha^\kappa S_\alpha )}
- {\partial t}
- - \sum_\alpha  \text{div} \left\{ \varrho_\alpha \frac{M^\kappa}{M_\alpha} x_\alpha^\kappa
- \frac{k_{r\alpha}}{\mu_\alpha} \mathbf{K}
- (\textbf{grad}\, p_\alpha - \varrho_{\alpha}  \mbox{\bf g}) \right\}
- \nonumber \\ \nonumber \\
- &-& \sum_\alpha \text{div} \left\{ D_{\alpha,\text{pm}}^\kappa \varrho_{\alpha} \frac{M^\kappa}{M_\alpha}
- \textbf{grad} x^\kappa_{\alpha} \right\}
- - \sum_\alpha q_\alpha^\kappa = 0 \qquad \kappa \in \{w, a\} \, ,
- \alpha \in \{w, g\}
- \f}
- *
- * All equations are discretized using a vertex-centered finite volume (box)
- * or cell-centered finite volume scheme as spatial
- * and the implicit Euler method as time discretization.
- *
- * By using constitutive relations for the capillary pressure \f$p_c =
- * p_n - p_w\f$ and relative permeability \f$k_{r\alpha}\f$ and taking
- * advantage of the fact that \f$S_w + S_n = 1\f$ and \f$x^\kappa_w + x^\kappa_n = 1\f$, the number of
- * unknowns can be reduced to two.
- * The used primary variables are, like in the two-phase model, either \f$p_w\f$ and \f$S_n\f$
- * or \f$p_n\f$ and \f$S_w\f$. The formulation which ought to be used can be
- * specified by setting the <tt>Formulation</tt> property to either
- * TwoPTwoCIndices::pWsN or TwoPTwoCIndices::pNsW. By
- * default, the model uses \f$p_w\f$ and \f$S_n\f$.
- * Moreover, the second primary variable depends on the phase state, since a
- * primary variable switch is included. The phase state is stored for all nodes
- * of the system.
- * The model is able to use either mole or mass fractions. The property useMoles can be set to either true or false in the
- * problem file. Make sure that the according units are used in the problem setup. useMoles is set to true by default.
- * Following cases can be distinguished:
- * <ul>
- *  <li> Both phases are present: The saturation is used (either \f$S_n\f$ or \f$S_w\f$, dependent on the chosen <tt>Formulation</tt>),
- *      as long as \f$ 0 < S_\alpha < 1\f$</li>.
- *  <li> Only wetting phase is present: The mole fraction of, e.g., air in the wetting phase \f$x^a_w\f$ is used,
- *      as long as the maximum mole fraction is not exceeded \f$(x^a_w<x^a_{w,max})\f$</li>
- *  <li> Only non-wetting phase is present: The mole fraction of, e.g., water in the non-wetting phase, \f$x^w_n\f$, is used,
- *      as long as the maximum mole fraction is not exceeded \f$(x^w_n<x^w_{n,max})\f$</li>
- * </ul>
- */
-
-template<class TypeTag>
-class TwoPTwoCModel: public GET_PROP_TYPE(TypeTag, BaseModel)
-{
-    typedef typename GET_PROP_TYPE(TypeTag, BaseModel) ParentType;
-
-    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
-    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
-    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
-    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector;
-    enum {
-        numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
-        numComponents = GET_PROP_VALUE(TypeTag, NumComponents)
-    };
-
-    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
-    enum {
-        switchIdx = Indices::switchIdx,
-
-        wPhaseIdx = Indices::wPhaseIdx,
-        nPhaseIdx = Indices::nPhaseIdx,
-        wCompIdx = Indices::wCompIdx,
-        nCompIdx = Indices::nCompIdx,
-
-        wPhaseOnly = Indices::wPhaseOnly,
-        nPhaseOnly = Indices::nPhaseOnly,
-        bothPhases = Indices::bothPhases,
-
-        pwsn = TwoPTwoCFormulation::pwsn,
-        pnsw = TwoPTwoCFormulation::pnsw,
-        formulation = GET_PROP_VALUE(TypeTag, Formulation)
-    };
-
-    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
-    enum {
-        dim = GridView::dimension,
-        dimWorld = GridView::dimensionworld
-    };
-
-    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
-    typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition;
-    static const bool useMoles = GET_PROP_VALUE(TypeTag, UseMoles);
-
-    enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) };
-    enum { dofCodim = isBox ? dim : 0 };
-
-public:
-    /*!
-     * \brief Initialize the static data with the initial solution.
-     *
-     * \param problem The problem to be solved
-     */
-    void init(Problem &problem)
-    {
-        ParentType::init(problem);
-
-        unsigned numDofs = this->numDofs();
-
-        staticDat_.resize(numDofs);
-
-        setSwitched_(false);
-
-        // check, if velocity output can be used (works only for cubes so far)
-        for (const auto& element : Dune::elements(this->gridView_()))
-        {
-            if (!isBox) // i.e. cell-centered discretization
-            {
-                int eIdxGlobal = this->dofMapper().index(element);
-                const GlobalPosition &globalPos = element.geometry().center();
-
-                // initialize phase presence
-                staticDat_[eIdxGlobal].phasePresence
-                    = this->problem_().initialPhasePresence(*(this->gridView_().template begin<dim>()),
-                                                            eIdxGlobal, globalPos);
-                staticDat_[eIdxGlobal].wasSwitched = false;
-
-                staticDat_[eIdxGlobal].oldPhasePresence
-                    = staticDat_[eIdxGlobal].phasePresence;
-            }
-        }
-
-        if (isBox) // i.e. vertex-centered discretization
-        {
-            for (const auto& vertex : Dune::vertices(this->gridView_()))
-            {
-                int vIdxGlobal = this->dofMapper().index(vertex);
-                const GlobalPosition &globalPos = vertex.geometry().corner(0);
-
-                // initialize phase presence
-                staticDat_[vIdxGlobal].phasePresence
-                    = this->problem_().initialPhasePresence(vertex, vIdxGlobal,
-                                                            globalPos);
-                staticDat_[vIdxGlobal].wasSwitched = false;
-
-                staticDat_[vIdxGlobal].oldPhasePresence
-                    = staticDat_[vIdxGlobal].phasePresence;
-            }
-        }
-    }
-
-    /*!
-     * \brief Compute the total storage of all conservation quantities in one phase
-     *
-     * \param storage Contains the storage of each component in one phase
-     * \param phaseIdx The phase index
-     */
-    void globalPhaseStorage(PrimaryVariables &storage, const int phaseIdx)
-    {
-        storage = 0;
-
-        for (const auto& element : Dune::elements(this->gridView_())) {
-            if(element.partitionType() == Dune::InteriorEntity)
-            {
-
-
-                this->localResidual().evalPhaseStorage(element, phaseIdx);
-
-                for (unsigned int i = 0; i < this->localResidual().storageTerm().size(); ++i)
-                    storage += this->localResidual().storageTerm()[i];
-            }
-        }
-        if (this->gridView_().comm().size() > 1)
-            storage = this->gridView_().comm().sum(storage);
-    }
-
-    /*!
-     * \brief Called by the update() method if applying the Newton
-     *        method was unsuccessful.
-     */
-    void updateFailed()
-    {
-        ParentType::updateFailed();
-
-        setSwitched_(false);
-        resetPhasePresence_();
-    }
-
-    /*!
-     * \brief Called by the problem if a time integration was
-     *        successful, post processing of the solution is done and the
-     *        result has been written to disk.
-     *
-     * This should prepare the model for the next time integration.
-     */
-    void advanceTimeLevel()
-    {
-        ParentType::advanceTimeLevel();
-
-        // update the phase state
-        updateOldPhasePresence_();
-        setSwitched_(false);
-    }
-
-    /*!
-     * \brief Returns true if the primary variables were switched for
-     *        at least one vertex after the last timestep.
-     */
-    bool switched() const
-    {
-        return switchFlag_;
-    }
-
-    /*!
-     * \brief Returns the phase presence of the current or the old solution of a degree of freedom.
-     *
-     * \param dofIdxGlobal The global index of the degree of freedom
-     * \param oldSol Based on oldSol current or previous time step is used
-     */
-    int phasePresence(int dofIdxGlobal, bool oldSol) const
-    {
-        return oldSol ? staticDat_[dofIdxGlobal].oldPhasePresence
-            : staticDat_[dofIdxGlobal].phasePresence;
-    }
-
-    /*!
-     * \brief Append all quantities of interest which can be derived
-     *        from the solution of the current time step to the VTK
-     *        writer.
-     *
-     * \param sol The solution vector
-     * \param writer The writer for multi-file VTK datasets
-     */
-    template<class MultiWriter>
-    void addOutputVtkFields(const SolutionVector &sol,
-                                MultiWriter &writer)
-    {
-        typedef Dune::BlockVector<Dune::FieldVector<double, 1> > ScalarField;
-        typedef Dune::BlockVector<Dune::FieldVector<double, dimWorld> > VectorField;
-
-        // get the number of degrees of freedom
-        unsigned numDofs = this->numDofs();
-
-        // create the required scalar fields
-        ScalarField *sN    = writer.allocateManagedBuffer(numDofs);
-        ScalarField *sW    = writer.allocateManagedBuffer(numDofs);
-        ScalarField *pn    = writer.allocateManagedBuffer(numDofs);
-        ScalarField *pw    = writer.allocateManagedBuffer(numDofs);
-        ScalarField *pc    = writer.allocateManagedBuffer(numDofs);
-        ScalarField *rhoW  = writer.allocateManagedBuffer(numDofs);
-        ScalarField *rhoN  = writer.allocateManagedBuffer(numDofs);
-        ScalarField *mobW  = writer.allocateManagedBuffer(numDofs);
-        ScalarField *mobN = writer.allocateManagedBuffer(numDofs);
-        ScalarField *phasePresence = writer.allocateManagedBuffer(numDofs);
-        ScalarField *massFrac[numPhases][numComponents];
-        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
-            for (int compIdx = 0; compIdx < numComponents; ++compIdx)
-                massFrac[phaseIdx][compIdx] = writer.allocateManagedBuffer(numDofs);
-        ScalarField *moleFrac[numPhases][numComponents];
-        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
-                    for (int compIdx = 0; compIdx < numComponents; ++compIdx)
-                        moleFrac[phaseIdx][compIdx] = writer.allocateManagedBuffer(numDofs);
-        ScalarField *temperature = writer.allocateManagedBuffer(numDofs);
-        ScalarField *poro = writer.allocateManagedBuffer(numDofs);
-        VectorField *velocityN = writer.template allocateManagedBuffer<double, dimWorld>(numDofs);
-        VectorField *velocityW = writer.template allocateManagedBuffer<double, dimWorld>(numDofs);
-        ImplicitVelocityOutput<TypeTag> velocityOutput(this->problem_());
-
-        if (velocityOutput.enableOutput()) // check if velocity output is demanded
-        {
-            // initialize velocity fields
-            for (unsigned int i = 0; i < numDofs; ++i)
-            {
-                (*velocityN)[i] = Scalar(0);
-                (*velocityW)[i] = Scalar(0);
-            }
-        }
-
-        unsigned numElements = this->gridView_().size(0);
-        ScalarField *rank = writer.allocateManagedBuffer(numElements);
-
-        for (const auto& element : Dune::elements(this->gridView_()))
-        {
-            if(element.partitionType() == Dune::InteriorEntity)
-            {
-                int eIdx = this->elementMapper().index(element);
-                (*rank)[eIdx] = this->gridView_().comm().rank();
-
-                FVElementGeometry fvGeometry;
-                fvGeometry.update(this->gridView_(), element);
-
-                ElementVolumeVariables elemVolVars;
-                elemVolVars.update(this->problem_(),
-                                   element,
-                                   fvGeometry,
-                                   false /* oldSol? */);
-
-                for (int scvIdx = 0; scvIdx < fvGeometry.numScv; ++scvIdx)
-                {
-                    int dofIdxGlobal = this->dofMapper().subIndex(element, scvIdx, dofCodim);
-
-                    (*sN)[dofIdxGlobal]    = elemVolVars[scvIdx].saturation(nPhaseIdx);
-                    (*sW)[dofIdxGlobal]    = elemVolVars[scvIdx].saturation(wPhaseIdx);
-                    (*pn)[dofIdxGlobal]    = elemVolVars[scvIdx].pressure(nPhaseIdx);
-                    (*pw)[dofIdxGlobal]    = elemVolVars[scvIdx].pressure(wPhaseIdx);
-                    (*pc)[dofIdxGlobal]    = elemVolVars[scvIdx].capillaryPressure();
-                    (*rhoW)[dofIdxGlobal]  = elemVolVars[scvIdx].density(wPhaseIdx);
-                    (*rhoN)[dofIdxGlobal]  = elemVolVars[scvIdx].density(nPhaseIdx);
-                    (*mobW)[dofIdxGlobal]  = elemVolVars[scvIdx].mobility(wPhaseIdx);
-                    (*mobN)[dofIdxGlobal]  = elemVolVars[scvIdx].mobility(nPhaseIdx);
-                    for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
-                        for (int compIdx = 0; compIdx < numComponents; ++compIdx)
-                        {
-                            (*massFrac[phaseIdx][compIdx])[dofIdxGlobal]
-                                = elemVolVars[scvIdx].massFraction(phaseIdx, compIdx);
-
-                            Valgrind::CheckDefined((*massFrac[phaseIdx][compIdx])[dofIdxGlobal][0]);
-                        }
-                    for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
-                        for (int compIdx = 0; compIdx < numComponents; ++compIdx)
-                        {
-                            (*moleFrac[phaseIdx][compIdx])[dofIdxGlobal]
-                                = elemVolVars[scvIdx].moleFraction(phaseIdx, compIdx);
-
-                            Valgrind::CheckDefined((*moleFrac[phaseIdx][compIdx])[dofIdxGlobal][0]);
-                        }
-                    (*poro)[dofIdxGlobal]  = elemVolVars[scvIdx].porosity();
-                    (*temperature)[dofIdxGlobal] = elemVolVars[scvIdx].temperature();
-                    (*phasePresence)[dofIdxGlobal]
-                        = staticDat_[dofIdxGlobal].phasePresence;
-                }
-
-                // velocity output
-                velocityOutput.calculateVelocity(*velocityW, elemVolVars, fvGeometry, element, wPhaseIdx);
-                velocityOutput.calculateVelocity(*velocityN, elemVolVars, fvGeometry, element, nPhaseIdx);
-            }
-
-        } // loop over elements
-
-        writer.attachDofData(*sN,     "Sn", isBox);
-        writer.attachDofData(*sW,     "Sw", isBox);
-        writer.attachDofData(*pn,     "pn", isBox);
-        writer.attachDofData(*pw,     "pw", isBox);
-        writer.attachDofData(*pc,     "pc", isBox);
-        writer.attachDofData(*rhoW,   "rhoW", isBox);
-        writer.attachDofData(*rhoN,   "rhoN", isBox);
-        writer.attachDofData(*mobW,   "mobW", isBox);
-        writer.attachDofData(*mobN,   "mobN", isBox);
-        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
-        {
-            for (int compIdx = 0; compIdx < numComponents; ++compIdx)
-            {
-                std::ostringstream oss;
-                oss << "X_" << FluidSystem::phaseName(phaseIdx) << "^" << FluidSystem::componentName(compIdx);
-                writer.attachDofData(*massFrac[phaseIdx][compIdx], oss.str(), isBox);
-            }
-        }
-        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
-        {
-            for (int compIdx = 0; compIdx < numComponents; ++compIdx)
-            {
-                std::ostringstream oss;
-                oss << "x_" << FluidSystem::phaseName(phaseIdx) << "^" << FluidSystem::componentName(compIdx);
-                writer.attachDofData(*moleFrac[phaseIdx][compIdx], oss.str(), isBox);
-            }
-        }
-        writer.attachDofData(*poro, "porosity", isBox);
-        writer.attachDofData(*temperature,    "temperature", isBox);
-        writer.attachDofData(*phasePresence,  "phase presence", isBox);
-
-        if (velocityOutput.enableOutput()) // check if velocity output is demanded
-        {
-            writer.attachDofData(*velocityW,  "velocityW", isBox, dim);
-            writer.attachDofData(*velocityN,  "velocityN", isBox, dim);
-        }
-
-        writer.attachCellData(*rank, "process rank");
-    }
-
-    /*!
-     * \brief Write the current solution to a restart file.
-     *
-     * \param outStream The output stream of one vertex for the restart file
-     * \param entity The entity, either a vertex or an element
-     */
-    template<class Entity>
-    void serializeEntity(std::ostream &outStream, const Entity &entity)
-    {
-        // write primary variables
-        ParentType::serializeEntity(outStream, entity);
-
-        int dofIdxGlobal = this->dofMapper().index(entity);
-
-        if (!outStream.good())
-            DUNE_THROW(Dune::IOError, "Could not serialize entity " << dofIdxGlobal);
-
-        outStream << staticDat_[dofIdxGlobal].phasePresence << " ";
-    }
-
-    /*!
-     * \brief Reads the current solution from a restart file.
-     *
-     * \param inStream The input stream of one vertex from the restart file
-     * \param entity The entity, either a vertex or an element
-     */
-    template<class Entity>
-    void deserializeEntity(std::istream &inStream, const Entity &entity)
-    {
-        // read primary variables
-        ParentType::deserializeEntity(inStream, entity);
-
-        // read phase presence
-        int dofIdxGlobal = this->dofMapper().index(entity);
-
-        if (!inStream.good())
-            DUNE_THROW(Dune::IOError,
-                       "Could not deserialize entity " << dofIdxGlobal);
-
-        inStream >> staticDat_[dofIdxGlobal].phasePresence;
-        staticDat_[dofIdxGlobal].oldPhasePresence
-            = staticDat_[dofIdxGlobal].phasePresence;
-
-    }
-
-    /*!
-     * \brief Update the static data of all vertices in the grid.
-     *
-     * \param curGlobalSol The current global solution
-     * \param oldGlobalSol The previous global solution
-     */
-    void updateStaticData(SolutionVector &curGlobalSol,
-                          const SolutionVector &oldGlobalSol)
-    {
-        bool wasSwitched = false;
-        int succeeded;
-        try {
-            for (unsigned i = 0; i < staticDat_.size(); ++i)
-                staticDat_[i].visited = false;
-
-            FVElementGeometry fvGeometry;
-            static VolumeVariables volVars;
-            for (const auto& element : Dune::elements(this->gridView_()))
-            {
-                fvGeometry.update(this->gridView_(), element);
-                for (int scvIdx = 0; scvIdx < fvGeometry.numScv; ++scvIdx)
-                {
-                    int dofIdxGlobal = this->dofMapper().subIndex(element, scvIdx, dofCodim);
-
-                    if (staticDat_[dofIdxGlobal].visited)
-                        continue;
-
-                    staticDat_[dofIdxGlobal].visited = true;
-                    volVars.update(curGlobalSol[dofIdxGlobal],
-                            this->problem_(),
-                            element,
-                            fvGeometry,
-                            scvIdx,
-                            false);
-                    const GlobalPosition &globalPos = fvGeometry.subContVol[scvIdx].global;
-                    if (primaryVarSwitch_(curGlobalSol,
-                            volVars,
-                            dofIdxGlobal,
-                            globalPos))
-                    {
-                        this->jacobianAssembler().markDofRed(dofIdxGlobal);
-                        wasSwitched = true;
-                    }
-                }
-            }
-            succeeded = 1;
-        }
-        catch (Dumux::NumericalProblem &e)
-        {
-            std::cout << "\n"
-                      << "Rank " << this->problem_().gridView().comm().rank()
-                      << " caught an exception while updating the static data." << e.what()
-                      << "\n";
-            succeeded = 0;
-        }
-        //make sure that all processes succeeded. If not throw a NumericalProblem to decrease the time step size.
-        if (this->gridView_().comm().size() > 1)
-            succeeded = this->gridView_().comm().min(succeeded);
-
-        if (!succeeded) {
-                DUNE_THROW(NumericalProblem,
-                        "A process did not succeed in updating the static data.");
-            return;
-        }
-
-        // make sure that if there was a variable switch in an
-        // other partition we will also set the switch flag
-        // for our partition.
-        if (this->gridView_().comm().size() > 1)
-            wasSwitched = this->gridView_().comm().max(wasSwitched);
-
-        setSwitched_(wasSwitched);
-    }
-
- protected:
-    /*!
-     * \brief Data which is attached to each vertex and is not only
-     *        stored locally.
-     */
-    struct StaticVars
-    {
-        int phasePresence;
-        bool wasSwitched;
-
-        int oldPhasePresence;
-        bool visited;
-    };
-
-    /*!
-     * \brief Resets the current phase presence of all vertices to the old one.
-     *
-     * This is done after an update failed.
-     */
-    void resetPhasePresence_()
-    {
-        for (unsigned int idx = 0; idx < staticDat_.size(); ++idx)
-        {
-            staticDat_[idx].phasePresence
-                = staticDat_[idx].oldPhasePresence;
-            staticDat_[idx].wasSwitched = false;
-        }
-    }
-
-    /*!
-     * \brief Sets the phase presence of all vertices state to the current one.
-     */
-    void updateOldPhasePresence_()
-    {
-        for (unsigned int idx = 0; idx < staticDat_.size(); ++idx)
-        {
-            staticDat_[idx].oldPhasePresence
-                = staticDat_[idx].phasePresence;
-            staticDat_[idx].wasSwitched = false;
-        }
-    }
-
-    /*!
-     * \brief Sets whether there was a primary variable switch after
-     *        the last timestep.
-     */
-    void setSwitched_(bool yesno)
-    {
-        switchFlag_ = yesno;
-    }
-
-    /*!
-     * \brief Performs variable switch at a vertex, returns true if a
-     *        variable switch was performed.
-     */
-    bool primaryVarSwitch_(SolutionVector &globalSol,
-                           const VolumeVariables &volVars,
-                           int dofIdxGlobal,
-                           const GlobalPosition &globalPos)
-    {
-        // evaluate primary variable switch
-        bool wouldSwitch = false;
-        int phasePresence = staticDat_[dofIdxGlobal].phasePresence;
-        int newPhasePresence = phasePresence;
-
-        // check if a primary var switch is necessary
-        if (phasePresence == nPhaseOnly)
-        {
-            // calculate mole fraction in the hypothetic wetting phase
-            Scalar xww = volVars.moleFraction(wPhaseIdx, wCompIdx);
-            Scalar xwn = volVars.moleFraction(wPhaseIdx, nCompIdx);
-
-            Scalar xwMax = 1.0;
-            if (xww + xwn > xwMax)
-                wouldSwitch = true;
-            if (staticDat_[dofIdxGlobal].wasSwitched)
-                xwMax *= 1.02;
-
-            // if the sum of the mole fractions is larger than
-            // 100%, wetting phase appears
-            if (xww + xwn > xwMax)
-            {
-                // wetting phase appears
-                std::cout << "wetting phase appears at vertex " << dofIdxGlobal
-                          << ", coordinates: " << globalPos << ", xww + xwn: "
-                          << xww + xwn << std::endl;
-                newPhasePresence = bothPhases;
-                if (formulation == pnsw)
-                    globalSol[dofIdxGlobal][switchIdx] = 0.0;
-                else if (formulation == pwsn)
-                    globalSol[dofIdxGlobal][switchIdx] = 1.0;
-            }
-        }
-        else if (phasePresence == wPhaseOnly)
-        {
-            // calculate fractions of the partial pressures in the
-            // hypothetic nonwetting phase
-            Scalar xnw = volVars.moleFraction(nPhaseIdx, wCompIdx);
-            Scalar xnn = volVars.moleFraction(nPhaseIdx, nCompIdx);
-
-            Scalar xgMax = 1.0;
-            if (xnw + xnn > xgMax)
-                wouldSwitch = true;
-            if (staticDat_[dofIdxGlobal].wasSwitched)
-                xgMax *= 1.02;
-
-            // if the sum of the mole fractions is larger than
-            // 100%, nonwetting phase appears
-            if (xnw + xnn > xgMax)
-            {
-                // nonwetting phase appears
-                std::cout << "nonwetting phase appears at vertex " << dofIdxGlobal
-                          << ", coordinates: " << globalPos << ", xnw + xnn: "
-                          << xnw + xnn << std::endl;
-                newPhasePresence = bothPhases;
-                if (formulation == pnsw)
-                    globalSol[dofIdxGlobal][switchIdx] = 0.999;
-                else if (formulation == pwsn)
-                    globalSol[dofIdxGlobal][switchIdx] = 0.001;
-            }
-        }
-        else if (phasePresence == bothPhases)
-        {
-            Scalar Smin = 0.0;
-            if (staticDat_[dofIdxGlobal].wasSwitched)
-                Smin = -0.01;
-
-            if (volVars.saturation(nPhaseIdx) <= Smin)
-            {
-                wouldSwitch = true;
-                // nonwetting phase disappears
-                std::cout << "Nonwetting phase disappears at vertex " << dofIdxGlobal
-                          << ", coordinates: " << globalPos << ", sn: "
-                          << volVars.saturation(nPhaseIdx) << std::endl;
-                newPhasePresence = wPhaseOnly;
-
-                if(useMoles) // mole-fraction formulation
-                {
-                    globalSol[dofIdxGlobal][switchIdx]
-                        = volVars.moleFraction(wPhaseIdx, nCompIdx);
-                }
-                else // mass-fraction formulation
-                {
-                    globalSol[dofIdxGlobal][switchIdx]
-                        = volVars.massFraction(wPhaseIdx, nCompIdx);
-                }
-            }
-            else if (volVars.saturation(wPhaseIdx) <= Smin)
-            {
-                wouldSwitch = true;
-                // wetting phase disappears
-                std::cout << "Wetting phase disappears at vertex " << dofIdxGlobal
-                          << ", coordinates: " << globalPos << ", sw: "
-                          << volVars.saturation(wPhaseIdx) << std::endl;
-                newPhasePresence = nPhaseOnly;
-
-                if(useMoles) // mole-fraction formulation
-                {
-                    globalSol[dofIdxGlobal][switchIdx]
-                        = volVars.moleFraction(nPhaseIdx, wCompIdx);
-                }
-                else // mass-fraction formulation
-                {
-                    globalSol[dofIdxGlobal][switchIdx]
-                        = volVars.massFraction(nPhaseIdx, wCompIdx);
-                }
-            }
-        }
-
-        staticDat_[dofIdxGlobal].phasePresence = newPhasePresence;
-        staticDat_[dofIdxGlobal].wasSwitched = wouldSwitch;
-        return phasePresence != newPhasePresence;
-    }
-
-protected:
-    // parameters given in constructor
-    std::vector<StaticVars> staticDat_;
-    bool switchFlag_;
-};
-
-}
-
-#include "2p2cpropertydefaults.hh"
+#include <dumux/porousmediumflow/2p2c/implicit/model.hh>
 
 #endif
diff --git a/dumux/implicit/2p2c/2p2cnewtoncontroller.hh b/dumux/implicit/2p2c/2p2cnewtoncontroller.hh
index 782fee3b7b..a07f5ac55c 100644
--- a/dumux/implicit/2p2c/2p2cnewtoncontroller.hh
+++ b/dumux/implicit/2p2c/2p2cnewtoncontroller.hh
@@ -1,104 +1,8 @@
-// -*- 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/>.   *
- *****************************************************************************/
-/*!
- * \file
- * \brief A two-phase two-component specific controller for the Newton solver.
- */
-#ifndef DUMUX_2P2C_NEWTON_CONTROLLER_HH
-#define DUMUX_2P2C_NEWTON_CONTROLLER_HH
+#ifndef DUMUX_2P2C_NEWTON_CONTROLLER_HH_OLD
+#define DUMUX_2P2C_NEWTON_CONTROLLER_HH_OLD
 
-#include "2p2cproperties.hh"
+#warning this header is deprecated, use dumux/porousmediumflow/2p2c/implicit/newtoncontroller.hh instead
 
-#include <dumux/nonlinear/newtoncontroller.hh>
-
-namespace Dumux {
-
-/*!
- * \ingroup Newton
- * \ingroup TwoPTwoCModel
- * \brief A two-phase two-component specific controller for the Newton solver.
- *
- * This controller 'knows' what a 'physically meaningful' solution is
- * which allows the Newton method to abort earlier if the solution is
- * way out of bounds.
- */
-template <class TypeTag>
-class TwoPTwoCNewtonController : public NewtonController<TypeTag>
-{
-    typedef NewtonController<TypeTag> ParentType;
-    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
-    typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector;
-
-public:
-    TwoPTwoCNewtonController(const Problem &problem)
-        : ParentType(problem)
-    {}
-
-    /*!
-     * \brief Suggest a new time step size based either on the number of Newton
-     *        iterations required or on the variable switch
-     *
-     * \param uCurrentIter The current global solution vector
-     * \param uLastIter The previous global solution vector
-     *
-     */
-    void newtonEndStep(SolutionVector &uCurrentIter,
-                       const SolutionVector &uLastIter)
-    {
-        int succeeded;
-        try {
-            // call the method of the base class
-            this->method().model().updateStaticData(uCurrentIter, uLastIter);
-            ParentType::newtonEndStep(uCurrentIter, uLastIter);
-
-            succeeded = 1;
-            if (this->gridView_().comm().size() > 1)
-                succeeded = this->gridView_().comm().min(succeeded);
-        }
-        catch (Dumux::NumericalProblem &e)
-        {
-            std::cout << "rank " << this->problem_().gridView().comm().rank()
-                      << " caught an exception while updating:" << e.what()
-                      << "\n";
-            succeeded = 0;
-            if (this->gridView_().comm().size() > 1)
-                succeeded = this->gridView_().comm().min(succeeded);
-        }
-
-        if (!succeeded) {
-            DUNE_THROW(NumericalProblem,
-                       "A process did not succeed in linearizing the system");
-        }
-    }
-
-    /*!
-     * \brief Returns true if the current solution can be considered to
-     *        be accurate enough
-     */
-    bool newtonConverged()
-    {
-        if (this->method().model().switched())
-            return false;
-
-        return ParentType::newtonConverged();
-    }
-};
-}
+#include <dumux/porousmediumflow/2p2c/implicit/newtoncontroller.hh>
 
 #endif
diff --git a/dumux/implicit/2p2c/2p2cproperties.hh b/dumux/implicit/2p2c/2p2cproperties.hh
index 1d0a6811bd..dae800ae1b 100644
--- a/dumux/implicit/2p2c/2p2cproperties.hh
+++ b/dumux/implicit/2p2c/2p2cproperties.hh
@@ -1,85 +1,8 @@
-// -*- 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/>.   *
- *****************************************************************************/
-/*!
- * \ingroup Properties
- * \ingroup ImplicitProperties
- * \ingroup TwoPTwoCModel
- *
- * \file
- *
- * \brief Defines the properties required for the two-phase two-component
- *        fully implicit model.
- */
-#ifndef DUMUX_2P2C_PROPERTIES_HH
-#define DUMUX_2P2C_PROPERTIES_HH
+#ifndef DUMUX_2P2C_PROPERTIES_HH_OLD
+#define DUMUX_2P2C_PROPERTIES_HH_OLD
 
-#include <dumux/implicit/box/properties.hh>
-#include <dumux/implicit/cellcentered/properties.hh>
-#include<dumux/porousmediumflow/nonisothermal/implicit/properties.hh>
+#warning this header is deprecated, use dumux/porousmediumflow/2p2c/implicit/properties.hh instead
 
-namespace Dumux
-{
-
-namespace Properties
-{
-//////////////////////////////////////////////////////////////////
-// Type tags
-//////////////////////////////////////////////////////////////////
-
-//! The type tags for the implicit isothermal two-phase two-component problems
-NEW_TYPE_TAG(TwoPTwoC);
-NEW_TYPE_TAG(BoxTwoPTwoC, INHERITS_FROM(BoxModel, TwoPTwoC));
-NEW_TYPE_TAG(CCTwoPTwoC, INHERITS_FROM(CCModel, TwoPTwoC));
-
-//! The type tags for the corresponding non-isothermal problems
-NEW_TYPE_TAG(TwoPTwoCNI, INHERITS_FROM(TwoPTwoC, NonIsothermal));
-NEW_TYPE_TAG(BoxTwoPTwoCNI, INHERITS_FROM(BoxModel, TwoPTwoCNI));
-NEW_TYPE_TAG(CCTwoPTwoCNI, INHERITS_FROM(CCModel, TwoPTwoCNI));
-
-//////////////////////////////////////////////////////////////////
-// Property tags
-//////////////////////////////////////////////////////////////////
-
-NEW_PROP_TAG(NumPhases); //!< Number of fluid phases in the system
-NEW_PROP_TAG(NumComponents); //!< Number of fluid components in the system
-NEW_PROP_TAG(Indices); //!< Enumerations for the model
-NEW_PROP_TAG(Formulation); //!< The formulation of the model
-NEW_PROP_TAG(SpatialParams); //!< The type of the spatial parameters
-NEW_PROP_TAG(FluidSystem); //!< The type of the multi-component relations
-NEW_PROP_TAG(FluidState); //!< The type of the 2p2c fluid state
-
-NEW_PROP_TAG(MaterialLaw); //!< The material law which ought to be used (extracted from the spatial parameters)
-NEW_PROP_TAG(MaterialLawParams); //!< The parameters of the material law (extracted from the spatial parameters)
-NEW_PROP_TAG(EffectiveDiffusivityModel); //!< The employed model for the computation of the effective diffusivity
-
-NEW_PROP_TAG(ProblemEnableGravity); //!< Returns whether gravity is considered in the problem
-NEW_PROP_TAG(UseMoles); //!< Defines whether mole (true) or mass (false) fractions are used
-NEW_PROP_TAG(UseConstraintSolver); //!< Determines whether the constraint solver should be used
-
-NEW_PROP_TAG(ImplicitMassUpwindWeight); //!< The value of the upwind weight for the mass conservation equations
-NEW_PROP_TAG(ImplicitMobilityUpwindWeight); //!< Weight for the upwind mobility in the velocity calculation
-NEW_PROP_TAG(ReplaceCompEqIdx); //!< The index of the total mass balance equation,
-                                //!< if one component balance is replaced (ReplaceCompEqIdx < NumComponents)
-NEW_PROP_TAG(VtkAddVelocity); //!< Returns whether velocity vectors are written into the VTK output
-NEW_PROP_TAG(BaseFluxVariables); //!< The base flux variables
-NEW_PROP_TAG(SpatialParamsForchCoeff); //!< Property for the forchheimer coefficient
-}
-}
+#include <dumux/porousmediumflow/2p2c/implicit/properties.hh>
 
 #endif
diff --git a/dumux/implicit/2p2c/2p2cpropertydefaults.hh b/dumux/implicit/2p2c/2p2cpropertydefaults.hh
index e7c1fbe620..bfc725354a 100644
--- a/dumux/implicit/2p2c/2p2cpropertydefaults.hh
+++ b/dumux/implicit/2p2c/2p2cpropertydefaults.hh
@@ -1,232 +1,8 @@
-// -*- 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/>.   *
- *****************************************************************************/
-/*!
- * \ingroup Properties
- * \ingroup ImplicitProperties
- * \ingroup TwoPTwoCModel
- * \file
- *
- * \brief Defines default values for most properties required by the
- *        two-phase two-component fully implicit model.
- */
-#ifndef DUMUX_2P2C_PROPERTY_DEFAULTS_HH
-#define DUMUX_2P2C_PROPERTY_DEFAULTS_HH
+#ifndef DUMUX_2P2C_PROPERTY_DEFAULTS_HH_OLD
+#define DUMUX_2P2C_PROPERTY_DEFAULTS_HH_OLD
 
-#include "2p2cproperties.hh"
-#include "2p2cmodel.hh"
-#include "2p2cindices.hh"
-#include "2p2cfluxvariables.hh"
-#include "2p2cvolumevariables.hh"
-#include "2p2clocalresidual.hh"
-#include "2p2cnewtoncontroller.hh"
+#warning this header is deprecated, use dumux/porousmediumflow/2p2c/implicit/propertydefaults.hh instead
 
-#include <dumux/porousmediumflow/nonisothermal/implicit/propertydefaults.hh>
-#include <dumux/material/fluidmatrixinteractions/diffusivitymillingtonquirk.hh>
-#include <dumux/porousmediumflow/implicit/darcyfluxvariables.hh>
-#include <dumux/material/spatialparams/implicitspatialparams.hh>
-#include <dumux/material/fluidmatrixinteractions/2p/thermalconductivitysomerton.hh>
-
-namespace Dumux
-{
-
-namespace Properties {
-//////////////////////////////////////////////////////////////////
-// Property values
-//////////////////////////////////////////////////////////////////
-
-/*!
- * \brief Set the property for the number of components.
- *
- * We just forward the number from the fluid system and use a static
- * assert to make sure it is 2.
- */
-SET_PROP(TwoPTwoC, NumComponents)
-{
- private:
-    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
-
- public:
-    static const int value = FluidSystem::numComponents;
-
-    static_assert(value == 2,
-                  "Only fluid systems with 2 components are supported by the 2p-2c model!");
-};
-
-/*!
- * \brief Set the property for the number of fluid phases.
- *
- * We just forward the number from the fluid system and use a static
- * assert to make sure it is 2.
- */
-SET_PROP(TwoPTwoC, NumPhases)
-{
- private:
-    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
-
- public:
-    static const int value = FluidSystem::numPhases;
-    static_assert(value == 2,
-                  "Only fluid systems with 2 phases are supported by the 2p-2c model!");
-};
-
-/*!
- * \brief The fluid state which is used by the volume variables to
- *        store the thermodynamic state. This should be chosen
- *        appropriately for the model ((non-)isothermal, equilibrium, ...).
- *        This can be done in the problem.
- */
-SET_PROP(TwoPTwoC, FluidState){
-    private:
-        typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
-        typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
-    public:
-        typedef Dumux::CompositionalFluidState<Scalar, FluidSystem> type;
-};
-
-//! Set the number of equations to 2
-SET_INT_PROP(TwoPTwoC, NumEq, 2);
-
-//! Set the default formulation to pw-sn
-SET_INT_PROP(TwoPTwoC,
-             Formulation,
-             TwoPTwoCFormulation::pwsn);
-
-//! Set as default that no component mass balance is replaced by the total mass balance
-SET_INT_PROP(TwoPTwoC, ReplaceCompEqIdx, 2);
-
-//! Set the property for the material parameters by extracting it from the material law.
-SET_PROP(TwoPTwoC, MaterialLawParams)
-{
- private:
-    typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw;
-
- public:
-    typedef typename MaterialLaw::Params type;
-};
-
-//! Use the 2p2c local residual operator
-SET_TYPE_PROP(TwoPTwoC,
-              LocalResidual,
-              TwoPTwoCLocalResidual<TypeTag>);
-
-//! Use the 2p2c Newton controller
-SET_TYPE_PROP(TwoPTwoC, NewtonController, TwoPTwoCNewtonController<TypeTag>);
-
-//! Use the 2p2c model
-SET_TYPE_PROP(TwoPTwoC, Model, TwoPTwoCModel<TypeTag>);
-
-//! Use the 2p2c VolumeVariables
-SET_TYPE_PROP(TwoPTwoC, VolumeVariables, TwoPTwoCVolumeVariables<TypeTag>);
-
-//! Use the 2p2c FluxVariables
-SET_TYPE_PROP(TwoPTwoC, FluxVariables, TwoPTwoCFluxVariables<TypeTag>);
-
-//! Set the BaseFluxVariables to realize Darcy flow
-SET_TYPE_PROP(TwoPTwoC, BaseFluxVariables, ImplicitDarcyFluxVariables<TypeTag>);
-
-//! Set the upwind weight for the mass conservation equations
-SET_SCALAR_PROP(TwoPTwoC, ImplicitMassUpwindWeight, 1.0);
-
-//! Set default mobility upwind weight to 1.0, i.e. fully upwind
-SET_SCALAR_PROP(TwoPTwoC, ImplicitMobilityUpwindWeight, 1.0);
-
-//! Set the indices required by the isothermal 2p2c
-SET_PROP(TwoPTwoC, Indices)
-{ private:
-    enum { Formulation = GET_PROP_VALUE(TypeTag, Formulation) };
- public:
-    typedef TwoPTwoCIndices<TypeTag, Formulation, 0> type;
-};
-
-//! Use the ImplicitSpatialParams by default
-SET_TYPE_PROP(TwoPTwoC, SpatialParams, ImplicitSpatialParams<TypeTag>);
-
-//! Use the model after Millington (1961) for the effective diffusivity
-SET_PROP(TwoPTwoC, EffectiveDiffusivityModel)
-{ private :
-    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
- public:
-    typedef DiffusivityMillingtonQuirk<Scalar> type;
-};
-
-//! Disable velocity output by default
-SET_BOOL_PROP(TwoPTwoC, VtkAddVelocity, false);
-
-//! Enable gravity by default
-SET_BOOL_PROP(TwoPTwoC, ProblemEnableGravity, true);
-
-//! Use mole fractions in the balance equations by default
-SET_BOOL_PROP(TwoPTwoC, UseMoles, true);
-
-//! Determines whether the constraint solver is used
-SET_BOOL_PROP(TwoPTwoC, UseConstraintSolver, true);
-
-//! Set default value for the Forchheimer coefficient
-// Source: Ward, J.C. 1964 Turbulent flow in porous media. ASCE J. Hydraul. Div 90.
-//        Actually the Forchheimer coefficient is also a function of the dimensions of the
-//        porous medium. Taking it as a constant is only a first approximation
-//        (Nield, Bejan, Convection in porous media, 2006, p. 10)
-SET_SCALAR_PROP(TwoPTwoC, SpatialParamsForchCoeff, 0.55);
-
-//! Somerton is used as default model to compute the effective thermal heat conductivity
-SET_PROP(TwoPTwoCNI, ThermalConductivityModel)
-{
-private:
-    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
-    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
-public:
-    typedef ThermalConductivitySomerton<Scalar, Indices> type;
-};
-
-//! temperature is already written by the isothermal model
-SET_BOOL_PROP(TwoPTwoCNI, NiOutputLevel, 0);
-
-//////////////////////////////////////////////////////////////////
-// Property values for isothermal model required for the general non-isothermal model
-//////////////////////////////////////////////////////////////////
-
-// set isothermal Model
-SET_TYPE_PROP(TwoPTwoCNI, IsothermalModel, TwoPTwoCModel<TypeTag>);
-
-// set isothermal FluxVariables
-SET_TYPE_PROP(TwoPTwoCNI, IsothermalFluxVariables, TwoPTwoCFluxVariables<TypeTag>);
-
-//set isothermal VolumeVariables
-SET_TYPE_PROP(TwoPTwoCNI, IsothermalVolumeVariables, TwoPTwoCVolumeVariables<TypeTag>);
-
-//set isothermal LocalResidual
-SET_TYPE_PROP(TwoPTwoCNI, IsothermalLocalResidual, TwoPTwoCLocalResidual<TypeTag>);
-
-//set isothermal Indices
-SET_PROP(TwoPTwoCNI, IsothermalIndices)
-{
-private:
-    enum { Formulation = GET_PROP_VALUE(TypeTag, Formulation) };
-public:
-    typedef TwoPTwoCIndices<TypeTag, Formulation, 0> type;
-};
-
-//set isothermal NumEq
-SET_INT_PROP(TwoPTwoCNI, IsothermalNumEq, 2);
-
-}
-
-}
+#include <dumux/porousmediumflow/2p2c/implicit/propertydefaults.hh>
 
 #endif
diff --git a/dumux/implicit/2p2c/2p2cvolumevariables.hh b/dumux/implicit/2p2c/2p2cvolumevariables.hh
index 65ab5a884f..a71c4a04d6 100644
--- a/dumux/implicit/2p2c/2p2cvolumevariables.hh
+++ b/dumux/implicit/2p2c/2p2cvolumevariables.hh
@@ -1,621 +1,8 @@
-// -*- 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/>.   *
- *****************************************************************************/
-/*!
- * \file
- *
- * \brief Contains the quantities which are constant within a
- *        finite volume in the two-phase two-component model.
- */
-#ifndef DUMUX_2P2C_VOLUME_VARIABLES_HH
-#define DUMUX_2P2C_VOLUME_VARIABLES_HH
+#ifndef DUMUX_2P2C_VOLUME_VARIABLES_HH_OLD
+#define DUMUX_2P2C_VOLUME_VARIABLES_HH_OLD
 
-#include <dumux/implicit/model.hh>
-#include <dumux/material/fluidstates/compositionalfluidstate.hh>
-#include <dumux/material/constraintsolvers/computefromreferencephase.hh>
-#include <dumux/material/constraintsolvers/misciblemultiphasecomposition.hh>
-#include "2p2cproperties.hh"
-#include "2p2cindices.hh"
+#warning this header is deprecated, use dumux/porousmediumflow/2p2c/implicit/volumevariables.hh instead
 
-namespace Dumux
-{
-
-/*!
- * \ingroup TwoPTwoCModel
- * \ingroup ImplicitVolumeVariables
- * \brief Contains the quantities which are constant within a
- *        finite volume in the two-phase two-component model.
- */
-template <class TypeTag>
-class TwoPTwoCVolumeVariables : public ImplicitVolumeVariables<TypeTag>
-{
-    typedef ImplicitVolumeVariables<TypeTag> ParentType;
-
-    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) Implementation;
-    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
-    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
-    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw;
-    typedef typename GET_PROP_TYPE(TypeTag, MaterialLawParams) MaterialLawParams;
-    enum {
-        numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
-        numComponents = GET_PROP_VALUE(TypeTag, NumComponents)
-    };
-
-    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
-    enum {
-        wCompIdx = Indices::wCompIdx,
-        nCompIdx = Indices::nCompIdx,
-        wPhaseIdx = Indices::wPhaseIdx,
-        nPhaseIdx = Indices::nPhaseIdx
-    };
-
-    // present phases
-    enum {
-        wPhaseOnly = Indices::wPhaseOnly,
-        nPhaseOnly = Indices::nPhaseOnly,
-        bothPhases = Indices::bothPhases
-    };
-
-    // formulations
-    enum {
-        formulation = GET_PROP_VALUE(TypeTag, Formulation),
-        pwsn = TwoPTwoCFormulation::pwsn,
-        pnsw = TwoPTwoCFormulation::pnsw
-    };
-
-    // primary variable indices
-    enum {
-        switchIdx = Indices::switchIdx,
-        pressureIdx = Indices::pressureIdx
-    };
-
-    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
-    typedef typename GridView::template Codim<0>::Entity Element;
-    enum { dim = GridView::dimension};
-
-    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
-    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
-    typedef Dumux::MiscibleMultiPhaseComposition<Scalar, FluidSystem> MiscibleMultiPhaseComposition;
-    static const bool useMoles = GET_PROP_VALUE(TypeTag, UseMoles);
-    static const bool useConstraintSolver = GET_PROP_VALUE(TypeTag, UseConstraintSolver);
-    static_assert(useMoles || (!useMoles && useConstraintSolver),
-                  "if UseMoles is set false, UseConstraintSolver has to be set to true");
-    typedef Dumux::ComputeFromReferencePhase<Scalar, FluidSystem> ComputeFromReferencePhase;
-
-    enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) };
-    enum { dofCodim = isBox ? dim : 0 };
-
-public:
-
-    typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState;
-
-    /*!
-     * \copydoc ImplicitVolumeVariables::update
-     */
-    void update(const PrimaryVariables &priVars,
-                const Problem &problem,
-                const Element &element,
-                const FVElementGeometry &fvGeometry,
-                const int scvIdx,
-                const bool isOldSol)
-    {
-        ParentType::update(priVars,
-                           problem,
-                           element,
-                           fvGeometry,
-                           scvIdx,
-                           isOldSol);
-
-        completeFluidState(priVars, problem, element, fvGeometry, scvIdx, fluidState_, isOldSol);
-
-        /////////////
-        // calculate the remaining quantities
-        /////////////
-        const MaterialLawParams &materialParams =
-        problem.spatialParams().materialLawParams(element, fvGeometry, scvIdx);
-
-        // Second instance of a parameter cache.
-        // Could be avoided if diffusion coefficients also
-        // became part of the fluid state.
-        typename FluidSystem::ParameterCache paramCache;
-        paramCache.updateAll(fluidState_);
-        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
-
-
-            // relative permeabilities
-            Scalar kr;
-            if (phaseIdx == wPhaseIdx)
-                kr = MaterialLaw::krw(materialParams, saturation(wPhaseIdx));
-            else // ATTENTION: krn requires the wetting phase saturation
-                // as parameter!
-                kr = MaterialLaw::krn(materialParams, saturation(wPhaseIdx));
-            relativePermeability_[phaseIdx] = kr;
-            Valgrind::CheckDefined(relativePermeability_[phaseIdx]);
-
-            // binary diffusion coefficients
-            diffCoeff_[phaseIdx] =
-            FluidSystem::binaryDiffusionCoefficient(fluidState_,
-                                                    paramCache,
-                                                    phaseIdx,
-                                                    wCompIdx,
-                                                    nCompIdx);
-            Valgrind::CheckDefined(diffCoeff_[phaseIdx]);
-        }
-
-        // porosity
-        porosity_ = problem.spatialParams().porosity(element,
-                                                     fvGeometry,
-                                                     scvIdx);
-        Valgrind::CheckDefined(porosity_);
-
-        // energy related quantities not contained in the fluid state
-        asImp_().updateEnergy_(priVars, problem, element, fvGeometry, scvIdx, isOldSol);
-    }
-
-    /*!
-     * \copydoc ImplicitModel::completeFluidState
-     * \param isOldSol Specifies whether this is the previous solution or the current one
-     */
-    static void completeFluidState(const PrimaryVariables& priVars,
-                                   const Problem& problem,
-                                   const Element& element,
-                                   const FVElementGeometry& fvGeometry,
-                                   int scvIdx,
-                                   FluidState& fluidState,
-                                   bool isOldSol = false)
-    {
-        Scalar t = Implementation::temperature_(priVars, problem, element,
-                                                fvGeometry, scvIdx);
-        fluidState.setTemperature(t);
-        int dofIdxGlobal = problem.model().dofMapper().subIndex(element, scvIdx, dofCodim);
-        int phasePresence = problem.model().phasePresence(dofIdxGlobal, isOldSol);
-
-        /////////////
-        // set the saturations
-        /////////////
-        Scalar sn;
-        if (phasePresence == nPhaseOnly)
-            sn = 1.0;
-        else if (phasePresence == wPhaseOnly) {
-            sn = 0.0;
-        }
-        else if (phasePresence == bothPhases) {
-            if (formulation == pwsn)
-                sn = priVars[switchIdx];
-            else if (formulation == pnsw)
-                sn = 1.0 - priVars[switchIdx];
-            else DUNE_THROW(Dune::InvalidStateException, "Formulation: " << formulation << " is invalid.");
-        }
-        else DUNE_THROW(Dune::InvalidStateException, "phasePresence: " << phasePresence << " is invalid.");
-        fluidState.setSaturation(wPhaseIdx, 1 - sn);
-        fluidState.setSaturation(nPhaseIdx, sn);
-
-        /////////////
-        // set the pressures of the fluid phases
-        /////////////
-
-        // calculate capillary pressure
-        const MaterialLawParams &materialParams =
-        problem.spatialParams().materialLawParams(element, fvGeometry, scvIdx);
-        Scalar pc = MaterialLaw::pc(materialParams, 1 - sn);
-
-        if (formulation == pwsn) {
-            fluidState.setPressure(wPhaseIdx, priVars[pressureIdx]);
-            fluidState.setPressure(nPhaseIdx, priVars[pressureIdx] + pc);
-        }
-        else if (formulation == pnsw) {
-            fluidState.setPressure(nPhaseIdx, priVars[pressureIdx]);
-            fluidState.setPressure(wPhaseIdx, priVars[pressureIdx] - pc);
-        }
-        else DUNE_THROW(Dune::InvalidStateException, "Formulation: " << formulation << " is invalid.");
-
-        /////////////
-        // calculate the phase compositions
-        /////////////
-        typename FluidSystem::ParameterCache paramCache;
-
-        //get the phase pressures and set the fugacity coefficients here if constraintsolver is not used
-        Scalar pn = 0;
-        Scalar pw = 0;
-
-        if(!useConstraintSolver) {
-            if (formulation == pwsn) {
-                pw = priVars[pressureIdx];
-                pn = pw + pc;
-            }
-            else {
-                pn = priVars[pressureIdx];
-                pw = pn - pc;
-            }
-
-            for (int phaseIdx = 0; phaseIdx < numPhases; ++ phaseIdx) {
-                assert(FluidSystem::isIdealMixture(phaseIdx));
-
-                for (int compIdx = 0; compIdx < numComponents; ++ compIdx) {
-                    Scalar phi = FluidSystem::fugacityCoefficient(fluidState, paramCache, phaseIdx, compIdx);
-                    fluidState.setFugacityCoefficient(phaseIdx, compIdx, phi);
-                }
-            }
-        }
-
-        // now comes the tricky part: calculate phase compositions
-        if (phasePresence == bothPhases) {
-            // both phases are present, phase compositions are a
-            // result of the the nonwetting <-> wetting equilibrium. This is
-            // the job of the "MiscibleMultiPhaseComposition"
-            // constraint solver
-            if(useConstraintSolver) {
-                MiscibleMultiPhaseComposition::solve(fluidState,
-                                                     paramCache,
-                                                     /*setViscosity=*/true,
-                                                     /*setInternalEnergy=*/false);
-            }
-            // ... or calculated explicitly this way ...
-            else {
-                //get the partial pressure of the main component of the the wetting phase ("H20") within the nonwetting (gas) phase == vapor pressure due to equilibrium
-                //note that in this case the fugacityCoefficient * pw is the vapor pressure (see implementation in respective fluidsystem)
-                Scalar partPressH2O = FluidSystem::fugacityCoefficient(fluidState,
-                                                                       wPhaseIdx,
-                                                                       wCompIdx) * pw;
-
-                // get the partial pressure of the main component of the the nonwetting (gas) phase ("Air")
-                Scalar partPressAir = pn - partPressH2O;
-
-                //calculate the mole fractions of the components within the nonwetting phase
-                Scalar xnn = partPressAir/pn;
-                Scalar xnw = partPressH2O/pn;
-
-                // calculate the mole fractions of the components within the wetting phase
-                //note that in this case the fugacityCoefficient * pw is the Henry Coefficient (see implementation in respective fluidsystem)
-                Scalar xwn = partPressAir
-                  / (FluidSystem::fugacityCoefficient(fluidState,
-                                                      wPhaseIdx,nCompIdx)
-                  * pw);
-
-                Scalar xww = 1.0 -xwn;
-
-                //set all mole fractions
-                fluidState.setMoleFraction(wPhaseIdx, wCompIdx, xww);
-                fluidState.setMoleFraction(wPhaseIdx, nCompIdx, xwn);
-                fluidState.setMoleFraction(nPhaseIdx, wCompIdx, xnw);
-                fluidState.setMoleFraction(nPhaseIdx, nCompIdx, xnn);
-
-                paramCache.updateComposition(fluidState, wPhaseIdx);
-                paramCache.updateComposition(fluidState, nPhaseIdx);
-
-                //set the phase densities
-                Scalar rhoW = FluidSystem::density(fluidState, paramCache, wPhaseIdx);
-                Scalar rhoN = FluidSystem::density(fluidState, paramCache, nPhaseIdx);
-
-                fluidState.setDensity(wPhaseIdx, rhoW);
-                fluidState.setDensity(nPhaseIdx, rhoN);
-            }
-        }
-        else if (phasePresence == nPhaseOnly) {
-            // only the nonwetting phase is present, i.e. nonwetting phase
-            // composition is stored explicitly.
-            if(useMoles)
-            {
-                fluidState.setMoleFraction(nPhaseIdx, nCompIdx, 1 - priVars[switchIdx]);
-                fluidState.setMoleFraction(nPhaseIdx, wCompIdx, priVars[switchIdx]);
-            }
-            else
-            {
-                // setMassFraction() has only to be called 1-numComponents times
-                fluidState.setMassFraction(nPhaseIdx, wCompIdx, priVars[switchIdx]);
-            }
-
-            // calculate the composition of the remaining phases (as
-            // well as the densities of all phases). This is the job
-            // of the "ComputeFromReferencePhase" constraint solver
-            if (useConstraintSolver) {
-                ComputeFromReferencePhase::solve(fluidState,
-                                                 paramCache,
-                                                 nPhaseIdx,
-                                                 /*setViscosity=*/true,
-                                                 /*setInternalEnergy=*/false);
-            }
-            // ... or calculated explicitly this way ...
-            else {
-                // note that the water phase is actually not existing!
-                // thus, this is used as phase switch criterion
-                Scalar xnw = priVars[switchIdx];
-                Scalar xnn = 1.0 -xnw;
-
-                //first, xww:
-                // xnw * pn = "actual" (hypothetical) vapor pressure
-                // fugacityCoefficient * pw = vapor pressure given by thermodynamic conditions
-                // Here, xww is not actually the mole fraction of water in the wetting phase
-                // xww is only the ratio of "actual" vapor pressure / "thermodynamic" vapor pressure
-                // If xww > 1 : gas is over-saturated with water vapor,
-                // condensation takes place (see switch criterion in model)
-                Scalar xww = xnw * pn
-                  / (FluidSystem::fugacityCoefficient(fluidState,
-                                                      wPhaseIdx,wCompIdx)
-                     * pw);
-
-                // now, xwn:
-                //partialPressure / xwn = Henry
-                //partialPressure = xnn * pn
-                //xwn = xnn * pn / Henry
-                // Henry = fugacityCoefficient * pw
-                Scalar xwn = xnn * pn / (FluidSystem::fugacityCoefficient(fluidState,
-                                                                          wPhaseIdx,nCompIdx)
-                                         * pw);
-
-                fluidState.setMoleFraction(wPhaseIdx, wCompIdx, xww);
-                fluidState.setMoleFraction(wPhaseIdx, nCompIdx, xwn);
-
-                paramCache.updateComposition(fluidState, wPhaseIdx);
-                paramCache.updateComposition(fluidState, nPhaseIdx);
-
-                Scalar rhoW = FluidSystem::density(fluidState, paramCache, wPhaseIdx);
-                Scalar rhoN = FluidSystem::density(fluidState, paramCache, nPhaseIdx);
-
-                fluidState.setDensity(wPhaseIdx, rhoW);
-                fluidState.setDensity(nPhaseIdx, rhoN);
-            }
-        }
-        else if (phasePresence == wPhaseOnly) {
-            // only the wetting phase is present, i.e. wetting phase
-            // composition is stored explicitly.
-            if(useMoles) // mole-fraction formulation
-            {
-                fluidState.setMoleFraction(wPhaseIdx, wCompIdx, 1-priVars[switchIdx]);
-                fluidState.setMoleFraction(wPhaseIdx, nCompIdx, priVars[switchIdx]);
-            }
-            else // mass-fraction formulation
-            {
-                // setMassFraction() has only to be called 1-numComponents times
-                fluidState.setMassFraction(wPhaseIdx, nCompIdx, priVars[switchIdx]);
-            }
-
-            // calculate the composition of the remaining phases (as
-            // well as the densities of all phases). This is the job
-            // of the "ComputeFromReferencePhase" constraint solver
-            if (useConstraintSolver) {
-                ComputeFromReferencePhase::solve(fluidState,
-                                                 paramCache,
-                                                 wPhaseIdx,
-                                                 /*setViscosity=*/true,
-                                                 /*setInternalEnergy=*/false);
-            }
-            // ... or calculated explicitly this way ...
-            else {
-                // note that the gas phase is actually not existing!
-                // thus, this is used as phase switch criterion
-                Scalar xwn = priVars[switchIdx];
-
-                //first, xnw:
-                //psteam = xnw * pn = partial pressure of water in gas phase
-                //psteam = fugacityCoefficient * pw
-                Scalar xnw = (FluidSystem::fugacityCoefficient(fluidState,
-                                                               wPhaseIdx,wCompIdx)
-                              * pw) / pn ;
-
-                //now, xnn:
-                // xwn = partialPressure / Henry
-                // partialPressure = pn * xnn
-                // xwn = pn * xnn / Henry
-                // xnn = xwn * Henry / pn
-                // Henry = fugacityCoefficient * pw
-                Scalar xnn = xwn * (FluidSystem::fugacityCoefficient(fluidState,
-                                                                     wPhaseIdx,nCompIdx)
-                                    * pw) / pn ;
-
-                fluidState.setMoleFraction(nPhaseIdx, nCompIdx, xnn);
-                fluidState.setMoleFraction(nPhaseIdx, wCompIdx, xnw);
-
-                paramCache.updateComposition(fluidState, wPhaseIdx);
-                paramCache.updateComposition(fluidState, nPhaseIdx);
-
-                Scalar rhoW = FluidSystem::density(fluidState, paramCache, wPhaseIdx);
-                Scalar rhoN = FluidSystem::density(fluidState, paramCache, nPhaseIdx);
-
-                fluidState.setDensity(wPhaseIdx, rhoW);
-                fluidState.setDensity(nPhaseIdx, rhoN);
-            }
-        }
-
-        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
-            //set the viscosity here if constraintsolver is not used
-            if(!useConstraintSolver) {
-                const Scalar mu =
-                FluidSystem::viscosity(fluidState,
-                                       paramCache,
-                                       phaseIdx);
-                fluidState.setViscosity(phaseIdx,mu);
-            }
-            // compute and set the enthalpy
-            Scalar h = Implementation::enthalpy_(fluidState, paramCache, phaseIdx);
-            fluidState.setEnthalpy(phaseIdx, h);
-        }
-   }
-
-
-    /*!
-     * \brief Returns the phase state within the control volume.
-     */
-    const FluidState &fluidState() const
-    { return fluidState_; }
-
-    /*!
-     * \brief Returns the saturation of a given phase within
-     *        the control volume in \f$[-]\f$.
-     *
-     * \param phaseIdx The phase index
-     */
-    Scalar saturation(const int phaseIdx) const
-    { return fluidState_.saturation(phaseIdx); }
-
-    /*!
-     * \brief Returns the mass fraction of a given component in a
-     *        given phase within the control volume in \f$[-]\f$.
-     *
-     * \param phaseIdx The phase index
-     * \param compIdx The component index
-     */
-    Scalar massFraction(const int phaseIdx, const int compIdx) const
-    { return fluidState_.massFraction(phaseIdx, compIdx); }
-
-    /*!
-     * \brief Returns the mole fraction of a given component in a
-     *        given phase within the control volume in \f$[-]\f$.
-     *
-     * \param phaseIdx The phase index
-     * \param compIdx The component index
-     */
-    Scalar moleFraction(const int phaseIdx, const int compIdx) const
-    { return fluidState_.moleFraction(phaseIdx, compIdx); }
-
-    /*!
-     * \brief Returns the mass density of a given phase within the
-     *        control volume in \f$[kg/m^3]\f$.
-     *
-     * \param phaseIdx The phase index
-     */
-    Scalar density(const int phaseIdx) const
-    { return fluidState_.density(phaseIdx); }
-
-    /*!
-     * \brief Returns the dynamic viscosity of the fluid within the
-     *        control volume in \f$\mathrm{[Pa s]}\f$.
-     *
-     * \param phaseIdx The phase index
-     */
-    Scalar viscosity(const int phaseIdx) const
-    { return fluidState_.viscosity(phaseIdx); }
-
-    /*!
-     * \brief Returns the mass density of a given phase within the
-     *        control volume in \f$[mol/m^3]\f$.
-     *
-     * \param phaseIdx The phase index
-     */
-    Scalar molarDensity(const int phaseIdx) const
-    { return fluidState_.density(phaseIdx) / fluidState_.averageMolarMass(phaseIdx); }
-
-    /*!
-     * \brief Returns the effective pressure of a given phase within
-     *        the control volume in \f$[kg/(m*s^2)=N/m^2=Pa]\f$.
-     *
-     * \param phaseIdx The phase index
-     */
-    Scalar pressure(const int phaseIdx) const
-    { return fluidState_.pressure(phaseIdx); }
-
-    /*!
-     * \brief Returns temperature within the control volume in \f$[K]\f$.
-     *
-     * Note that we assume thermodynamic equilibrium, i.e. the
-     * temperature of the rock matrix and of all fluid phases are
-     * identical.
-     */
-    Scalar temperature() const
-    { return fluidState_.temperature(/*phaseIdx=*/0); }
-
-    /*!
-     * \brief Returns the relative permeability of a given phase within
-     *        the control volume in \f$[-]\f$.
-     *
-     * \param phaseIdx The phase index
-     */
-    Scalar relativePermeability(const int phaseIdx) const
-    {
-        return relativePermeability_[phaseIdx];
-    }
-
-    /*!
-     * \brief Returns the effective mobility of a given phase within
-     *        the control volume in \f$[s*m/kg]\f$.
-     *
-     * \param phaseIdx The phase index
-     */
-    Scalar mobility(const int phaseIdx) const
-    {
-        return relativePermeability_[phaseIdx]/fluidState_.viscosity(phaseIdx);
-    }
-
-    /*!
-     * \brief Returns the effective capillary pressure within the control volume
-     *        in \f$[kg/(m*s^2)=N/m^2=Pa]\f$.
-     */
-    Scalar capillaryPressure() const
-    { return fluidState_.pressure(nPhaseIdx) - fluidState_.pressure(wPhaseIdx); }
-
-    /*!
-     * \brief Returns the average porosity within the control volume in \f$[-]\f$.
-     */
-    Scalar porosity() const
-    { return porosity_; }
-
-    /*!
-     * \brief Returns the binary diffusion coefficients for a phase in \f$[m^2/s]\f$.
-     */
-    Scalar diffCoeff(const int phaseIdx) const
-    { return diffCoeff_[phaseIdx]; }
-
-
-protected:
-    static Scalar temperature_(const PrimaryVariables &priVars,
-                               const Problem& problem,
-                               const Element &element,
-                               const FVElementGeometry &fvGeometry,
-                               int scvIdx)
-    {
-        return problem.temperatureAtPos(fvGeometry.subContVol[scvIdx].global);
-    }
-
-    template<class ParameterCache>
-    static Scalar enthalpy_(const FluidState& fluidState,
-                            const ParameterCache& paramCache,
-                            const int phaseIdx)
-    {
-        return 0;
-    }
-
-    /*!
-     * \brief Called by update() to compute the energy related quantities
-     */
-    void updateEnergy_(const PrimaryVariables &sol,
-                       const Problem &problem,
-                       const Element &element,
-                       const FVElementGeometry &fvGeometry,
-                       const int scvIdx,
-                       bool isOldSol)
-    { }
-
-    Scalar porosity_; //!< Effective porosity within the control volume
-    Scalar relativePermeability_[numPhases]; //!< Relative permeability within the control volume
-    Scalar diffCoeff_[numPhases]; //!< Binary diffusion coefficients for the phases
-    FluidState fluidState_;
-
-private:
-    Implementation &asImp_()
-    { return *static_cast<Implementation*>(this); }
-
-    const Implementation &asImp_() const
-    { return *static_cast<const Implementation*>(this); }
-
-
-};
-
-} // end namespace
+#include <dumux/porousmediumflow/2p2c/implicit/volumevariables.hh>
 
 #endif
diff --git a/dumux/implicit/2pnc/2pncfluxvariables.hh b/dumux/implicit/2pnc/2pncfluxvariables.hh
index 541db7b224..ce450cea11 100644
--- a/dumux/implicit/2pnc/2pncfluxvariables.hh
+++ b/dumux/implicit/2pnc/2pncfluxvariables.hh
@@ -1,415 +1,8 @@
-// -*- 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/>.   *
- *****************************************************************************/
-/*!
- * \file
- * \brief Contains the data which is required to calculate
- *        all fluxes of components over a face of a finite volume for
- *        the two-phase two-component model fully implicit model.
- */
-#ifndef DUMUX_2PNC_FLUX_VARIABLES_HH
-#define DUMUX_2PNC_FLUX_VARIABLES_HH
+#ifndef DUMUX_2PNC_FLUX_VARIABLES_HH_OLD
+#define DUMUX_2PNC_FLUX_VARIABLES_HH_OLD
 
-#include <dumux/common/math.hh>
-#include <dumux/common/spline.hh>
+#warning this header is deprecated, use dumux/porousmediumflow/2pnc/implicit/fluxvariables.hh instead
 
-#include "2pncproperties.hh"
-
-namespace Dumux
-{
-/*!
- * \ingroup TwoPNCModel
- * \ingroup ImplicitFluxVariables
- * \brief Contains the data which is required to calculate
- *        all fluxes of components over a face of a finite volume for
- *        the two-phase n-component fully implicit model.
- *
- * This means pressure and concentration gradients, phase densities at
- * the integration point, etc.
- */
-
-template <class TypeTag>
-class TwoPNCFluxVariables : public GET_PROP_TYPE(TypeTag, BaseFluxVariables)
-{
-    typedef typename GET_PROP_TYPE(TypeTag, BaseFluxVariables) BaseFluxVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
-    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
-
-    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
-    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
-
-    typedef typename GridView::ctype CoordScalar;
-    typedef typename GridView::template Codim<0>::Entity Element;
-    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
-
-    enum {
-            dim = GridView::dimension,
-            dimWorld = GridView::dimensionworld,
-            numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
-            numComponents = GET_PROP_VALUE(TypeTag, NumComponents),
-          };
-
-    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
-    typedef typename GET_PROP_TYPE(TypeTag, SpatialParams) SpatialParams;
-    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
-//     typedef typename FVElementGeometry::SubControlVolume SCV;
-    typedef typename FVElementGeometry::SubControlVolumeFace SCVFace;
-
-    typedef Dune::FieldVector<CoordScalar, dimWorld> DimVector;
-    typedef Dune::FieldMatrix<CoordScalar, dim, dim> DimMatrix;
-
-    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
-    enum {
-            wPhaseIdx = FluidSystem::wPhaseIdx,
-            nPhaseIdx = FluidSystem::nPhaseIdx,
-            wCompIdx  = FluidSystem::wCompIdx,
-         };
-
-public:
-    /*!
-     * \brief The constructor
-     *
-     * \param problem The problem
-     * \param element The finite element
-     * \param fvGeometry The finite-volume geometry in the fully implicit scheme
-     * \param fIdx The local index of the sub-control-volume face
-     * \param elemVolVars The volume variables of the current element
-     * \param onBoundary Evaluate flux at inner sub-control-volume face or on a boundary face
-     */
-    TwoPNCFluxVariables(const Problem &problem,
-                     const Element &element,
-                     const FVElementGeometry &fvGeometry,
-                     const int fIdx,
-                     const ElementVolumeVariables &elemVolVars,
-                     const bool onBoundary = false)
-    : BaseFluxVariables(problem, element, fvGeometry, fIdx, elemVolVars, onBoundary)
-    {
-        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
-            density_[phaseIdx] = Scalar(0);
-            molarDensity_[phaseIdx] = Scalar(0);
-            potentialGrad_[phaseIdx] = Scalar(0);
-            for (int compIdx = 0; compIdx < numComponents; ++compIdx)
-            {
-                massFractionGrad_[phaseIdx][compIdx] = Scalar(0);
-                moleFractionGrad_[phaseIdx][compIdx] = Scalar(0);
-            }
-        }
-        calculateGradients_(problem, element, elemVolVars);
-        calculateVelocities_(problem, element, elemVolVars);
-        calculateporousDiffCoeff_(problem, element, elemVolVars);
-    };
-
-protected:
-    void calculateGradients_(const Problem &problem,
-                             const Element &element,
-                             const ElementVolumeVariables &elemVolVars)
-    {
-        // calculate gradients
-        DimVector tmp(0.0);
-        for (int idx = 0;
-             idx < this->fvGeometry_.numScv;
-             idx++) // loop over adjacent vertices
-        {
-            // FE gradient at vertex idx
-            const DimVector &feGrad = face().grad[idx];
-
-            // compute sum of pressure gradients for each phase
-            for (int phaseIdx = 0; phaseIdx < numPhases; phaseIdx++)
-            {
-                // the pressure gradient
-                tmp = feGrad;
-                tmp *= elemVolVars[idx].pressure(phaseIdx); //FE grad times phase pressure
-                potentialGrad_[phaseIdx] += tmp;
-            }
-
-            // the concentration gradient of the non-wetting
-            // component in the wetting phase
-
-            for(int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
-            {
-                for(int compIdx = 0; compIdx < numComponents; ++compIdx)
-                {
-                    if(compIdx != phaseIdx) //No grad is needed for this case
-                    {
-                        tmp = feGrad;
-                        tmp *= elemVolVars[idx].massFraction(phaseIdx, compIdx);
-                        massFractionGrad_[phaseIdx][compIdx] += tmp;
-
-                        tmp = feGrad;
-                        tmp *= elemVolVars[idx].moleFraction(phaseIdx, compIdx);
-                        moleFractionGrad_[phaseIdx][compIdx] += tmp;
-                    }
-                }
-            }
-        }
-
-        // correct the pressure gradients by the hydrostatic
-        // pressure due to gravity
-        for (int phaseIdx=0; phaseIdx < numPhases; phaseIdx++)
-        {
-            int i = face().i;
-            int j = face().j;
-            Scalar fI = rhoFactor_(phaseIdx, i, elemVolVars);
-            Scalar fJ = rhoFactor_(phaseIdx, j, elemVolVars);
-            if (fI + fJ <= 0)
-                fI = fJ = 0.5; // doesn't matter because no phase is
-                               // present in both cells!
-            density_[phaseIdx] =
-                (fI*elemVolVars[i].density(phaseIdx) +
-                 fJ*elemVolVars[j].density(phaseIdx))
-                /
-                (fI + fJ);
-            // phase density
-            molarDensity_[phaseIdx]
-                =
-                (fI*elemVolVars[i].molarDensity(phaseIdx) +
-                 fJ*elemVolVars[j].molarDensity(phaseIdx))
-                /
-                (fI + fJ); //arithmetic averaging
-
-            tmp = problem.gravity();
-            tmp *= density_[phaseIdx];
-
-            potentialGrad_[phaseIdx] -= tmp;
-        }
-    }
-
-    Scalar rhoFactor_(int phaseIdx, int scvIdx, const ElementVolumeVariables &vDat)
-    {
-
-        static const Scalar eps = 1e-2;
-        const Scalar sat = vDat[scvIdx].density(phaseIdx);
-        if (sat > eps)
-            return 0.5;
-        if (sat <= 0)
-            return 0;
-
-        static const Dumux::Spline<Scalar> sp(0, eps, // x0, x1
-                                              0, 0.5, // y0, y1
-                                              0, 0); // m0, m1
-        return sp.eval(sat);
-    }
-
-    void calculateVelocities_(const Problem &problem,
-                              const Element &element,
-                              const ElementVolumeVariables &elemVolVars)
-    {
-        const SpatialParams &spatialParams = problem.spatialParams();
-        // multiply the pressure potential with the intrinsic
-        // permeability
-        DimMatrix K(0.0);
-
-        for (int phaseIdx=0; phaseIdx < numPhases; phaseIdx++)
-        {
-            auto K_i = spatialParams.intrinsicPermeability(element,this->fvGeometry_,face().i);
-            //K_i *= volVarsI.permFactor();
-
-            auto K_j = spatialParams.intrinsicPermeability(element,this->fvGeometry_,face().j);
-            //K_j *= volVarsJ.permFactor();
-
-            spatialParams.meanK(K,K_i,K_j);
-
-            K.mv(potentialGrad_[phaseIdx], Kmvp_[phaseIdx]);
-            KmvpNormal_[phaseIdx] = - (Kmvp_[phaseIdx] * face().normal);
-        }
-
-        // set the upstream and downstream vertices
-        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
-        {
-            upstreamIdx_[phaseIdx] = face().i;
-            downstreamIdx_[phaseIdx] = face().j;
-
-            if (KmvpNormal_[phaseIdx] < 0) {
-                std::swap(upstreamIdx_[phaseIdx],
-                          downstreamIdx_[phaseIdx]);
-            }
-        }
-    }
-
-    void calculateporousDiffCoeff_(const Problem &problem,
-                                   const Element &element,
-                                   const ElementVolumeVariables &elemVolVars)
-    {
-        const VolumeVariables &volVarsI = elemVolVars[face().i];
-        const VolumeVariables &volVarsJ = elemVolVars[face().j];
-
-        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
-        {
-            /* If there is no phase saturation on either side of the face
-                * no diffusion takes place */
-
-            if (volVarsI.saturation(phaseIdx) <= 0 ||
-                volVarsJ.saturation(phaseIdx) <= 0)
-                {
-                for (int compIdx = 0; compIdx < numComponents; ++compIdx)
-                    {
-                        porousDiffCoeff_[phaseIdx][compIdx] = 0.0;
-                    }
-                }
-
-            else
-            {
-            // calculate tortuosity at the nodes i and j needed
-            // for porous media diffusion coefficient
-            Scalar tauI =  1.0/(volVarsI.porosity() * volVarsI.porosity()) *
-                            pow(volVarsI.porosity() * volVarsI.saturation(phaseIdx), 7.0/3);
-
-            Scalar tauJ =   1.0/(volVarsJ.porosity() * volVarsJ.porosity()) *
-                            pow(volVarsJ.porosity() * volVarsJ.saturation(phaseIdx), 7.0/3);
-            // Diffusion coefficient in the porous medium
-
-            // -> harmonic mean
-            for (int compIdx = 0; compIdx < numComponents; ++compIdx)
-                {
-                    if(phaseIdx==compIdx)
-                        porousDiffCoeff_[phaseIdx][compIdx] = 0.0;
-                    else
-                    {
-                        porousDiffCoeff_[phaseIdx][compIdx] = harmonicMean(volVarsI.porosity() * volVarsI.saturation(phaseIdx) * tauI * volVarsI.diffCoeff(phaseIdx, compIdx),
-                                                                            volVarsJ.porosity() * volVarsJ.saturation(phaseIdx) * tauJ * volVarsJ.diffCoeff(phaseIdx, compIdx));
-                    }
-                }
-            }
-        }
-    }
-
-public:
-    /*!
-     * \brief Return the pressure potential multiplied with the
-     *        intrinsic permeability which goes from vertex i to
-     *        vertex j.
-     *
-     * Note that the length of the face's normal is the area of the
-     * face, so this is not the actual velocity by the integral of
-     * the velocity over the face's area. Also note that the phase
-     * mobility is not yet included here since this would require a
-     * decision on the upwinding approach (which is done in the
-     * model and/or local residual file).
-     *
-     *   \param phaseIdx The phase index
-     */
-    Scalar KmvpNormal(int phaseIdx) const
-    { return KmvpNormal_[phaseIdx]; }
-
-    /*!
-     * \brief Return the pressure potential multiplied with the
-     *        intrinsic permeability as vector (for velocity output)
-     *
-     *   \param phaseIdx The phase index
-     */
-    DimVector Kmvp(int phaseIdx) const
-    { return Kmvp_[phaseIdx]; }
-
-    /*!
-     * \brief Return the local index of the upstream control volume
-     *        for a given phase.
-     *
-     *   \param phaseIdx The phase index
-     */
-    int upstreamIdx(int phaseIdx) const
-    { return upstreamIdx_[phaseIdx]; }
-
-    /*!
-     * \brief Return the local index of the downstream control volume
-     *        for a given phase.
-     *
-     *   \param phaseIdx The phase index
-     */
-    int downstreamIdx(int phaseIdx) const
-    { return downstreamIdx_[phaseIdx]; }
-
-    /*!
-     * \brief The binary diffusion coefficient for each fluid phase.
-     *
-     *   \param phaseIdx The phase index
-     *   \param compIdx The component index
-     */
-    Scalar porousDiffCoeff(int phaseIdx, int compIdx) const
-    { return porousDiffCoeff_[phaseIdx][compIdx];}
-
-    /*!
-     * \brief Return density \f$\mathrm{[kg/m^3]}\f$ of a phase at the integration
-     *        point.
-     *
-     * \param phaseIdx The phase index
-     */
-    Scalar density(int phaseIdx) const
-    { return density_[phaseIdx]; }
-
-    /*!
-     * \brief Return molar density \f$\mathrm{[mol/m^3]}\f$ of a phase at the integration
-     *        point.
-     *
-     * \param phaseIdx The phase index
-     */
-    Scalar molarDensity(int phaseIdx) const
-    { return molarDensity_[phaseIdx]; }
-
-    /*!
-     * \brief The concentration gradient of a component in a phase.
-     *
-     * \param phaseIdx The phase index
-     * \param compIdx The component index
-     */
-    const DimVector &massFractionGrad(int phaseIdx, int compIdx) const
-    { return massFractionGrad_[phaseIdx][compIdx]; }
-
-    /*!
-     * \brief The molar concentration gradient of a component in a phase.
-     *
-     * \param phaseIdx The phase index
-     * \param compIdx The component index
-     */
-    const DimVector &moleFractionGrad(int phaseIdx, int compIdx) const
-    { return moleFractionGrad_[phaseIdx][compIdx]; }
-
-    const SCVFace &face() const
-    {
-    if (this->onBoundary_)
-        return this->fvGeometry_.boundaryFace[this->faceIdx_];
-    else
-        return this->fvGeometry_.subContVolFace[this->faceIdx_];
-    }
-
-protected:
-
-    // gradients
-    DimVector potentialGrad_[numPhases];
-    DimVector massFractionGrad_[numPhases][numComponents];
-    DimVector moleFractionGrad_[numPhases][numComponents];
-
-    // density of each face at the integration point
-    Scalar density_[numPhases], molarDensity_[numPhases];
-
-    // intrinsic permeability times pressure potential gradient
-    DimVector Kmvp_[numPhases];
-    // projected on the face normal
-    Scalar KmvpNormal_[numPhases];
-
-    // local index of the upwind vertex for each phase
-    int upstreamIdx_[numPhases];
-    // local index of the downwind vertex for each phase
-    int downstreamIdx_[numPhases];
-
-    // the diffusion coefficient for the porous medium
-    Dune::FieldMatrix<Scalar, numPhases, numComponents> porousDiffCoeff_;
-};
-
-} // end namespace
+#include <dumux/porousmediumflow/2pnc/implicit/fluxvariables.hh>
 
 #endif
diff --git a/dumux/implicit/2pnc/2pncindices.hh b/dumux/implicit/2pnc/2pncindices.hh
index 16e55dad8d..309c8c7318 100644
--- a/dumux/implicit/2pnc/2pncindices.hh
+++ b/dumux/implicit/2pnc/2pncindices.hh
@@ -1,80 +1,8 @@
-// -*- 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_2PNC_INDICES_HH_OLD
+#define DUMUX_2PNC_INDICES_HH_OLD
 
-/*!
- * \file
- * \brief Defines the indices required for the two-phase n-component
- *        fully implicit model.
- */
-#ifndef DUMUX_2PNC_INDICES_HH
-#define DUMUX_2PNC_INDICES_HH
-#include "2pncproperties.hh"
-namespace Dumux
-{
-/*!
- * \ingroup TwoPNCModel
- * \ingroup ImplicitIndices
- * \brief Enumerates the formulations which the two-phase n-component model accepts.
- *
- */
-struct TwoPNCFormulation//TODO: This might need to be change similar to 2p2c indices
-{
-    enum {
-            plSg,
-            pgSl,
-            pnSw = pgSl,
-            pwSn = plSg
-          };
-};
+#warning this header is deprecated, use dumux/porousmediumflow/2pnc/implicit/indices.hh instead
 
-/*!
- * \ingroup TwoPNCModel
- * \ingroup ImplicitIndices
- * \brief The indices for the isothermal two-phase n-component model.
- *
- * \tparam PVOffset The first index in a primary variable vector.
- */
-template <class TypeTag, int PVOffset = 0>
-class TwoPNCIndices
-{
-    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
-
-public:
-    // Phase indices
-    static const int wPhaseIdx = FluidSystem::wPhaseIdx; //!< Index of the wetting phase
-    static const int nPhaseIdx = FluidSystem::nPhaseIdx; //!< Index of the non-wetting phase
-    // present phases (-> 'pseudo' primary variable)
-    static const int wPhaseOnly = 1; //!< Only the non-wetting phase is present
-    static const int nPhaseOnly = 2; //!< Only the wetting phase is present
-    static const int bothPhases = 3; //!< Both phases are present
-
-    // Primary variable indices
-    static const int pressureIdx = PVOffset + 0; //!< Index for wetting/non-wetting phase pressure (depending on formulation) in a solution vector
-    static const int switchIdx = PVOffset + 1; //!< Index of the either the saturation or the mass fraction of the non-wetting/wetting phase
-    // equation indices
-    static const int conti0EqIdx = PVOffset + 0; //!< Reference index for mass conservation equations.
-    static const int contiWEqIdx = conti0EqIdx + FluidSystem::wCompIdx; //!< Index of the mass conservation equation for the wetting phase major component
-    static const int contiNEqIdx = conti0EqIdx + FluidSystem::nCompIdx; //!< Index of the mass conservation equation for the non-wetting phase major component
-};
-
-// \}
-
-}
+#include <dumux/porousmediumflow/2pnc/implicit/indices.hh>
 
 #endif
diff --git a/dumux/implicit/2pnc/2pnclocalresidual.hh b/dumux/implicit/2pnc/2pnclocalresidual.hh
index 6cbb065a1f..719ae05878 100644
--- a/dumux/implicit/2pnc/2pnclocalresidual.hh
+++ b/dumux/implicit/2pnc/2pnclocalresidual.hh
@@ -1,349 +1,8 @@
-// -*- 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/>.   *
- *****************************************************************************/
-/*!
- * \file
- *
- * \brief Element-wise calculation of the Jacobian matrix for problems
- *        using the two-phase n-component box model.
- */
+#ifndef DUMUX_2PNC_LOCAL_RESIDUAL_BASE_HH_OLD
+#define DUMUX_2PNC_LOCAL_RESIDUAL_BASE_HH_OLD
 
-#ifndef DUMUX_2PNC_LOCAL_RESIDUAL_BASE_HH
-#define DUMUX_2PNC_LOCAL_RESIDUAL_BASE_HH
+#warning this header is deprecated, use dumux/porousmediumflow/2pnc/implicit/localresidual.hh instead
 
-#include "2pncproperties.hh"
-#include "2pncvolumevariables.hh"
-#include <dumux/nonlinear/newtoncontroller.hh>
-
-#include <iostream>
-#include <vector>
-
-namespace Dumux
-{
-/*!
- * \ingroup TwoPNCModel
- * \ingroup ImplicitLocalResidual
- * \brief Element-wise calculation of the Jacobian matrix for problems
- *        using the two-phase n-component fully implicit box model.
- *
- * This class is used to fill the gaps in ImplicitLocalResidual for the two-phase n-component flow.
- */
-template<class TypeTag>
-class TwoPNCLocalResidual: public GET_PROP_TYPE(TypeTag, BaseLocalResidual)
-{
-protected:
-    typedef TwoPNCLocalResidual<TypeTag> ThisType;
-    typedef typename GET_PROP_TYPE(TypeTag, LocalResidual) Implementation;
-    typedef BoxLocalResidual<TypeTag> ParentType;
-
-    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
-    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
-
-    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
-    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
-
-    typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector;
-    typedef typename GET_PROP_TYPE(TypeTag, ElementSolutionVector) ElementSolutionVector;
-    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes;
-
-    typedef CompositionalFluidState<Scalar, FluidSystem> FluidState;
-    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
-
-    enum
-    {
-        dim = GridView::dimension,
-        dimWorld = GridView::dimensionworld,
-
-        numEq = GET_PROP_VALUE(TypeTag, NumEq),
-        numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
-        numComponents = GET_PROP_VALUE(TypeTag, NumComponents),
-
-        replaceCompEqIdx = GET_PROP_VALUE(TypeTag, ReplaceCompEqIdx),
-
-        pressureIdx = Indices::pressureIdx,
-        switchIdx = Indices::switchIdx,
-
-        wPhaseIdx = FluidSystem::wPhaseIdx,
-        nPhaseIdx = FluidSystem::nPhaseIdx,
-
-        wCompIdx = FluidSystem::wCompIdx,
-        nCompIdx = FluidSystem::nCompIdx,
-
-        conti0EqIdx = Indices::conti0EqIdx,
-
-        wPhaseOnly = Indices::wPhaseOnly,
-        nPhaseOnly = Indices::nPhaseOnly,
-        bothPhases = Indices::bothPhases,
-
-        plSg = TwoPNCFormulation::plSg,
-        pgSl = TwoPNCFormulation::pgSl,
-        formulation = GET_PROP_VALUE(TypeTag, Formulation)
-    };
-
-    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, ElementBoundaryTypes) ElementBoundaryTypes;
-    typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, SpatialParams) SpatialParams;
-    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
-
-
-    typedef typename GridView::template Codim<0>::Entity Element;
-    typedef typename GridView::ctype CoordScalar;
-
-
-public:
-    /*!
-     * \brief Constructor. Sets the upwind weight.
-     */
-    TwoPNCLocalResidual()
-    {
-        // retrieve the upwind weight for the mass conservation equations. Use the value
-        // specified via the property system as default, and overwrite
-        // it by the run-time parameter from the Dune::ParameterTree
-        massUpwindWeight_ = GET_PARAM_FROM_GROUP(TypeTag, Scalar, Implicit, MassUpwindWeight);
-    };
-
-    /*!
-     * \brief Evaluate the storage term of the current solution in a
-     *        single phase.
-     *
-     * \param element The element
-     * \param phaseIdx The index of the fluid phase
-     */
-    void evalPhaseStorage(const Element &element, int phaseIdx)
-    {
-        FVElementGeometry fvGeometry;
-        fvGeometry.update(this->gridView_(), element);
-        ElementBoundaryTypes bcTypes;
-        bcTypes.update(this->problem_(), element, fvGeometry);
-        ElementVolumeVariables volVars;
-        volVars.update(this->problem_(), element, fvGeometry, false);
-
-        this->residual_.resize(fvGeometry.numScv);
-        this->residual_ = 0;
-
-        this->elemPtr_ = &element;
-        this->fvElemGeomPtr_ = &fvGeometry;
-        this->bcTypesPtr_ = &bcTypes;
-        this->prevVolVarsPtr_ = 0;
-        this->curVolVarsPtr_ = &volVars;
-        evalPhaseStorage_(phaseIdx);
-    }
-
-    /*!
-     * \brief Evaluate the amount all conservation quantities
-     *        (e.g. phase mass) within a sub-control volume.
-     *
-     * The result should be averaged over the volume (e.g. phase mass
-     * inside a sub control volume divided by the volume)
-     *
-     *  \param storage the mass of the component within the sub-control volume
-     *  \param scvIdx The SCV (sub-control-volume) index
-     *  \param usePrevSol Evaluate function with solution of current or previous time step
-     */
-    void computeStorage(PrimaryVariables &storage, int scvIdx, bool usePrevSol) const
-    {
-        // 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 &elemVolVars = usePrevSol ? this->prevVolVars_()
-                : this->curVolVars_();
-        const VolumeVariables &volVars = elemVolVars[scvIdx];
-
-        // Compute storage term of all fluid components in the fluid phases
-        storage = 0;
-        for (unsigned int phaseIdx = 0; phaseIdx < numPhases /*+ numSPhases*/; ++phaseIdx)
-        {
-            //if(phaseIdx< numPhases)
-            //{
-                for (unsigned int compIdx = 0; compIdx < numComponents; ++compIdx) //H2O, Air, Salt
-                {
-                    int eqIdx = conti0EqIdx + compIdx;
-                    if (replaceCompEqIdx != eqIdx)
-                    {
-                        storage[eqIdx] += volVars.molarDensity(phaseIdx)
-                                        * volVars.saturation(phaseIdx)
-                                        * volVars.moleFraction(phaseIdx, compIdx)
-                                        * volVars.porosity();
-                    }
-                    else
-                    {
-                        storage[replaceCompEqIdx] += volVars.molarDensity(phaseIdx)
-                                                * volVars.saturation(phaseIdx)
-                                                * volVars.porosity();
-                    }
-                }
-        }
-         Valgrind::CheckDefined(storage);
-    }
-    /*!
-     * \brief Evaluates the total flux of all conservation quantities
-     *        over a face of a sub-control volume.
-     *
-     * \param flux The flux over the sub-control-volume face for each component
-     * \param fIdx The index of the sub-control-volume face
-     * \param onBoundary Evaluate flux at inner sub-control-volume face or on a boundary face
-     */
-    void computeFlux(PrimaryVariables &flux, const int fIdx, bool onBoundary = false) const
-    {
-        FluxVariables fluxVars(this->problem_(),
-                      this->element_(),
-                      this->fvGeometry_(),
-                      fIdx,
-                      this->curVolVars_(),
-                      onBoundary);
-
-        flux = 0;
-        asImp_()->computeAdvectiveFlux(flux, fluxVars);
-        asImp_()->computeDiffusiveFlux(flux, fluxVars);
-        Valgrind::CheckDefined(flux);
-    }
-    /*!
-     * \brief Evaluates the advective mass flux of all components over
-     *        a face of a subcontrol volume.
-     *
-     * \param flux The advective flux over the sub-control-volume face for each component
-     * \param fluxVars The flux variables at the current SCV
-     */
-    void computeAdvectiveFlux(PrimaryVariables &flux, const FluxVariables &fluxVars) const
-    {
-        ////////
-        // advective fluxes of all components in all phases
-        ////////
-        for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
-        {
-         // data attached to upstream and the downstream vertices
-         // of the current phase
-         const VolumeVariables &up = this->curVolVars_(fluxVars.upstreamIdx(phaseIdx));
-         const VolumeVariables &dn = this->curVolVars_(fluxVars.downstreamIdx(phaseIdx));
-
-         for (unsigned int compIdx = 0; compIdx < numComponents; ++compIdx)
-         {
-         // add advective flux of current component in current
-         // phase
-            unsigned int eqIdx = conti0EqIdx + compIdx;
-
-         if (eqIdx != replaceCompEqIdx)
-         {
-            // upstream vertex
-            flux[eqIdx] += fluxVars.KmvpNormal(phaseIdx)
-                        * (massUpwindWeight_
-                            * up.mobility(phaseIdx)
-                            * up.molarDensity(phaseIdx)
-                            * up.moleFraction(phaseIdx, compIdx)
-                        +
-                            (1.0 - massUpwindWeight_)
-                            * dn.mobility(phaseIdx)
-                            * dn.molarDensity(phaseIdx)
-                            * dn.moleFraction(phaseIdx, compIdx));
-
-            Valgrind::CheckDefined(fluxVars.KmvpNormal(phaseIdx));
-            Valgrind::CheckDefined(up.molarDensity(phaseIdx));
-            Valgrind::CheckDefined(dn.molarDensity(phaseIdx));
-         }
-         else
-         {
-         flux[replaceCompEqIdx] += fluxVars.KmvpNormal(phaseIdx)
-                                * (massUpwindWeight_
-                                    * up.molarDensity(phaseIdx)
-                                    * up.mobility(phaseIdx)
-                                    +
-                                    (1.0 - massUpwindWeight_)
-                                    * dn.molarDensity(phaseIdx)
-                                    * dn.mobility(phaseIdx));
-
-
-         Valgrind::CheckDefined(fluxVars.KmvpNormal(phaseIdx));
-         Valgrind::CheckDefined(up.molarDensity(phaseIdx));
-         Valgrind::CheckDefined(dn.molarDensity(phaseIdx));
-         }
-         }
-       }
-     }
-
-    /*!
-     * \brief Evaluates the diffusive mass flux of all components over
-     *        a face of a sub-control volume.
-     *
-     * \param flux The flux over the sub-control-volume face for each component
-     * \param fluxVars The flux variables at the current sub-control-volume face
-     */
-    void computeDiffusiveFlux(PrimaryVariables &flux, const FluxVariables &fluxVars) const
-    {
-        //Loop calculates the diffusive flux for every component in a phase. The amount of moles of a component
-        //(eg Air in liquid) in a phase
-        //which is not the main component (eg. H2O in the liquid phase) moved from i to j equals the amount of moles moved
-        //from the main component in a phase (eg. H2O in the liquid phase) from j to i. So two fluxes in each component loop
-        // are calculated in the same phase.
-
-        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
-            for (int compIdx = 0; compIdx < numComponents; ++compIdx)
-            {
-                //add diffusive fluxes only to the component balances
-                if (replaceCompEqIdx != (conti0EqIdx + compIdx))
-                {
-                    Scalar diffCont = - fluxVars.porousDiffCoeff(phaseIdx ,compIdx)
-                                        * fluxVars.molarDensity(phaseIdx)
-                                        * (fluxVars.moleFractionGrad(phaseIdx, compIdx)
-                                            * fluxVars.face().normal);
-                    flux[conti0EqIdx + compIdx] += diffCont;
-                    flux[conti0EqIdx + phaseIdx] -= diffCont;
-                }
-            }
-    }
-
-protected:
-
-    void evalPhaseStorage_(int phaseIdx)
-    {
-        // evaluate the storage terms of a single phase
-        for (int i=0; i < this->fvGeometry_().numScv; i++)
-        {
-            PrimaryVariables &result = this->residual_[i];
-            const ElementVolumeVariables &elemVolVars = this->curVolVars_();
-            const VolumeVariables &volVars = elemVolVars[i];
-
-            // compute storage term of all fluid components within all phases
-            result = 0;
-            for (int compIdx = 0; compIdx < numComponents; ++compIdx)
-            {
-                result[conti0EqIdx + compIdx] += volVars.density(phaseIdx)
-                                * volVars.saturation(phaseIdx)
-                                * volVars.massFraction(phaseIdx, compIdx)
-                                * volVars.porosity();
-            }
-            result *= this->fvGeometry_().subContVol[i].volume;
-        }
-    }
-
-    Implementation *asImp_()
-    { return static_cast<Implementation *> (this); }
-    const Implementation *asImp_() const
-    { return static_cast<const Implementation *> (this); }
-
-public:
-   Scalar massUpwindWeight_;
-};
-
-} // end namespace
+#include <dumux/porousmediumflow/2pnc/implicit/localresidual.hh>
 
 #endif
diff --git a/dumux/implicit/2pnc/2pncmodel.hh b/dumux/implicit/2pnc/2pncmodel.hh
index 11201d35d5..a42f648246 100644
--- a/dumux/implicit/2pnc/2pncmodel.hh
+++ b/dumux/implicit/2pnc/2pncmodel.hh
@@ -1,741 +1,8 @@
-// -*- 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/>.   *
- *****************************************************************************/
-/*!
-* \file
-*
-* \brief Adaption of the fully implicit box scheme to the two-phase n-component flow model.
-*/
+#ifndef DUMUX_2PNC_MODEL_HH_OLD
+#define DUMUX_2PNC_MODEL_HH_OLD
 
-#ifndef DUMUX_2PNC_MODEL_HH
-#define DUMUX_2PNC_MODEL_HH
+#warning this header is deprecated, use dumux/porousmediumflow/2pnc/implicit/model.hh instead
 
-#include <dumux/porousmediumflow/implicit/velocityoutput.hh>
-
-#include "2pncproperties.hh"
-#include "2pncindices.hh"
-#include "2pnclocalresidual.hh"
-
-namespace Dumux
-{
-/*!
- * \ingroup TwoPNCModel
- * \brief Adaption of the fully implicit scheme to the
- *        two-phase n-component fully implicit model.
- *
- * This model implements two-phase n-component flow of two compressible and
- * partially miscible fluids \f$\alpha \in \{ w, n \}\f$ composed of the n components
- * \f$\kappa \in \{ w, a,\cdots \}\f$. The standard multiphase Darcy
- * approach is used as the equation for the conservation of momentum:
- * \f[
- v_\alpha = - \frac{k_{r\alpha}}{\mu_\alpha} \mbox{\bf K}
- \left(\text{grad}\, p_\alpha - \varrho_{\alpha} \mbox{\bf g} \right)
- * \f]
- *
- * By inserting this into the equations for the conservation of the
- * components, one gets one transport equation for each component
- * \f{eqnarray}
- && \phi \frac{\partial (\sum_\alpha \varrho_\alpha X_\alpha^\kappa S_\alpha )}
- {\partial t}
- - \sum_\alpha  \text{div} \left\{ \varrho_\alpha X_\alpha^\kappa
- \frac{k_{r\alpha}}{\mu_\alpha} \mbox{\bf K}
- (\text{grad}\, p_\alpha - \varrho_{\alpha}  \mbox{\bf g}) \right\}
- \nonumber \\ \nonumber \\
-    &-& \sum_\alpha \text{div} \left\{{\bf D_{\alpha, pm}^\kappa} \varrho_{\alpha} \text{grad}\, X^\kappa_{\alpha} \right\}
- - \sum_\alpha q_\alpha^\kappa = 0 \qquad \kappa \in \{w, a,\cdots \} \, ,
- \alpha \in \{w, g\}
- \f}
- *
- * All equations are discretized using a vertex-centered finite volume (box)
- * or cell-centered finite volume scheme (this is not done for 2pnc approach yet, however possible) as
- * spatial and the implicit Euler method as time discretization.
- *
- * By using constitutive relations for the capillary pressure \f$p_c =
- * p_n - p_w\f$ and relative permeability \f$k_{r\alpha}\f$ and taking
- * advantage of the fact that \f$S_w + S_n = 1\f$ and \f$X^\kappa_w + X^\kappa_n = 1\f$, the number of
- * unknowns can be reduced to number of components.
- *
- * The used primary variables are, like in the two-phase model, either \f$p_w\f$ and \f$S_n\f$
- * or \f$p_n\f$ and \f$S_w\f$. The formulation which ought to be used can be
- * specified by setting the <tt>Formulation</tt> property to either
- * TwoPTwoCIndices::pWsN or TwoPTwoCIndices::pNsW. By
- * default, the model uses \f$p_w\f$ and \f$S_n\f$.
- *
- * Moreover, the second primary variable depends on the phase state, since a
- * primary variable switch is included. The phase state is stored for all nodes
- * of the system. The model is uses mole fractions.
- *Following cases can be distinguished:
- * <ul>
- *  <li> Both phases are present: The saturation is used (either \f$S_n\f$ or \f$S_w\f$, dependent on the chosen <tt>Formulation</tt>),
- *      as long as \f$ 0 < S_\alpha < 1\f$</li>.
- *  <li> Only wetting phase is present: The mass fraction of, e.g., air in the wetting phase \f$X^a_w\f$ is used,
- *      as long as the maximum mass fraction is not exceeded (\f$X^a_w<X^a_{w,max}\f$)</li>
- *  <li> Only non-wetting phase is present: The mass fraction of, e.g., water in the non-wetting phase, \f$X^w_n\f$, is used,
- *      as long as the maximum mass fraction is not exceeded (\f$X^w_n<X^w_{n,max}\f$)</li>
- * </ul>
- */
-
-template<class TypeTag>
-class TwoPNCModel: public GET_PROP_TYPE(TypeTag, BaseModel)
-{
-    typedef typename GET_PROP_TYPE(TypeTag, BaseModel) ParentType;
-
-    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
-    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
-    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
-    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
-
-    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
-    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector;
-    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
-
-    enum { dim = GridView::dimension };
-    enum { dimWorld = GridView::dimensionworld };
-
-    enum { numEq = GET_PROP_VALUE(TypeTag, NumEq) };
-    enum { numPhases = GET_PROP_VALUE(TypeTag, NumPhases) };
-    enum {  numComponents = GET_PROP_VALUE(TypeTag, NumComponents) };
-    enum {  numMajorComponents = GET_PROP_VALUE(TypeTag, NumMajorComponents) };
-
-    enum {
-            pressureIdx = Indices::pressureIdx,
-            switchIdx = Indices::switchIdx
-    };
-    enum {
-            wPhaseIdx = Indices::wPhaseIdx,
-            nPhaseIdx = Indices::nPhaseIdx
-    };
-    enum {
-            wCompIdx = FluidSystem::wCompIdx,
-            nCompIdx = FluidSystem::nCompIdx
-    };
-    enum {
-            wPhaseOnly = Indices::wPhaseOnly,
-            nPhaseOnly = Indices::nPhaseOnly,
-            bothPhases = Indices::bothPhases
-    };
-    enum {
-            plSg = TwoPNCFormulation::plSg,
-            pgSl = TwoPNCFormulation::pgSl,
-            formulation = GET_PROP_VALUE(TypeTag, Formulation)
-    };
-
-    typedef CompositionalFluidState<Scalar, FluidSystem> FluidState;
-
-    typedef typename GridView::template Codim<dim>::Entity Vertex;
-    typedef typename GridView::template Codim<0>::Entity Element;
-
-    typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition;
-    typedef typename GridView::ctype CoordScalar;
-    typedef Dune::FieldMatrix<CoordScalar, dimWorld, dimWorld> Tensor;
-
-    enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) };
-    enum { dofCodim = isBox ? dim : 0 };
-
-public:
-    /*!
-     * \brief Initialize the static data with the initial solution.
-     *
-     * \param problem The problem to be solved
-     */
-    void init(Problem &problem)
-    {
-        ParentType::init(problem);
-
-        unsigned numDofs = this->numDofs();
-
-        staticDat_.resize(numDofs);
-
-        setSwitched_(false);
-
-        for (const auto& element : Dune::elements(this->gridView_()))
-        {
-            if (!isBox) // i.e. cell-centered discretization
-            {
-                int dofIdxGlobal = this->dofMapper().index(element);
-                const GlobalPosition &globalPos = element.geometry().center();
-
-                // initialize phase presence
-                staticDat_[dofIdxGlobal].phasePresence
-                    = this->problem_().initialPhasePresence(*(this->gridView_().template begin<dim>()),
-                                                            dofIdxGlobal, globalPos);
-                staticDat_[dofIdxGlobal].wasSwitched = false;
-
-                staticDat_[dofIdxGlobal].oldPhasePresence
-                    = staticDat_[dofIdxGlobal].phasePresence;
-            }
-        }
-
-        if (isBox) // i.e. vertex-centered discretization
-        {
-            for (const auto& vertex : Dune::vertices(this->gridView_()))
-            {
-                int dofIdxGlobal = this->dofMapper().index(vertex);
-                const GlobalPosition &globalPos = vertex.geometry().corner(0);
-
-                // initialize phase presence
-                staticDat_[dofIdxGlobal].phasePresence
-                    = this->problem_().initialPhasePresence(vertex, dofIdxGlobal,
-                                                            globalPos);
-                staticDat_[dofIdxGlobal].wasSwitched = false;
-
-                staticDat_[dofIdxGlobal].oldPhasePresence
-                    = staticDat_[dofIdxGlobal].phasePresence;
-            }
-        }
-    }
-
-    /*!
-     * \brief Compute the total storage of all conservation quantities in one phase
-     *
-     * \param storage Contains the storage of each component in one phase
-     * \param phaseIdx The phase index
-     */
-    void globalPhaseStorage(PrimaryVariables &storage, int phaseIdx)
-    {
-        storage = 0;
-
-        for (const auto& element : Dune::elements(this->gridView_()))
-        {
-            if(element.partitionType() == Dune::InteriorEntity)
-            {
-                this->localResidual().evalPhaseStorage(element, phaseIdx);
-
-                for (unsigned int i = 0; i < this->localResidual().storageTerm().size(); ++i)
-                    storage += this->localResidual().storageTerm()[i];
-            }
-        }
-
-        this->gridView_().comm().sum(storage);
-    }
-
-    /*!
-     * \brief Called by the update() method if applying the newton
-     *         method was unsuccessful.
-     */
-    void updateFailed()
-    {
-        ParentType::updateFailed();
-
-        setSwitched_(false);
-        resetPhasePresence_();
-    }
-
-    /*!
-     * \brief Called by the problem if a time integration was
-     *        successful, post processing of the solution is done and the
-     *        result has been written to disk.
-     *
-     * This should prepare the model for the next time integration.
-     */
-    void advanceTimeLevel()
-    {
-        ParentType::advanceTimeLevel();
-
-        // update the phase state
-        updateOldPhasePresence_();
-        setSwitched_(false);
-    }
-
-    /*!
-     * \brief Return true if the primary variables were switched for
-     *        at least one vertex after the last timestep.
-     */
-    bool switched() const
-    {
-        return switchFlag_;
-    }
-
-    /*!
-     * \brief Returns the phase presence of the current or the old solution of a vertex.
-     *
-     * \param globalVertexIdx The global vertex index
-     * \param oldSol Evaluate function with solution of current or previous time step
-     */
-    int phasePresence(int globalVertexIdx, bool oldSol) const
-    {
-        return oldSol ? staticDat_[globalVertexIdx].oldPhasePresence
-                : staticDat_[globalVertexIdx].phasePresence;
-    }
-
-    /*!
-     * \brief Append all quantities of interest which can be derived
-     *        from the solution of the current time step to the VTK
-     *        writer.
-     *
-     * \param sol The solution vector
-     * \param writer The writer for multi-file VTK datasets
-     */
-    template<class MultiWriter>
-    void addOutputVtkFields(const SolutionVector &sol,
-                            MultiWriter &writer)
-    {
-
-        typedef Dune::BlockVector<Dune::FieldVector<Scalar, 1> > ScalarField;
-        typedef Dune::BlockVector<Dune::FieldVector<Scalar, dim> > VectorField;
-
-        // get the number of degrees of freedom
-        unsigned numDofs = this->numDofs();
-
-        ScalarField *Sg            = writer.allocateManagedBuffer (numDofs);
-        ScalarField *Sl            = writer.allocateManagedBuffer (numDofs);
-        ScalarField *pg            = writer.allocateManagedBuffer (numDofs);
-        ScalarField *pl            = writer.allocateManagedBuffer (numDofs);
-        ScalarField *pc            = writer.allocateManagedBuffer (numDofs);
-        ScalarField *rhoL          = writer.allocateManagedBuffer (numDofs);
-        ScalarField *rhoG          = writer.allocateManagedBuffer (numDofs);
-        ScalarField *mobL          = writer.allocateManagedBuffer (numDofs);
-        ScalarField *mobG          = writer.allocateManagedBuffer (numDofs);
-        ScalarField *temperature   = writer.allocateManagedBuffer (numDofs);
-        ScalarField *poro          = writer.allocateManagedBuffer (numDofs);
-        ScalarField *boxVolume     = writer.allocateManagedBuffer (numDofs);
-        VectorField *velocityN = writer.template allocateManagedBuffer<double, dim>(numDofs);
-        VectorField *velocityW = writer.template allocateManagedBuffer<double, dim>(numDofs);
-        ImplicitVelocityOutput<TypeTag> velocityOutput(this->problem_());
-
-        if (velocityOutput.enableOutput()) // check if velocity output is demanded
-        {
-            // initialize velocity fields
-            for (unsigned int i = 0; i < numDofs; ++i)
-            {
-                (*velocityN)[i] = Scalar(0);
-                (*velocityW)[i] = Scalar(0);
-            }
-        }
-
-        ScalarField *moleFraction[numPhases][numComponents];
-        for (int i = 0; i < numPhases; ++i)
-            for (int j = 0; j < numComponents; ++j)
-                moleFraction[i][j] = writer.allocateManagedBuffer(numDofs);
-
-        ScalarField *molarity[numComponents];
-        for (int j = 0; j < numComponents ; ++j)
-            molarity[j] = writer.allocateManagedBuffer(numDofs);
-
-        ScalarField *Perm[dim];
-        for (int j = 0; j < dim; ++j) //Permeability only in main directions xx and yy
-            Perm[j] = writer.allocateManagedBuffer(numDofs);
-
-        *boxVolume = 0;
-
-        unsigned numElements = this->gridView_().size(0);
-        ScalarField *rank = writer.allocateManagedBuffer (numElements);
-
-        FVElementGeometry fvGeometry;
-        VolumeVariables volVars;
-        ElementVolumeVariables elemVolVars;
-
-        for (const auto& element : Dune::elements(this->gridView_()))
-        {
-            int eIdxGlobal = this->problem_().elementMapper().index(element);
-            (*rank)[eIdxGlobal] = this->gridView_().comm().rank();
-            fvGeometry.update(this->gridView_(), element);
-
-            elemVolVars.update(this->problem_(),
-                               element,
-                               fvGeometry,
-                               false /* oldSol? */);
-
-            for (int scvIdx = 0; scvIdx < fvGeometry.numScv; ++scvIdx)
-            {
-                int dofIdxGlobal = this->dofMapper().subIndex(element, scvIdx, dofCodim);
-
-                volVars.update(sol[dofIdxGlobal],
-                               this->problem_(),
-                               element,
-                               fvGeometry,
-                               scvIdx,
-                               false);
-
-                GlobalPosition globalPos = fvGeometry.subContVol[scvIdx].global;
-                (*Sg)[dofIdxGlobal]             = elemVolVars[scvIdx].saturation(nPhaseIdx);
-                (*Sl)[dofIdxGlobal]             = elemVolVars[scvIdx].saturation(wPhaseIdx);
-                (*pg)[dofIdxGlobal]             = elemVolVars[scvIdx].pressure(nPhaseIdx);
-                (*pl)[dofIdxGlobal]             = elemVolVars[scvIdx].pressure(wPhaseIdx);
-                (*pc)[dofIdxGlobal]             = elemVolVars[scvIdx].capillaryPressure();
-                (*rhoL)[dofIdxGlobal]           = elemVolVars[scvIdx].density(wPhaseIdx);
-                (*rhoG)[dofIdxGlobal]           = elemVolVars[scvIdx].density(nPhaseIdx);
-                (*mobL)[dofIdxGlobal]           = elemVolVars[scvIdx].mobility(wPhaseIdx);
-                (*mobG)[dofIdxGlobal]           = elemVolVars[scvIdx].mobility(nPhaseIdx);
-                (*boxVolume)[dofIdxGlobal]     += fvGeometry.subContVol[scvIdx].volume;
-                (*poro)[dofIdxGlobal]           = elemVolVars[scvIdx].porosity();
-                (*temperature)[dofIdxGlobal]    = elemVolVars[scvIdx].temperature();
-
-                for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
-                {
-                    for (int compIdx = 0; compIdx < numComponents; ++compIdx)
-                    {
-                        (*moleFraction[phaseIdx][compIdx])[dofIdxGlobal]= volVars.moleFraction(phaseIdx,compIdx);
-                        Valgrind::CheckDefined((*moleFraction[phaseIdx][compIdx])[dofIdxGlobal]);
-                    }
-                }
-                for (int compIdx = 0; compIdx < numComponents; ++compIdx)
-                    (*molarity[compIdx])[dofIdxGlobal] = (volVars.molarity(wPhaseIdx, compIdx));
-
-                Tensor K = perm_(this->problem_().spatialParams().intrinsicPermeability(element, fvGeometry, scvIdx));
-
-                for (int j = 0; j<dim; ++j)
-                    (*Perm[j])[dofIdxGlobal] = K[j][j] /* volVars.permFactor()*/;
-            };
-
-            // velocity output
-            if(velocityOutput.enableOutput()){
-                velocityOutput.calculateVelocity(*velocityW, elemVolVars, fvGeometry, element, wPhaseIdx);
-                velocityOutput.calculateVelocity(*velocityN, elemVolVars, fvGeometry, element, nPhaseIdx);
-            }
-
-        } // loop over element
-
-        writer.attachDofData(*Sg, "Sg", isBox);
-        writer.attachDofData(*Sl, "Sl", isBox);
-        writer.attachDofData(*pg, "pg", isBox);
-        writer.attachDofData(*pl, "pl", isBox);
-        writer.attachDofData(*pc, "pc", isBox);
-        writer.attachDofData(*rhoL, "rhoL", isBox);
-        writer.attachDofData(*rhoG, "rhoG", isBox);
-        writer.attachDofData(*mobL, "mobL", isBox);
-        writer.attachDofData(*mobG, "mobG", isBox);
-        writer.attachDofData(*poro, "porosity", isBox);
-        writer.attachDofData(*temperature, "temperature", isBox);
-        writer.attachDofData(*boxVolume, "boxVolume", isBox);
-        writer.attachDofData(*Perm[0], "Kxx", isBox);
-        if (dim >= 2)
-            writer.attachDofData(*Perm[1], "Kyy", isBox);
-        if (dim == 3)
-            writer.attachDofData(*Perm[2], "Kzz", isBox);
-
-        for (int i = 0; i < numPhases; ++i)
-        {
-            for (int j = 0; j < numComponents; ++j)
-            {
-                std::ostringstream oss;
-                oss << "x"
-                    << FluidSystem::componentName(j)
-                    << FluidSystem::phaseName(i);
-                writer.attachDofData(*moleFraction[i][j], oss.str().c_str(), isBox);
-            }
-        }
-
-        for (int j = 0; j < numComponents; ++j)
-        {
-            std::ostringstream oss;
-            oss << "m^w_"
-                << FluidSystem::componentName(j);
-            writer.attachDofData(*molarity[j], oss.str().c_str(), isBox);
-        }
-
-        if (velocityOutput.enableOutput()) // check if velocity output is demanded
-        {
-            writer.attachDofData(*velocityW,  "velocityW", isBox, dim);
-            writer.attachDofData(*velocityN,  "velocityN", isBox, dim);
-        }
-
-        writer.attachCellData(*rank, "process rank");
-    }
-
-    /*!
-     * \brief Write the current solution to a restart file.
-     *
-     * \param outStream The output stream of one vertex for the restart file
-     * \param entity The Entity
-     */
-    template<class Entity>
-    void serializeEntity(std::ostream &outStream, const Entity &entity)
-    {
-        // write primary variables
-        ParentType::serializeEntity(outStream, entity);
-        int dofIdxGlobal = this->dofMapper().index(entity);
-
-        if (!outStream.good())
-            DUNE_THROW(Dune::IOError, "Could not serialize vertex " << dofIdxGlobal);
-
-        outStream << staticDat_[dofIdxGlobal].phasePresence << " ";
-    }
-
-    /*!
-     * \brief Reads the current solution for a vertex from a restart
-     *        file.
-     *
-     * \param inStream The input stream of one vertex from the restart file
-     * \param entity The Entity
-     */
-    template<class Entity>
-    void deserializeEntity(std::istream &inStream, const Entity &entity)
-    {
-        // read primary variables
-        ParentType::deserializeEntity(inStream, entity);
-        int dofIdxGlobal = this->dofMapper().index(entity);
-
-        if (!inStream.good())
-            DUNE_THROW(Dune::IOError,
-                       "Could not deserialize vertex " << dofIdxGlobal);
-
-        inStream >> staticDat_[dofIdxGlobal].phasePresence;
-        staticDat_[dofIdxGlobal].oldPhasePresence
-                = staticDat_[dofIdxGlobal].phasePresence;
-
-    }
-
-    /*!
-     * \brief Update the static data of all vertices in the grid.
-     *
-     * \param curGlobalSol The current global solution
-     * \param oldGlobalSol The previous global solution
-     */
-    void updateStaticData(SolutionVector &curGlobalSol,
-                          const SolutionVector &oldGlobalSol)
-    {
-        bool wasSwitched = false;
-
-        for (unsigned i = 0; i < staticDat_.size(); ++i)
-            staticDat_[i].visited = false;
-
-        FVElementGeometry fvGeometry;
-        static VolumeVariables volVars;
-        for (const auto& element : Dune::elements(this->gridView_()))
-        {
-            fvGeometry.update(this->gridView_(), element);
-            for (int scvIdx = 0; scvIdx < fvGeometry.numScv; ++scvIdx)
-            {
-                int dofIdxGlobal = this->dofMapper().subIndex(element, scvIdx, dim);
-
-                if (staticDat_[dofIdxGlobal].visited)
-                    continue;
-
-                staticDat_[dofIdxGlobal].visited = true;
-                volVars.update(curGlobalSol[dofIdxGlobal],
-                               this->problem_(),
-                               element,
-                               fvGeometry,
-                               scvIdx,
-                               false);
-                const GlobalPosition &global = element.geometry().corner(scvIdx);
-                if (primaryVarSwitch_(curGlobalSol, volVars, dofIdxGlobal, global))
-                    wasSwitched = true;
-            }
-        }
-
-        // make sure that if there was a variable switch in an
-        // other partition we will also set the switch flag
-        // for our partition.
-        wasSwitched = this->gridView_().comm().max(wasSwitched);
-
-        setSwitched_(wasSwitched);
-    }
-
-protected:
-    /*!
-     * \brief Data which is attached to each vertex and is not only
-     *        stored locally.
-     */
-    struct StaticVars
-    {
-        int phasePresence;
-        bool wasSwitched;
-
-        int oldPhasePresence;
-        bool visited;
-    };
-
-    Tensor perm_(Scalar perm)
-    {
-        Tensor K(0.0);
-
-        for(int i=0; i<dim; i++)
-            K[i][i] = perm;
-
-       return K;
-    }
-
-    Tensor perm_(Tensor perm)
-    {
-       return perm;
-    }
-
-    /*!
-     * \brief Reset the current phase presence of all vertices to the old one.
-     *
-     * This is done after an update failed.
-     */
-    void resetPhasePresence_()
-    {
-        int numDofs = this->gridView_().size(dim);
-        for (int i = 0; i < numDofs; ++i)
-        {
-            staticDat_[i].phasePresence
-                    = staticDat_[i].oldPhasePresence;
-            staticDat_[i].wasSwitched = false;
-        }
-    }
-
-    /*!
-     * \brief Set the old phase of all verts state to the current one.
-     */
-    void updateOldPhasePresence_()
-    {
-        int numDofs = this->gridView_().size(dim);
-        for (int i = 0; i < numDofs; ++i)
-        {
-            staticDat_[i].oldPhasePresence
-                    = staticDat_[i].phasePresence;
-            staticDat_[i].wasSwitched = false;
-        }
-    }
-
-    /*!
-     * \brief Set whether there was a primary variable switch after in
-     *        the last timestep.
-     */
-    void setSwitched_(bool yesno)
-    {
-        switchFlag_ = yesno;
-    }
-
-    //  perform variable switch at a vertex; Returns true if a
-    //  variable switch was performed.
-    bool primaryVarSwitch_(SolutionVector &globalSol,
-                           const VolumeVariables &volVars, int dofIdxGlobal,
-                           const GlobalPosition &globalPos)
-    {
-
-            // evaluate primary variable switch
-            bool wouldSwitch = false;
-            int phasePresence = staticDat_[dofIdxGlobal].phasePresence;
-            int newPhasePresence = phasePresence;
-
-            //check if a primary variable switch is necessary
-            if (phasePresence == bothPhases)
-            {
-                Scalar Smin = 0; //saturation threshold
-                if (staticDat_[dofIdxGlobal].wasSwitched)
-                    Smin = -0.01;
-
-                //if saturation of liquid phase is smaller 0 switch
-                if (volVars.saturation(wPhaseIdx) <= Smin)
-                {
-                    wouldSwitch = true;
-                    //liquid phase has to disappear
-                    std::cout << "Liquid Phase disappears at vertex " << dofIdxGlobal
-                                << ", coordinated: " << globalPos << ", Sl: "
-                                << volVars.saturation(wPhaseIdx) << std::endl;
-                    newPhasePresence = nPhaseOnly;
-
-                    //switch not depending on formulation
-                    //switch "Sl" to "xgH20"
-                    globalSol[dofIdxGlobal][switchIdx]
-                            = volVars.moleFraction(nPhaseIdx, wCompIdx /*H2O*/);
-
-                    //switch all secondary components to mole fraction in gas phase
-                    for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx)
-                        globalSol[dofIdxGlobal][compIdx] = volVars.moleFraction(nPhaseIdx,compIdx);
-                }
-                //if saturation of gas phase is smaller than 0 switch
-                else if (volVars.saturation(nPhaseIdx) <= Smin)
-                {
-                    wouldSwitch = true;
-                    //gas phase has to disappear
-                    std::cout << "Gas Phase disappears at vertex " << dofIdxGlobal
-                                << ", coordinated: " << globalPos << ", Sg: "
-                                << volVars.saturation(nPhaseIdx) << std::endl;
-                    newPhasePresence = wPhaseOnly;
-
-                    //switch "Sl" to "xlN2"
-                    globalSol[dofIdxGlobal][switchIdx]
-                            = volVars.moleFraction(wPhaseIdx, nCompIdx /*N2*/);
-                }
-            }
-            else if (phasePresence == nPhaseOnly)
-            {
-                Scalar xlmax = 1;
-                Scalar sumxl = 0;
-                //Calculate sum of mole fractions in the hypothetical liquid phase
-                for (int compIdx = 0; compIdx < numComponents; compIdx++)
-                {
-                    sumxl += volVars.moleFraction(wPhaseIdx, compIdx);
-                }
-                if (sumxl > xlmax)
-                    wouldSwitch = true;
-                if (staticDat_[dofIdxGlobal].wasSwitched)
-                    xlmax *=1.02;
-                //liquid phase appears if sum is larger than one
-                if (sumxl/*sum of mole fractions*/ > xlmax/*1*/)
-                {
-                    std::cout << "Liquid Phase appears at vertex " << dofIdxGlobal
-                            << ", coordinated: " << globalPos << ", sumxl: "
-                            << sumxl << std::endl;
-                    newPhasePresence = bothPhases;
-
-                    //saturation of the liquid phase set to 0.0001 (if formulation pgSl and vice versa)
-                    if (formulation == pgSl)
-                        globalSol[dofIdxGlobal][switchIdx] = 0.0001;
-                    else if (formulation == plSg)
-                        globalSol[dofIdxGlobal][switchIdx] = 0.9999;
-
-                    //switch all secondary components back to liquid mole fraction
-                    for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx)
-                        globalSol[dofIdxGlobal][compIdx] = volVars.moleFraction(wPhaseIdx,compIdx);
-                }
-            }
-            else if (phasePresence == wPhaseOnly)
-            {
-                Scalar xgmax = 1;
-                Scalar sumxg = 0;
-                //Calculate sum of mole fractions in the hypothetical liquid phase
-                for (int compIdx = 0; compIdx < numComponents; compIdx++)
-                {
-                    sumxg += volVars.moleFraction(nPhaseIdx, compIdx);
-                }
-                if (sumxg > xgmax)
-                    wouldSwitch = true;
-                if (staticDat_[dofIdxGlobal].wasSwitched)
-                    xgmax *=1.02;
-                //liquid phase appears if sum is larger than one
-                if (sumxg > xgmax)
-                {
-                    std::cout << "Gas Phase appears at vertex " << dofIdxGlobal
-                            << ", coordinated: " << globalPos << ", sumxg: "
-                            << sumxg << std::endl;
-                    newPhasePresence = bothPhases;
-                    //saturation of the liquid phase set to 0.9999 (if formulation pgSl and vice versa)
-                    if (formulation == pgSl)
-                        globalSol[dofIdxGlobal][switchIdx] = 0.9999;
-                    else if (formulation == plSg)
-                        globalSol[dofIdxGlobal][switchIdx] = 0.0001;
-
-                }
-            }
-
-
-            staticDat_[dofIdxGlobal].phasePresence = newPhasePresence;
-            staticDat_[dofIdxGlobal].wasSwitched = wouldSwitch;
-            return phasePresence != newPhasePresence;
-        }
-
-    // parameters given in constructor
-    std::vector<StaticVars> staticDat_;
-    bool switchFlag_;
-};
-
-}
-
-#include "2pncpropertydefaults.hh"
+#include <dumux/porousmediumflow/2pnc/implicit/model.hh>
 
 #endif
diff --git a/dumux/implicit/2pnc/2pncnewtoncontroller.hh b/dumux/implicit/2pnc/2pncnewtoncontroller.hh
index 2f970c83b1..d50d55380e 100644
--- a/dumux/implicit/2pnc/2pncnewtoncontroller.hh
+++ b/dumux/implicit/2pnc/2pncnewtoncontroller.hh
@@ -1,105 +1,8 @@
-// -*- 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/>.   *
- *****************************************************************************/
-/*!
- * \file
- * \brief A two-phase n-component specific controller for the newton solver.
- */
-#ifndef DUMUX_2PNC_NEWTON_CONTROLLER_HH
-#define DUMUX_2PNC_NEWTON_CONTROLLER_HH
+#ifndef DUMUX_2PNC_NEWTON_CONTROLLER_HH_OLD
+#define DUMUX_2PNC_NEWTON_CONTROLLER_HH_OLD
 
-#include "2pncproperties.hh"
+#warning this header is deprecated, use dumux/porousmediumflow/2pnc/implicit/newtoncontroller.hh instead
 
-#include <dumux/nonlinear/newtoncontroller.hh>
-
-namespace Dumux {
-/*!
- * \ingroup Newton
- * \ingroup TwoPNCModel
- * \brief A two-phase n-component specific controller for the newton solver.
- *
- * This controller 'knows' what a 'physically meaningful' solution is
- * which allows the newton method to abort quicker if the solution is
- * way out of bounds.
- */
-template <class TypeTag>
-class TwoPNCNewtonController : public NewtonController<TypeTag>
-{
-    typedef NewtonController<TypeTag> ParentType;
-    typedef typename GET_PROP_TYPE(TypeTag, PTAG(Problem)) Problem;
-    typedef typename GET_PROP_TYPE(TypeTag, PTAG(SolutionVector)) SolutionVector;
-
-public:
-  TwoPNCNewtonController(Problem &problem)
-      : ParentType(problem)
-    {};
-
-
-    /*!
-     * \brief
-     * Suggest a new time step size based either on the number of newton
-     * iterations required or on the variable switch
-     *
-     * \param uCurrentIter The current global solution vector
-     * \param uLastIter The previous global solution vector
-     *
-     */
-    void newtonEndStep(SolutionVector &uCurrentIter,
-                       const SolutionVector &uLastIter)
-    {
-        int succeeded;
-        try {
-            // call the method of the base class
-            this->method().model().updateStaticData(uCurrentIter, uLastIter);
-            ParentType::newtonEndStep(uCurrentIter, uLastIter);
-
-            succeeded = 1;
-            if (this->gridView_().comm().size() > 1)
-                succeeded = this->gridView_().comm().min(succeeded);
-        }
-        catch (Dumux::NumericalProblem &e)
-        {
-            std::cout << "rank " << this->problem_().gridView().comm().rank()
-                      << " caught an exception while updating:" << e.what()
-                      << "\n";
-            succeeded = 0;
-            if (this->gridView_().comm().size() > 1)
-                succeeded = this->gridView_().comm().min(succeeded);
-        }
-
-        if (!succeeded) {
-            DUNE_THROW(NumericalProblem,
-                       "A process did not succeed in linearizing the system");
-        }
-    }
-
-    /*!
-     * \brief Returns true if the current solution can be considered to
-     *        be accurate enough
-     */
-    bool newtonConverged()
-    {
-        if (this->method().model().switched())
-            return false;
-
-        return ParentType::newtonConverged();
-    }
-};
-}
+#include <dumux/porousmediumflow/2pnc/implicit/newtoncontroller.hh>
 
 #endif
diff --git a/dumux/implicit/2pnc/2pncproperties.hh b/dumux/implicit/2pnc/2pncproperties.hh
index 44e495060a..1ecb36db30 100644
--- a/dumux/implicit/2pnc/2pncproperties.hh
+++ b/dumux/implicit/2pnc/2pncproperties.hh
@@ -1,82 +1,8 @@
-// -*- 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/>.   *
- *****************************************************************************/
-/*!
- * \ingroup Properties
- * \ingroup ImplicitProperties
- * \ingroup TwoPNCModel
- *
- * \file
- *
- * \brief Defines the properties required for the two-phase n-component
- *        fully implicit model.
- */
-#ifndef DUMUX_2PNC_PROPERTIES_HH
-#define DUMUX_2PNC_PROPERTIES_HH
+#ifndef DUMUX_2PNC_PROPERTIES_HH_OLD
+#define DUMUX_2PNC_PROPERTIES_HH_OLD
 
-#include <dumux/implicit/box/properties.hh>
-#include <dumux/implicit/cellcentered/properties.hh>
-#include <dumux/porousmediumflow/nonisothermal/implicit/properties.hh>
+#warning this header is deprecated, use dumux/porousmediumflow/2pnc/implicit/properties.hh instead
 
-namespace Dumux
-{
-
-namespace Properties
-{
-//////////////////////////////////////////////////////////////////
-// Type tags
-//////////////////////////////////////////////////////////////////
-
-//! The type tag for the implicit isothermal two phase n component problems
-NEW_TYPE_TAG(TwoPNC);
-NEW_TYPE_TAG(BoxTwoPNC, INHERITS_FROM(BoxModel, TwoPNC));
-NEW_TYPE_TAG(CCTwoPNC, INHERITS_FROM(CCModel, TwoPNC));
-
-//! The type tag for the implicit non-isothermal two phase n component problems
-NEW_TYPE_TAG(TwoPNCNI, INHERITS_FROM(TwoPNC, NonIsothermal));
-NEW_TYPE_TAG(BoxTwoPNCNI, INHERITS_FROM(BoxModel, TwoPNCNI));
-NEW_TYPE_TAG(CCTwoPNCNI, INHERITS_FROM(CCModel, TwoPNCNI));
-
-//////////////////////////////////////////////////////////////////
-// Property tags
-//////////////////////////////////////////////////////////////////
-
-NEW_PROP_TAG(NumPhases);   //!< Number of fluid phases in the system
-NEW_PROP_TAG(NumComponents); //!< Number of fluid components in the system
-NEW_PROP_TAG(NumMajorComponents); //!< Number of major fluid components which are considered in the calculation of the phase density
-NEW_PROP_TAG(TwoPNCIndices); //!< Enumerations for the 2pncMin models
-NEW_PROP_TAG(Formulation);   //!< The formulation of the model
-NEW_PROP_TAG(SpatialParams); //!< The type of the spatial parameters
-NEW_PROP_TAG(FluidSystem); //!< Type of the multi-component relations
-NEW_PROP_TAG(FluidState); //!< Type of the fluid state of the 2pnc model
-NEW_PROP_TAG(Indices); //!< Enumerations for the model
-NEW_PROP_TAG(Chemistry); //!< The chemistry class with which solves equlibrium reactions
-
-NEW_PROP_TAG(MaterialLaw);   //!< The material law which ought to be used (extracted from the spatial parameters)
-NEW_PROP_TAG(MaterialLawParams); //!< The parameters of the material law (extracted from the spatial parameters)
-
-NEW_PROP_TAG(ReplaceCompEqIdx); //!< The index of the total mass balance equation, if one component balance is replaced (ReplaceCompEqIdx < NumComponents)
-NEW_PROP_TAG(VtkAddVelocity); //!< Returns whether velocity vectors are written into the vtk output
-NEW_PROP_TAG(ProblemEnableGravity); //!< Returns whether gravity is considered in the problem
-NEW_PROP_TAG(ImplicitMassUpwindWeight); //!< The value of the upwind weight for the mass conservation equations
-NEW_PROP_TAG(ImplicitMobilityUpwindWeight); //!< The value of the upwind parameter for the mobility
-NEW_PROP_TAG(BaseFluxVariables); //! The base flux variables
-}
-}
+#include <dumux/porousmediumflow/2pnc/implicit/properties.hh>
 
 #endif
diff --git a/dumux/implicit/2pnc/2pncpropertydefaults.hh b/dumux/implicit/2pnc/2pncpropertydefaults.hh
index 4d78e5f1c0..e60b1422fb 100644
--- a/dumux/implicit/2pnc/2pncpropertydefaults.hh
+++ b/dumux/implicit/2pnc/2pncpropertydefaults.hh
@@ -1,226 +1,8 @@
-// -*- 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/>.   *
- *****************************************************************************/
-/*!
- * \ingroup Properties
- * \ingroup ImplicitProperties
- * \ingroup TwoPNCModel
- * \file
- *
- * \brief Defines default values for most properties required by the
- *        two-phase n-component fully implicit model.
- */
-#ifndef DUMUX_2PNC_PROPERTY_DEFAULTS_HH
-#define DUMUX_2PNC_PROPERTY_DEFAULTS_HH
+#ifndef DUMUX_2PNC_PROPERTY_DEFAULTS_HH_OLD
+#define DUMUX_2PNC_PROPERTY_DEFAULTS_HH_OLD
 
-#include "2pncindices.hh"
-#include "2pncmodel.hh"
-#include "2pncindices.hh"
-#include "2pncfluxvariables.hh"
-#include "2pncvolumevariables.hh"
-#include "2pncproperties.hh"
-#include "2pncnewtoncontroller.hh"
+#warning this header is deprecated, use dumux/porousmediumflow/2pnc/implicit/propertydefaults.hh instead
 
-#include <dumux/porousmediumflow/nonisothermal/implicit/propertydefaults.hh>
-#include <dumux/porousmediumflow/implicit/darcyfluxvariables.hh>
-#include <dumux/material/spatialparams/implicitspatialparams.hh>
-#include <dumux/material/fluidmatrixinteractions/2p/thermalconductivitysomerton.hh>
-
-namespace Dumux
-{
-
-namespace Properties {
-//////////////////////////////////////////////////////////////////
-// Property values
-//////////////////////////////////////////////////////////////////
-
-/*!
- * \brief Set the property for the number of components.
- *
- * We just forward the number from the fluid system
- *
- */
-SET_PROP(TwoPNC, NumComponents)
-{
-private:
-    typedef typename GET_PROP_TYPE(TypeTag, PTAG(FluidSystem)) FluidSystem;
-
-public:
-    static const int value = FluidSystem::numComponents;
-
-};
-//! Set as default that no component mass balance is replaced by the total mass balance
-SET_PROP(TwoPNC, ReplaceCompEqIdx)
-{
-private:
-    typedef typename GET_PROP_TYPE(TypeTag, PTAG(FluidSystem)) FluidSystem;
-
-public:
-    static const int value = FluidSystem::numComponents;
-};
-//! The major components belonging to the existing phases are mentioned here e.g., 2 for water and air being the major component in the liquid and gas phases in a 2 phase system
-SET_PROP(TwoPNC, NumMajorComponents)
-{
-private:
-    typedef typename GET_PROP_TYPE(TypeTag, PTAG(FluidSystem)) FluidSystem;
-
-public:
-    static const int value = FluidSystem::numPhases;
-    static_assert(value == 2,
-                  "The model is restricted to two-phases, thus number of major components must also be two.");
-};
-
-/*!
- * \brief Set the property for the number of fluid phases.
- *
- * We just forward the number from the fluid system and use an static
- * assert to make sure it is 2.
- */
-SET_PROP(TwoPNC, NumPhases)
-{
-private:
-    typedef typename GET_PROP_TYPE(TypeTag, PTAG(FluidSystem)) FluidSystem;
-
-public:
-    static const int value = FluidSystem::numPhases;
-    static_assert(value == 2,
-                  "Only fluid systems with 2 fluid phases are supported by the 2p-nc model!");
-};
-/*!
- * \brief Set the property for the number of equations: For each existing component one equation has to be solved.
- */
-SET_PROP(TwoPNC, NumEq)
-{
-private:
-    typedef typename GET_PROP_TYPE(TypeTag, PTAG(FluidSystem)) FluidSystem;
-
-public:
-    static const int value = FluidSystem::numComponents;
-};
-
-/*!
- * \brief The fluid state which is used by the volume variables to
- *        store the thermodynamic state. This should be chosen
- *        appropriately for the model ((non-)isothermal, equilibrium, ...).
- *        This can be done in the problem.
- */
-SET_PROP(TwoPNC, FluidState){
-    private:
-        typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
-        typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
-    public:
-        typedef Dumux::CompositionalFluidState<Scalar, FluidSystem> type;
-};
-
-//! Set the default formulation to pl-Sg: This can be over written in the problem.
-SET_INT_PROP(TwoPNC, Formulation, TwoPNCFormulation::plSg);
-
-//! Set the property for the material parameters by extracting it from the material law.
-SET_PROP(TwoPNC, MaterialLawParams)
-{
-private:
-    typedef typename GET_PROP_TYPE(TypeTag, PTAG(MaterialLaw)) MaterialLaw;
-
-public:
-    typedef typename MaterialLaw::Params type;
-};
-
-//! Use the 2pnc local residual
-SET_TYPE_PROP(TwoPNC, LocalResidual, TwoPNCLocalResidual<TypeTag>);
-
-//! Use the 2pnc newton controller
-SET_TYPE_PROP(TwoPNC, NewtonController, TwoPNCNewtonController<TypeTag>);
-
-//! the Model property
-SET_TYPE_PROP(TwoPNC, Model, TwoPNCModel<TypeTag>);
-
-//! the VolumeVariables property
-SET_TYPE_PROP(TwoPNC, VolumeVariables, TwoPNCVolumeVariables<TypeTag>);
-
-//! the FluxVariables property
-SET_TYPE_PROP(TwoPNC, FluxVariables, TwoPNCFluxVariables<TypeTag>);
-
-//! define the base flux variables to realize Darcy flow
-SET_TYPE_PROP(TwoPNC, BaseFluxVariables, ImplicitDarcyFluxVariables<TypeTag>);
-
-//! the upwind weight for the mass conservation equations.
-SET_SCALAR_PROP(TwoPNC, ImplicitMassUpwindWeight, 1.0);
-
-//! Set default mobility upwind weight to 1.0, i.e. fully upwind
-SET_SCALAR_PROP(TwoPNC, ImplicitMobilityUpwindWeight, 1.0);
-
-//! The indices required by the isothermal 2pnc model
-SET_TYPE_PROP(TwoPNC, Indices, TwoPNCIndices <TypeTag, /*PVOffset=*/0>);
-
-//! Use the ImplicitSpatialParams by default
-SET_TYPE_PROP(TwoPNC, SpatialParams, ImplicitSpatialParams<TypeTag>);
-
-//! Enable gravity by default
-SET_BOOL_PROP(TwoPNC, ProblemEnableGravity, true);
-
-//! Disable velocity output by default
-SET_BOOL_PROP(TwoPNC, VtkAddVelocity, false);
-
-//! Somerton is used as default model to compute the effective thermal heat conductivity
-SET_PROP(TwoPNCNI, ThermalConductivityModel)
-{
-private:
-    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
-    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
-public:
-    typedef ThermalConductivitySomerton<Scalar, Indices> type;
-};
-
-//! temperature is already written by the isothermal model
-SET_BOOL_PROP(TwoPNCNI, NiOutputLevel, 0);
-
-//////////////////////////////////////////////////////////////////
-// Property values for isothermal model required for the general non-isothermal model
-//////////////////////////////////////////////////////////////////
-
-// set isothermal Model
-SET_TYPE_PROP(TwoPNCNI, IsothermalModel, TwoPNCModel<TypeTag>);
-
-// set isothermal FluxVariables
-SET_TYPE_PROP(TwoPNCNI, IsothermalFluxVariables, TwoPNCFluxVariables<TypeTag>);
-
-//set isothermal VolumeVariables
-SET_TYPE_PROP(TwoPNCNI, IsothermalVolumeVariables, TwoPNCVolumeVariables<TypeTag>);
-
-//set isothermal LocalResidual
-SET_TYPE_PROP(TwoPNCNI, IsothermalLocalResidual, TwoPNCLocalResidual<TypeTag>);
-
-//set isothermal Indices
-SET_TYPE_PROP(TwoPNCNI, IsothermalIndices, TwoPNCIndices<TypeTag, /*PVOffset=*/0>);
-
-//set isothermal NumEq
-SET_PROP(TwoPNCNI, IsothermalNumEq)
-{
-private:
-    typedef typename GET_PROP_TYPE(TypeTag, PTAG(FluidSystem)) FluidSystem;
-
-public:
-    static const int value = FluidSystem::numComponents;
-};
-
-
-}
-
-}
+#include <dumux/porousmediumflow/2pnc/implicit/propertydefaults.hh>
 
 #endif
diff --git a/dumux/implicit/2pnc/2pncvolumevariables.hh b/dumux/implicit/2pnc/2pncvolumevariables.hh
index 2e515ba8c4..22f705ef64 100644
--- a/dumux/implicit/2pnc/2pncvolumevariables.hh
+++ b/dumux/implicit/2pnc/2pncvolumevariables.hh
@@ -1,529 +1,8 @@
-// -*- 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/>.   *
- *****************************************************************************/
-/*!
- * \file
- *
- * \brief Contains the quantities which are constant within a
- *        finite volume in the two-phase, n-component model.
- */
-#ifndef DUMUX_2PNC_VOLUME_VARIABLES_HH
-#define DUMUX_2PNC_VOLUME_VARIABLES_HH
+#ifndef DUMUX_2PNC_VOLUME_VARIABLES_HH_OLD
+#define DUMUX_2PNC_VOLUME_VARIABLES_HH_OLD
 
-#include <iostream>
-#include <vector>
+#warning this header is deprecated, use dumux/porousmediumflow/2pnc/implicit/volumevariables.hh instead
 
-#include <dumux/implicit/model.hh>
-#include <dumux/material/fluidstates/compositionalfluidstate.hh>
-#include <dumux/common/math.hh>
-
-#include "2pncproperties.hh"
-#include "2pncindices.hh"
-#include <dumux/material/constraintsolvers/computefromreferencephase2pnc.hh>
-#include <dumux/material/constraintsolvers/miscible2pnccomposition.hh>
-
-namespace Dumux
-{
-
-/*!
- * \ingroup TwoPNCModel
- * \ingroup ImplicitVolumeVariables
- * \brief Contains the quantities which are are constant within a
- *        finite volume in the two-phase, n-component model.
- */
-template <class TypeTag>
-class TwoPNCVolumeVariables : public ImplicitVolumeVariables<TypeTag>
-{
-    typedef ImplicitVolumeVariables<TypeTag> ParentType;
-    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) Implementation;
-
-    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
-    typedef typename GET_PROP_TYPE(TypeTag, Grid) Grid;
-    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
-    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
-    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
-    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
-    typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw;
-    typedef typename GET_PROP_TYPE(TypeTag, MaterialLawParams) MaterialLawParams;
-    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
-    enum
-    {
-        dim = GridView::dimension,
-        dimWorld=GridView::dimensionworld,
-
-        numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
-        numComponents = GET_PROP_VALUE(TypeTag, NumComponents),
-        numMajorComponents = GET_PROP_VALUE(TypeTag, NumMajorComponents),
-
-        // formulations
-        formulation = GET_PROP_VALUE(TypeTag, Formulation),
-        plSg = TwoPNCFormulation::plSg,
-        pgSl = TwoPNCFormulation::pgSl,
-
-        // phase indices
-        wPhaseIdx = FluidSystem::wPhaseIdx,
-        nPhaseIdx = FluidSystem::nPhaseIdx,
-
-        // component indices
-        wCompIdx = FluidSystem::wCompIdx,
-        nCompIdx = FluidSystem::nCompIdx,
-
-        // phase presence enums
-        nPhaseOnly = Indices::nPhaseOnly,
-        wPhaseOnly = Indices::wPhaseOnly,
-        bothPhases = Indices::bothPhases,
-
-        // primary variable indices
-        pressureIdx = Indices::pressureIdx,
-        switchIdx = Indices::switchIdx,
-
-    };
-
-    typedef typename GridView::template Codim<0>::Entity Element;
-    typedef typename Grid::ctype CoordScalar;
-    typedef Dumux::Miscible2pNCComposition<Scalar, FluidSystem> Miscible2pNCComposition;
-    typedef Dumux::ComputeFromReferencePhase2pNC<Scalar, FluidSystem> ComputeFromReferencePhase2pNC;
-
-    enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) };
-    enum { dofCodim = isBox ? dim : 0 };
-public:
-
-    typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState;
-
-    /*!
-     * \copydoc ImplicitVolumeVariables::update
-     * \param primaryVariables The primary Variables
-     */
-    void update(const PrimaryVariables &primaryVariables,
-                const Problem &problem,
-                const Element &element,
-                const FVElementGeometry &fvGeometry,
-                int scvIdx,
-                bool isOldSol)
-    {
-        ParentType::update(primaryVariables,
-                           problem,
-                           element,
-                           fvGeometry,
-                           scvIdx,
-                           isOldSol);
-
-        completeFluidState(primaryVariables, problem, element, fvGeometry, scvIdx, fluidState_, isOldSol);
-
-        /////////////
-        // calculate the remaining quantities
-        /////////////
-        const MaterialLawParams &materialParams = problem.spatialParams().materialLawParams(element, fvGeometry, scvIdx);
-
-    // Second instance of a parameter cache.
-        // Could be avoided if diffusion coefficients also
-        // became part of the fluid state.
-        typename FluidSystem::ParameterCache paramCache;
-        paramCache.updateAll(fluidState_);
-        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
-            {// relative permeabilities
-                    Scalar kr;
-                    if (phaseIdx == wPhaseIdx)
-                        kr = MaterialLaw::krw(materialParams, saturation(wPhaseIdx));
-                    else // ATTENTION: krn requires the liquid saturation
-                        // as parameter!
-                        kr = MaterialLaw::krn(materialParams, saturation(wPhaseIdx));
-                        mobility_[phaseIdx] = kr / fluidState_.viscosity(phaseIdx);
-                        Valgrind::CheckDefined(mobility_[phaseIdx]);
-                    int compIIdx = phaseIdx;
-                    for(int compIdx = 0; compIdx < numComponents; ++compIdx)
-                    {
-                    int compJIdx = compIdx;
-                    // binary diffusion coefficents
-                    diffCoeff_[phaseIdx][compIdx] = 0.0;
-                    if(compIIdx!= compJIdx)
-                    diffCoeff_[phaseIdx][compIdx] = FluidSystem::binaryDiffusionCoefficient(fluidState_,
-                                                                                    paramCache,
-                                                                                    phaseIdx,
-                                                                                    compIIdx,
-                                                                                    compJIdx);
-                    Valgrind::CheckDefined(diffCoeff_[phaseIdx][compIdx]);
-                }
-            }
-
-    // porosity
-    porosity_ = problem.spatialParams().porosity(element,
-                                                        fvGeometry,
-                                                        scvIdx);
-    Valgrind::CheckDefined(porosity_);
-    // energy related quantities not contained in the fluid state
-
-    asImp_().updateEnergy_(primaryVariables, problem,element, fvGeometry, scvIdx, isOldSol);
-    }
-
-   /*!
-    * \copydoc ImplicitModel::completeFluidState
-    * \param isOldSol Specifies whether this is the previous solution or the current one
-    * \param primaryVariables The primary Variables
-    */
-    static void completeFluidState(const PrimaryVariables& primaryVariables,
-                    const Problem& problem,
-                    const Element& element,
-                    const FVElementGeometry& fvGeometry,
-                    int scvIdx,
-                    FluidState& fluidState,
-                    bool isOldSol = false)
-
-    {
-        Scalar t = Implementation::temperature_(primaryVariables, problem, element,
-                                                fvGeometry, scvIdx);
-        fluidState.setTemperature(t);
-
-        int dofIdxGlobal = problem.model().dofMapper().subIndex(element, scvIdx, dofCodim);
-        int phasePresence = problem.model().phasePresence(dofIdxGlobal, isOldSol);
-
-        /////////////
-        // set the saturations
-        /////////////
-
-    Scalar Sg;
-        if (phasePresence == nPhaseOnly)
-            Sg = 1.0;
-        else if (phasePresence == wPhaseOnly) {
-            Sg = 0.0;
-        }
-        else if (phasePresence == bothPhases) {
-            if (formulation == plSg)
-                Sg = primaryVariables[switchIdx];
-            else if (formulation == pgSl)
-                Sg = 1.0 - primaryVariables[switchIdx];
-            else DUNE_THROW(Dune::InvalidStateException, "Formulation: " << formulation << " is invalid.");
-        }
-    else DUNE_THROW(Dune::InvalidStateException, "phasePresence: " << phasePresence << " is invalid.");
-        fluidState.setSaturation(nPhaseIdx, Sg);
-        fluidState.setSaturation(wPhaseIdx, 1.0 - Sg);
-
-        /////////////
-        // set the pressures of the fluid phases
-        /////////////
-
-        // calculate capillary pressure
-        const MaterialLawParams &materialParams
-        = problem.spatialParams().materialLawParams(element, fvGeometry, scvIdx);
-        Scalar pc = MaterialLaw::pc(materialParams, 1 - Sg);
-
-        // extract the pressures
-        if (formulation == plSg) {
-            fluidState.setPressure(wPhaseIdx, primaryVariables[pressureIdx]);
-            if (primaryVariables[pressureIdx] + pc < 0.0)
-                 DUNE_THROW(Dumux::NumericalProblem,"Capillary pressure is too low");
-            fluidState.setPressure(nPhaseIdx, primaryVariables[pressureIdx] + pc);
-        }
-        else if (formulation == pgSl) {
-            fluidState.setPressure(nPhaseIdx, primaryVariables[pressureIdx]);
-            // Here we check for (p_g - pc) in order to ensure that (p_l > 0)
-            if (primaryVariables[pressureIdx] - pc < 0.0)
-            {
-                std::cout<< "p_g: "<< primaryVariables[pressureIdx]<<" Cap_press: "<< pc << std::endl;
-                DUNE_THROW(Dumux::NumericalProblem,"Capillary pressure is too high");
-            }
-            fluidState.setPressure(wPhaseIdx, primaryVariables[pressureIdx] - pc);
-        }
-        else DUNE_THROW(Dune::InvalidStateException, "Formulation: " << formulation << " is invalid.");
-
-        /////////////
-        // calculate the phase compositions
-        /////////////
-
-    typename FluidSystem::ParameterCache paramCache;
-
-        // now comes the tricky part: calculate phase composition
-        if (phasePresence == bothPhases) {
-            // both phases are present, phase composition results from
-            // the gas <-> liquid equilibrium. This is
-            // the job of the "MiscibleMultiPhaseComposition"
-            // constraint solver
-
-            // set the known mole fractions in the fluidState so that they
-            // can be used by the Miscible2pNCComposition constraint solver
-            for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx)
-            {
-                fluidState.setMoleFraction(wPhaseIdx, compIdx, primaryVariables[compIdx]);
-            }
-
-            Miscible2pNCComposition::solve(fluidState,
-                        paramCache,
-                        wPhaseIdx,  //known phaseIdx
-                        /*setViscosity=*/true,
-                        /*setInternalEnergy=*/false);
-        }
-        else if (phasePresence == nPhaseOnly){
-
-            Dune::FieldVector<Scalar, numComponents> moleFrac;
-
-
-            moleFrac[wCompIdx] =  primaryVariables[switchIdx];
-
-            for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx)
-                    moleFrac[compIdx] = primaryVariables[compIdx];
-
-
-            Scalar sumMoleFracNotGas = 0;
-            for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx)
-                    sumMoleFracNotGas+=moleFrac[compIdx];
-
-            sumMoleFracNotGas += moleFrac[wCompIdx];
-            moleFrac[nCompIdx] = 1 - sumMoleFracNotGas;
-
-
-            // Set fluid state mole fractions
-            for (int compIdx=0; compIdx<numComponents; ++compIdx)
-                    fluidState.setMoleFraction(nPhaseIdx, compIdx, moleFrac[compIdx]);
-
-
-            // calculate the composition of the remaining phases (as
-            // well as the densities of all phases). this is the job
-            // of the "ComputeFromReferencePhase2pNC" constraint solver
-                ComputeFromReferencePhase2pNC::solve(fluidState,
-                                                paramCache,
-                                                nPhaseIdx,
-                                                /*setViscosity=*/true,
-                                                /*setInternalEnergy=*/false);
-
-            }
-        else if (phasePresence == wPhaseOnly){
-        // only the liquid phase is present, i.e. liquid phase
-        // composition is stored explicitly.
-        // extract _mass_ fractions in the gas phase
-            Dune::FieldVector<Scalar, numComponents> moleFrac;
-
-            for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx)
-            {
-                moleFrac[compIdx] = primaryVariables[compIdx];
-            }
-            moleFrac[nCompIdx] = primaryVariables[switchIdx];
-            Scalar sumMoleFracNotWater = 0;
-            for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx)
-            {
-                    sumMoleFracNotWater+=moleFrac[compIdx];
-            }
-            sumMoleFracNotWater += moleFrac[nCompIdx];
-            moleFrac[wCompIdx] = 1 -sumMoleFracNotWater;
-
-
-            // convert mass to mole fractions and set the fluid state
-            for (int compIdx=0; compIdx<numComponents; ++compIdx)
-            {
-                fluidState.setMoleFraction(wPhaseIdx, compIdx, moleFrac[compIdx]);
-            }
-
-            // calculate the composition of the remaining phases (as
-            // well as the densities of all phases). this is the job
-            // of the "ComputeFromReferencePhase2pNC" constraint solver
-            ComputeFromReferencePhase2pNC::solve(fluidState,
-                                                paramCache,
-                                                wPhaseIdx,
-                                                /*setViscosity=*/true,
-                                                /*setInternalEnergy=*/false);
-        }
-        paramCache.updateAll(fluidState);
-        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
-        {
-            Scalar rho = FluidSystem::density(fluidState, paramCache, phaseIdx);
-            Scalar mu = FluidSystem::viscosity(fluidState, paramCache, phaseIdx);
-
-            fluidState.setDensity(phaseIdx, rho);
-            fluidState.setViscosity(phaseIdx, mu);
-        }
-    }
-
-    /*!
-     * \brief Returns the phase state for the control-volume.
-     */
-    const FluidState &fluidState() const
-    { return fluidState_; }
-
-    /*!
-     * \brief Returns the saturation of a given phase within
-     *        the control volume in \f$[-]\f$.
-     *
-     * \param phaseIdx The phase index
-     */
-    Scalar saturation(int phaseIdx) const
-    { return fluidState_.saturation(phaseIdx); }
-
-    /*!
-     * \brief Returns the mass density of a given phase within the
-     *        control volume.
-     *
-     * \param phaseIdx The phase index
-     */
-    Scalar density(int phaseIdx) const
-    {
-        if (phaseIdx < numPhases)
-            return fluidState_.density(phaseIdx);
-
-        else
-            DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx);
-    }
-
-    /*!
-     * \brief Returns the mass density of a given phase within the
-     *        control volume.
-     *
-     * \param phaseIdx The phase index
-     */
-    Scalar molarDensity(int phaseIdx) const
-    {
-        if (phaseIdx < numPhases)
-            return fluidState_.molarDensity(phaseIdx);
-
-        else
-            DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx);
-    }
-
-    /*!
-     * \brief Returns the effective pressure of a given phase within
-     *        the control volume.
-     *
-     * \param phaseIdx The phase index
-     */
-    Scalar pressure(int phaseIdx) const
-    {
-        return fluidState_.pressure(phaseIdx);
-    }
-
-    /*!
-     * \brief Returns temperature inside the sub-control volume.
-     *
-     * Note that we assume thermodynamic equilibrium, i.e. the
-     * temperature of the rock matrix and of all fluid phases are
-     * identical.
-     */
-    Scalar temperature() const
-    { return fluidState_.temperature(/*phaseIdx=*/0); }
-
-    /*!
-     * \brief Returns the effective mobility of a given phase within
-     *        the control volume.
-     *
-     * \param phaseIdx The phase index
-     */
-    Scalar mobility(int phaseIdx) const
-    {
-        return mobility_[phaseIdx];
-    }
-
-    /*!
-     * \brief Returns the effective capillary pressure within the control volume
-     *        in \f$[kg/(m*s^2)=N/m^2=Pa]\f$.
-     */
-    Scalar capillaryPressure() const
-    { return fluidState_.pressure(FluidSystem::nPhaseIdx) - fluidState_.pressure(FluidSystem::wPhaseIdx); }
-
-    /*!
-     * \brief Returns the average porosity within the control volume.
-     */
-    Scalar porosity() const
-    { return porosity_; }
-
-
-    /*!
-     * \brief Returns the binary diffusion coefficients for a phase in \f$[m^2/s]\f$.
-     */
-    Scalar diffCoeff(int phaseIdx, int compIdx) const
-    { return diffCoeff_[phaseIdx][compIdx]; }
-
-    /*!
-     * \brief Returns the molarity of a component in the phase
-     *
-     * \param phaseIdx the index of the fluid phase
-     * \param compIdx the index of the component
-     */
-     Scalar molarity(int phaseIdx, int compIdx) const // [moles/m^3]
-    { return this->fluidState_.molarity(phaseIdx, compIdx);}
-
-     /*!
-      * \brief Returns the mass fraction of a component in the phase
-      *
-      * \param phaseIdx the index of the fluid phase
-      * \param compIdx the index of the component
-      */
-     Scalar massFraction(int phaseIdx, int compIdx) const
-     {
-        return this->fluidState_.massFraction(phaseIdx, compIdx);
-     }
-
-     /*!
-      * \brief Returns the mole fraction of a component in the phase
-      *
-      * \param phaseIdx the index of the fluid phase
-      * \param compIdx the index of the component
-      */
-     Scalar moleFraction(int phaseIdx, int compIdx) const
-     {
-        return this->fluidState_.moleFraction(phaseIdx, compIdx);
-     }
-
-protected:
-
-    static Scalar temperature_(const PrimaryVariables &priVars,
-                               const Problem& problem,
-                               const Element &element,
-                               const FVElementGeometry &fvGeometry,
-                               int scvIdx)
-    {
-        return problem.temperatureAtPos(fvGeometry.subContVol[scvIdx].global);
-    }
-
-    template<class ParameterCache>
-    static Scalar enthalpy_(const FluidState& fluidState,
-                            const ParameterCache& paramCache,
-                            int phaseIdx)
-    {
-        return 0;
-    }
-
-    /*!
-        * \brief Called by update() to compute the energy related quantities
-        */
-    void updateEnergy_(const PrimaryVariables &priVars,
-                        const Problem &problem,
-                        const Element &element,
-                        const FVElementGeometry &fvGeometry,
-                        const int scvIdx,
-                        bool isOldSol)
-    { };
-
-    Scalar porosity_;        //!< Effective porosity within the control volume
-    Scalar mobility_[numPhases];  //!< Effective mobility within the control volume
-    Scalar density_;
-    FluidState fluidState_;
-    Scalar theta_;
-    Scalar InitialPorosity_;
-    Scalar molWtPhase_[numPhases];
-    Dune::FieldMatrix<Scalar, numPhases, numComponents> diffCoeff_;
-
-private:
-    Implementation &asImp_()
-    { return *static_cast<Implementation*>(this); }
-
-    const Implementation &asImp_() const
-    { return *static_cast<const Implementation*>(this); }
-
-};
-
-} // end namespace
+#include <dumux/porousmediumflow/2pnc/implicit/volumevariables.hh>
 
 #endif
diff --git a/dumux/implicit/2pncmin/2pncminfluxvariables.hh b/dumux/implicit/2pncmin/2pncminfluxvariables.hh
index 3e0f7940f7..ce5cbcfceb 100644
--- a/dumux/implicit/2pncmin/2pncminfluxvariables.hh
+++ b/dumux/implicit/2pncmin/2pncminfluxvariables.hh
@@ -1,162 +1,8 @@
-// -**- 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/>.   *
- *****************************************************************************/
-/*!
- * \file
- * \brief Contains the data which is required to calculate
- *        all fluxes of components over a face of a finite volume for
- *        the two-phase two-component mineralization model fully implicit model.
- */
-#ifndef DUMUX_2PNCMIN_FLUX_VARIABLES_HH
-#define DUMUX_2PNCMIN_FLUX_VARIABLES_HH
+#ifndef DUMUX_2PNCMIN_FLUX_VARIABLES_HH_OLD
+#define DUMUX_2PNCMIN_FLUX_VARIABLES_HH_OLD
 
-#include <dumux/common/math.hh>
-#include <dumux/common/spline.hh>
-#include <dumux/implicit/2pnc/2pncfluxvariables.hh>
-#include "2pncminproperties.hh"
+#warning this header is deprecated, use dumux/porousmediumflow/2pncmin/implicit/fluxvariables.hh instead
 
-namespace Dumux
-{
-
-/*!
- * \ingroup TwoPNCMinModel
- * \ingroup ImplicitFluxVariables
- * \brief Contains the data which is required to calculate
- *        all fluxes of components over a face of a finite volume for
- *        the two-phase n-component mineralization fully implicit model.
- *
- * This means pressure and concentration gradients, phase densities at
- * the integration point, etc.
- */
-
-template <class TypeTag>
-class TwoPNCMinFluxVariables : public TwoPNCFluxVariables<TypeTag>
-{
-    typedef TwoPNCFluxVariables<TypeTag> ParentType;
-    typedef TwoPNCMinFluxVariables<TypeTag> ThisType;
-
-    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
-    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
-
-    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
-    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
-
-    typedef typename GridView::ctype CoordScalar;
-    typedef typename GridView::template Codim<0>::Entity Element;
-    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
-
-    enum {
-        dim = GridView::dimension,
-        dimWorld = GridView::dimensionworld,
-        numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
-        numComponents = GET_PROP_VALUE(TypeTag, NumComponents),
-    };
-
-    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
-    typedef typename GET_PROP_TYPE(TypeTag, SpatialParams) SpatialParams;
-    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
-    typedef typename FVElementGeometry::SubControlVolume SCV;
-    typedef typename FVElementGeometry::SubControlVolumeFace SCVFace;
-
-    typedef Dune::FieldVector<CoordScalar, dimWorld> DimVector;
-    typedef Dune::FieldMatrix<CoordScalar, dim, dim> DimMatrix;
-
-    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
-    enum {
-        wPhaseIdx = FluidSystem::wPhaseIdx,
-        nPhaseIdx = FluidSystem::nPhaseIdx,
-        wCompIdx  = FluidSystem::wCompIdx,
-    };
-
-public:
-    /*!
-     * \brief The constructor
-     *
-     * \param problem The problem
-     * \param element The finite element
-     * \param fvGeometry The finite-volume geometry in the fully implicit scheme
-     * \param fIdx The local index of the sub-control-volume face
-     * \param elemVolVars The volume variables of the current element
-     * \param onBoundary Evaluate flux at inner sub-control-volume face or on a boundary face
-     */
-    TwoPNCMinFluxVariables(const Problem &problem,
-                     const Element &element,
-                     const FVElementGeometry &fvGeometry,
-                     const int fIdx,
-                     const ElementVolumeVariables &elemVolVars,
-                     const bool onBoundary = false)
-    : ParentType(problem, element, fvGeometry, fIdx, elemVolVars, onBoundary)
-    {
-        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
-            this->density_[phaseIdx] = Scalar(0);
-            this->molarDensity_[phaseIdx] = Scalar(0);
-            this->potentialGrad_[phaseIdx] = Scalar(0);
-            for (int compIdx = 0; compIdx < numComponents; ++compIdx)
-            {
-                this->massFractionGrad_[phaseIdx][compIdx] = Scalar(0);
-                this->moleFractionGrad_[phaseIdx][compIdx] = Scalar(0);
-            }
-        }
-        this->calculateGradients_(problem, element, elemVolVars);
-        this->calculateVelocities_(problem, element, elemVolVars);
-        this->calculateporousDiffCoeff_(problem, element, elemVolVars);
-    };
-
-protected:
-    void calculateVelocities_(const Problem &problem,
-                              const Element &element,
-                              const ElementVolumeVariables &elemVolVars)
-    {
-        const SpatialParams &spatialParams = problem.spatialParams();
-        // multiply the pressure potential with the intrinsic permeability
-        DimMatrix K(0.0);
-
-        for (int phaseIdx=0; phaseIdx < numPhases; phaseIdx++)
-        {
-            const VolumeVariables &volVarsI = elemVolVars[this->face().i];
-            const VolumeVariables &volVarsJ = elemVolVars[this->face().j];
-
-            auto K_i = spatialParams.intrinsicPermeability(element,this->fvGeometry_,this->face().i);
-            K_i *= volVarsI.permeabilityFactor();
-
-            auto K_j = spatialParams.intrinsicPermeability(element,this->fvGeometry_,this->face().j);
-            K_j *= volVarsJ.permeabilityFactor();
-
-            spatialParams.meanK(K,K_i,K_j);
-
-            K.mv(this->potentialGrad_[phaseIdx], this->Kmvp_[phaseIdx]);
-            this->KmvpNormal_[phaseIdx] = - (this->Kmvp_[phaseIdx] * this->face().normal);
-        }
-
-        // set the upstream and downstream vertices
-        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
-        {
-            this->upstreamIdx_[phaseIdx] = this->face().i;
-            this->downstreamIdx_[phaseIdx] = this->face().j;
-
-            if (this->KmvpNormal_[phaseIdx] < 0) {
-                std::swap(this->upstreamIdx_[phaseIdx],
-                          this->downstreamIdx_[phaseIdx]);
-            }
-        }
-    }
-};
-
-} // end namespace
+#include <dumux/porousmediumflow/2pncmin/implicit/fluxvariables.hh>
 
 #endif
diff --git a/dumux/implicit/2pncmin/2pncminindices.hh b/dumux/implicit/2pncmin/2pncminindices.hh
index 8f4e103666..bf98e8edbf 100644
--- a/dumux/implicit/2pncmin/2pncminindices.hh
+++ b/dumux/implicit/2pncmin/2pncminindices.hh
@@ -1,48 +1,8 @@
-// -*- 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_2PNCMIN_INDICES_HH_OLD
+#define DUMUX_2PNCMIN_INDICES_HH_OLD
 
-/*!
- * \file
- * \brief Defines the indices required for the two-phase n-component mineralization
- *        fully implicit model.
- */
-#ifndef DUMUX_2PNCMIN_INDICES_HH
-#define DUMUX_2PNCMIN_INDICES_HH
+#warning this header is deprecated, use dumux/porousmediumflow/2pncmin/implicit/indices.hh instead
 
-#include <dumux/implicit/2pnc/2pncindices.hh>
-
-namespace Dumux
-{
-/*!
- * \ingroup TwoPNCMinModel
- * \ingroup ImplicitIndices
- * \brief The indices for the isothermal two-phase n-component mineralization model.
- *
- * \tparam PVOffset The first index in a primary variable vector.
- */
-template <class TypeTag, int PVOffset = 0>
-    class TwoPNCMinIndices: public TwoPNCIndices<TypeTag, PVOffset>
-{
-};
-
-// \}
-
-}
+#include <dumux/porousmediumflow/2pncmin/implicit/indices.hh>
 
 #endif
diff --git a/dumux/implicit/2pncmin/2pncminlocalresidual.hh b/dumux/implicit/2pncmin/2pncminlocalresidual.hh
index 72299478f4..142ce3e389 100644
--- a/dumux/implicit/2pncmin/2pncminlocalresidual.hh
+++ b/dumux/implicit/2pncmin/2pncminlocalresidual.hh
@@ -1,140 +1,8 @@
-// -*- 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/>.   *
- *****************************************************************************/
-/*!
- * \file
- *
- * \brief Element-wise calculation of the Jacobian matrix for problems
- *        using the two-phase n-component mineralisation box model.
- */
+#ifndef DUMUX_2PNCMIN_LOCAL_RESIDUAL_BASE_HH_OLD
+#define DUMUX_2PNCMIN_LOCAL_RESIDUAL_BASE_HH_OLD
 
-#ifndef DUMUX_2PNCMIN_LOCAL_RESIDUAL_BASE_HH
-#define DUMUX_2PNCMIN_LOCAL_RESIDUAL_BASE_HH
+#warning this header is deprecated, use dumux/porousmediumflow/2pncmin/implicit/localresidual.hh instead
 
-#include "2pncminproperties.hh"
-#include <dumux/implicit/2pnc/2pnclocalresidual.hh>
-
-namespace Dumux
-{
-/*!
- * \ingroup TwoPNCMinModel
- * \ingroup ImplicitLocalResidual
- * \brief Element-wise calculation of the Jacobian matrix for problems
- *        using the two-phase n-component mineralization fully implicit box model.
- *
- * This class is used to fill the gaps in ImplicitLocalResidual for the two-phase n-component flow.
- */
-template<class TypeTag>
-class TwoPNCMinLocalResidual: public TwoPNCLocalResidual<TypeTag>
-{
-protected:
-    typedef TwoPNCLocalResidual<TypeTag> ParentType;
-    typedef TwoPNCMinLocalResidual<TypeTag> ThisType;
-    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
-    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
-    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
-    typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector;
-    typedef typename GET_PROP_TYPE(TypeTag, ElementSolutionVector) ElementSolutionVector;
-    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes;
-    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
-    typedef typename GET_PROP_TYPE(TypeTag, LocalResidual) Implementation;
-
-
-    enum
-    {
-        numEq = GET_PROP_VALUE(TypeTag, NumEq),
-        numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
-        numSPhases = GET_PROP_VALUE(TypeTag, NumSPhases),
-        numComponents = GET_PROP_VALUE(TypeTag, NumComponents),
-
-        replaceCompEqIdx = GET_PROP_VALUE(TypeTag, ReplaceCompEqIdx),
-
-        pressureIdx = Indices::pressureIdx,
-        switchIdx = Indices::switchIdx,
-
-        wPhaseIdx = FluidSystem::wPhaseIdx,
-        nPhaseIdx = FluidSystem::nPhaseIdx,
-
-        wCompIdx = FluidSystem::wCompIdx,
-        nCompIdx = FluidSystem::nCompIdx,
-
-        conti0EqIdx = Indices::conti0EqIdx,
-
-        wPhaseOnly = Indices::wPhaseOnly,
-        nPhaseOnly = Indices::nPhaseOnly,
-        bothPhases = Indices::bothPhases,
-
-        plSg = TwoPNCFormulation::plSg,
-        pgSl = TwoPNCFormulation::pgSl,
-        formulation = GET_PROP_VALUE(TypeTag, Formulation)
-    };
-
-    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, ElementBoundaryTypes) ElementBoundaryTypes;
-    typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, SpatialParams) SpatialParams;
-    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
-
-public:
-    /*!
-     * \brief Constructor. Sets the upwind weight.
-     */
-    TwoPNCMinLocalResidual()
-    {
-        // retrieve the upwind weight for the mass conservation equations. Use the value
-        // specified via the property system as default, and overwrite
-        // it by the run-time parameter from the Dune::ParameterTree
-        this->massUpwindWeight_ = GET_PARAM_FROM_GROUP(TypeTag, Scalar, Implicit, MassUpwindWeight);
-    };
-
-    /*!
-     * \brief Evaluate the amount all conservation quantities
-     *        (e.g. phase mass) within a sub-control volume.
-     *
-     * The result should be averaged over the volume (e.g. phase mass
-     * inside a sub control volume divided by the volume).
-     * In contrast to the 2pnc model, here, the storage of solid phases is included too.
-     *
-     *  \param storage the mass of the component within the sub-control volume
-     *  \param scvIdx The SCV (sub-control-volume) index
-     *  \param usePrevSol Evaluate function with solution of current or previous time step
-     */
-  void computeStorage(PrimaryVariables &storage, int scvIdx, bool usePrevSol) const
-  {
-      //call parenttype function
-      ParentType::computeStorage(storage, scvIdx, usePrevSol);
-
-      const ElementVolumeVariables &elemVolVars = usePrevSol ? this->prevVolVars_()
-      : this->curVolVars_();
-    const VolumeVariables &volVars = elemVolVars[scvIdx];
-
-    // Compute storage term of all solid (precipitated) phases (excluding the non-reactive matrix)
-    for (int phaseIdx = numPhases; phaseIdx < numPhases + numSPhases; ++phaseIdx)
-    {
-      int eqIdx = conti0EqIdx + numComponents-numPhases + phaseIdx;
-      storage[eqIdx] += volVars.precipitateVolumeFraction(phaseIdx)*volVars.molarDensity(phaseIdx);
-    }
-
-      Valgrind::CheckDefined(storage);
-  }
-};
-} // end namespace
+#include <dumux/porousmediumflow/2pncmin/implicit/localresidual.hh>
 
 #endif
diff --git a/dumux/implicit/2pncmin/2pncminmodel.hh b/dumux/implicit/2pncmin/2pncminmodel.hh
index ac054fa6ee..7bfac2d257 100644
--- a/dumux/implicit/2pncmin/2pncminmodel.hh
+++ b/dumux/implicit/2pncmin/2pncminmodel.hh
@@ -1,551 +1,8 @@
-// -*- 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/>.   *
- *****************************************************************************/
-/*!
-* \file
-*
-* \brief Adaption of the fully implicit box scheme to the two-phase n-component flow model.
-*/
+#ifndef DUMUX_2PNCMIN_MODEL_HH_OLD
+#define DUMUX_2PNCMIN_MODEL_HH_OLD
 
-#ifndef DUMUX_2PNCMIN_MODEL_HH
-#define DUMUX_2PNCMIN_MODEL_HH
+#warning this header is deprecated, use dumux/porousmediumflow/2pncmin/implicit/model.hh instead
 
-#include "2pncminproperties.hh"
-#include "2pncminindices.hh"
-
-#include <dumux/material/constants.hh>
- #include <dumux/implicit/2pnc/2pncmodel.hh>
-#include "2pncminlocalresidual.hh"
-#include <dumux/porousmediumflow/implicit/velocityoutput.hh>
-
-namespace Dumux
-{
-/*!
- * \ingroup TwoPNCMinModel
- * \brief Adaption of the fully implicit scheme to the
- *        two-phase n-component fully implicit model.
- *
- * This model implements two-phase n-component flow of two compressible and
- * partially miscible fluids \f$\alpha \in \{ w, n \}\f$ composed of the n components
- * \f$\kappa \in \{ w, a,\cdots \}\f$. The standard multiphase Darcy
- * approach is used as the equation for the conservation of momentum:
- * \f[
- v_\alpha = - \frac{k_{r\alpha}}{\mu_\alpha} \mbox{\bf K}
- \left(\text{grad}\, p_\alpha - \varrho_{\alpha} \mbox{\bf g} \right)
- * \f]
- *
- * By inserting this into the equations for the conservation of the
- * components, one gets one transport equation for each component
- * \f{eqnarray}
- && \phi \frac{\partial (\sum_\alpha \varrho_\alpha X_\alpha^\kappa S_\alpha )}
- {\partial t}
- - \sum_\alpha  \text{div} \left\{ \varrho_\alpha X_\alpha^\kappa
- \frac{k_{r\alpha}}{\mu_\alpha} \mbox{\bf K}
- (\text{grad}\, p_\alpha - \varrho_{\alpha}  \mbox{\bf g}) \right\}
- \nonumber \\ \nonumber \\
-    &-& \sum_\alpha \text{div} \left\{{\bf D_{\alpha, pm}^\kappa} \varrho_{\alpha} \text{grad}\, X^\kappa_{\alpha} \right\}
- - \sum_\alpha q_\alpha^\kappa = 0 \qquad \kappa \in \{w, a,\cdots \} \, ,
- \alpha \in \{w, g\}
- \f}
- *
- * All equations are discretized using a vertex-centered finite volume (box)
- * or cell-centered finite volume scheme (this is not done for 2pnc approach yet, however possible) as
- * spatial and the implicit Euler method as time discretization.
- *
- * By using constitutive relations for the capillary pressure \f$p_c =
- * p_n - p_w\f$ and relative permeability \f$k_{r\alpha}\f$ and taking
- * advantage of the fact that \f$S_w + S_n = 1\f$ and \f$X^\kappa_w + X^\kappa_n = 1\f$, the number of
- * unknowns can be reduced to number of components.
- *
- * The used primary variables are, like in the two-phase model, either \f$p_w\f$ and \f$S_n\f$
- * or \f$p_n\f$ and \f$S_w\f$. The formulation which ought to be used can be
- * specified by setting the <tt>Formulation</tt> property to either
- * TwoPTwoCIndices::pWsN or TwoPTwoCIndices::pNsW. By
- * default, the model uses \f$p_w\f$ and \f$S_n\f$.
- *
- * Moreover, the second primary variable depends on the phase state, since a
- * primary variable switch is included. The phase state is stored for all nodes
- * of the system. The model is uses mole fractions.
- *Following cases can be distinguished:
- * <ul>
- *  <li> Both phases are present: The saturation is used (either \f$S_n\f$ or \f$S_w\f$, dependent on the chosen <tt>Formulation</tt>),
- *      as long as \f$ 0 < S_\alpha < 1\f$</li>.
- *  <li> Only wetting phase is present: The mass fraction of, e.g., air in the wetting phase \f$X^a_w\f$ is used,
- *      as long as the maximum mass fraction is not exceeded (\f$X^a_w<X^a_{w,max}\f$)</li>
- *  <li> Only non-wetting phase is present: The mass fraction of, e.g., water in the non-wetting phase, \f$X^w_n\f$, is used,
- *      as long as the maximum mass fraction is not exceeded (\f$X^w_n<X^w_{n,max}\f$)</li>
- * </ul>
- */
-
-template<class TypeTag>
-class TwoPNCMinModel: public TwoPNCModel<TypeTag>
-{
-    typedef TwoPNCMinModel<TypeTag> ThisType;
-    typedef TwoPNCModel<TypeTag> ParentType;
-
-    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
-    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
-    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
-    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
-
-    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
-    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, ElementBoundaryTypes) ElementBoundaryTypes;
-    typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, VertexMapper) VertexMapper;
-    typedef typename GET_PROP_TYPE(TypeTag, ElementMapper) ElementMapper;
-    typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector;
-    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
-    typedef Dumux::Constants<Scalar> Constant;
-
-    enum {
-        dim = GridView::dimension,
-        dimWorld = GridView::dimensionworld,
-
-        numEq = GET_PROP_VALUE(TypeTag, NumEq),
-        numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
-        numSPhases = GET_PROP_VALUE(TypeTag, NumSPhases),
-        numComponents = GET_PROP_VALUE(TypeTag, NumComponents),
-        numSecComponents = GET_PROP_VALUE(TypeTag, NumSecComponents),
-        numMajorComponents = GET_PROP_VALUE(TypeTag, NumMajorComponents),
-
-        pressureIdx = Indices::pressureIdx,
-        switchIdx = Indices::switchIdx,
-
-        wPhaseIdx = Indices::wPhaseIdx,
-        nPhaseIdx = Indices::nPhaseIdx,
-
-        wCompIdx = FluidSystem::wCompIdx,
-        nCompIdx = FluidSystem::nCompIdx,
-
-        wPhaseOnly = Indices::wPhaseOnly,
-        nPhaseOnly = Indices::nPhaseOnly,
-        bothPhases = Indices::bothPhases,
-
-        plSg = TwoPNCFormulation::plSg,
-        pgSl = TwoPNCFormulation::pgSl,
-        formulation = GET_PROP_VALUE(TypeTag, Formulation)
-    };
-
-    typedef typename GridView::template Codim<dim>::Entity Vertex;
-    typedef typename GridView::template Codim<0>::Entity Element;
-
-    typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition;
-    typedef typename GridView::ctype CoordScalar;
-    typedef Dune::FieldMatrix<CoordScalar, dimWorld, dimWorld> Tensor;
-    typedef Dune::FieldVector<Scalar, numPhases> PhasesVector;
-
-    enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) };
-    enum { dofCodim = isBox ? dim : 0 };
-
-public:
-
-    /*!
-     * \brief Append all quantities of interest which can be derived
-     *        from the solution of the current time step to the VTK
-     *        writer.
-     *
-     * \param sol The solution vector
-     * \param writer The writer for multi-file VTK datasets
-     */
-    template<class MultiWriter>
-    //additional output of the permeability and the precipitate volume fractions
-    void addOutputVtkFields(const SolutionVector &sol,
-                            MultiWriter &writer)
-    {
-        typedef Dune::BlockVector<Dune::FieldVector<Scalar, 1> > ScalarField;
-        typedef Dune::BlockVector<Dune::FieldVector<double, dim> > VectorField;
-
-        // get the number of degrees of freedom
-        unsigned numDofs = this->numDofs();
-
-        // create the required scalar fields
-        ScalarField *Sg           = writer.allocateManagedBuffer (numDofs);
-        ScalarField *Sl        = writer.allocateManagedBuffer (numDofs);
-        ScalarField *pg           = writer.allocateManagedBuffer (numDofs);
-        ScalarField *pl           = writer.allocateManagedBuffer (numDofs);
-        ScalarField *pc        = writer.allocateManagedBuffer (numDofs);
-        ScalarField *rhoL       = writer.allocateManagedBuffer (numDofs);
-        ScalarField *rhoG       = writer.allocateManagedBuffer (numDofs);
-        ScalarField *mobL       = writer.allocateManagedBuffer (numDofs);
-        ScalarField *mobG        = writer.allocateManagedBuffer (numDofs);
-        ScalarField *phasePresence = writer.allocateManagedBuffer (numDofs);
-        ScalarField *temperature   = writer.allocateManagedBuffer (numDofs);
-        ScalarField *poro          = writer.allocateManagedBuffer (numDofs);
-        ScalarField *boxVolume     = writer.allocateManagedBuffer (numDofs);
-        ScalarField *cellNum        = writer.allocateManagedBuffer (numDofs);
-        ScalarField *permeabilityFactor    = writer.allocateManagedBuffer (numDofs);
-        ScalarField *precipitateVolumeFraction[numSPhases] ;
-
-        for (int i = 0; i < numSPhases; ++i)
-        {
-            precipitateVolumeFraction[i]= writer.allocateManagedBuffer (numDofs);
-        }
-
-        ScalarField *massFraction[numPhases][numComponents];
-        for (int i = 0; i < numPhases; ++i)
-            for (int j = 0; j < numComponents; ++j)
-                massFraction[i][j] = writer.allocateManagedBuffer(numDofs);
-
-        ScalarField *molarity[numComponents];
-        for (int j = 0; j < numComponents ; ++j)
-            molarity[j] = writer.allocateManagedBuffer(numDofs);
-
-        ScalarField *Perm[dim];
-        for (int j = 0; j < dim; ++j) //Permeability only in main directions xx and yy
-            Perm[j] = writer.allocateManagedBuffer(numDofs);
-
-        *boxVolume = 0;
-
-        VectorField *velocityN = writer.template allocateManagedBuffer<double, dim>(numDofs);
-        VectorField *velocityW = writer.template allocateManagedBuffer<double, dim>(numDofs);
-        ImplicitVelocityOutput<TypeTag> velocityOutput(this->problem_());
-
-        if (velocityOutput.enableOutput()) // check if velocity output is demanded
-        {
-            // initialize velocity fields
-            for (unsigned int i = 0; i < numDofs; ++i)
-            {
-                (*velocityN)[i] = Scalar(0);
-                (*velocityW)[i] = Scalar(0);
-                (*cellNum)[i] = Scalar(0.0);
-            }
-        }
-
-        unsigned numElements = this->gridView_().size(0);
-        ScalarField *rank =
-                writer.allocateManagedBuffer (numElements);
-
-        FVElementGeometry fvGeometry;
-        VolumeVariables volVars;
-        ElementVolumeVariables elemVolVars;
-
-        for (const auto& element : Dune::elements(this->gridView_()))
-        {
-            int idx = this->problem_().elementMapper().index(element);
-            (*rank)[idx] = this->gridView_().comm().rank();
-            fvGeometry.update(this->gridView_(), element);
-
-            elemVolVars.update(this->problem_(),
-                    element,
-                    fvGeometry,
-                    false /* oldSol? */);
-
-            int numVerts = element.subEntities(dim);
-
-            for (int i = 0; i < numVerts; ++i)
-            {
-                int globalIdx = this->vertexMapper().subIndex(element, i, dim);
-                volVars.update(sol[globalIdx],
-                               this->problem_(),
-                               element,
-                               fvGeometry,
-                               i,
-                               false);
-
-                (*Sg)[globalIdx]              = volVars.saturation(nPhaseIdx);
-                (*Sl)[globalIdx]              = volVars.saturation(wPhaseIdx);
-                (*pg)[globalIdx]                = volVars.pressure(nPhaseIdx);
-                (*pl)[globalIdx]                 = volVars.pressure(wPhaseIdx);
-                (*pc)[globalIdx]              = volVars.capillaryPressure();
-                (*rhoL)[globalIdx]               = volVars.density(wPhaseIdx);
-                (*rhoG)[globalIdx]               = volVars.density(nPhaseIdx);
-                (*mobL)[globalIdx]               = volVars.mobility(wPhaseIdx);
-                (*mobG)[globalIdx]               = volVars.mobility(nPhaseIdx);
-                (*boxVolume)[globalIdx]        += fvGeometry.subContVol[i].volume;
-                (*poro)[globalIdx]              = volVars.porosity();
-
-                for (int sPhaseIdx = 0; sPhaseIdx < numSPhases; ++sPhaseIdx)
-                {
-                    (*precipitateVolumeFraction[sPhaseIdx])[globalIdx]   = volVars.precipitateVolumeFraction(sPhaseIdx + numPhases);
-                }
-                (*temperature)[globalIdx]      = volVars.temperature();
-                (*permeabilityFactor)[globalIdx]      = volVars.permeabilityFactor();
-                (*phasePresence)[globalIdx]  = this->staticDat_[globalIdx].phasePresence;
-
-                for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
-                    for (int compIdx = 0; compIdx < numComponents; ++compIdx)
-                    {
-                        (*massFraction[phaseIdx][compIdx])[globalIdx]= volVars.massFraction(phaseIdx,compIdx);
-
-                        Valgrind::CheckDefined((*massFraction[phaseIdx][compIdx])[globalIdx]);
-
-                    }
-                for (int compIdx = 0; compIdx < numComponents; ++compIdx)
-                    (*molarity[compIdx])[globalIdx] = (volVars.molarity(wPhaseIdx, compIdx));
-
-                Tensor K = this->perm_(this->problem_().spatialParams().intrinsicPermeability(element, fvGeometry, i));
-
-                for (int j = 0; j<dim; ++j)
-                    (*Perm[j])[globalIdx] = K[j][j] * volVars.permeabilityFactor();
-            };
-
-            // velocity output
-            if(velocityOutput.enableOutput()){
-                velocityOutput.calculateVelocity(*velocityW, elemVolVars, fvGeometry, element, wPhaseIdx);
-                velocityOutput.calculateVelocity(*velocityN, elemVolVars, fvGeometry, element, nPhaseIdx);
-            }
-        }  // loop over element
-
-        writer.attachVertexData(*Sg, "Sg");
-        writer.attachVertexData(*Sl, "Sl");
-        writer.attachVertexData(*pg, "pg");
-        writer.attachVertexData(*pl, "pl");
-        writer.attachVertexData(*pc, "pc");
-        writer.attachVertexData(*rhoL, "rhoL");
-        writer.attachVertexData(*rhoG, "rhoG");
-        writer.attachVertexData(*mobL, "mobL");
-        writer.attachVertexData(*mobG, "mobG");
-        writer.attachVertexData(*poro, "porosity");
-        writer.attachVertexData(*permeabilityFactor, "permeabilityFactor");
-        writer.attachVertexData(*temperature, "temperature");
-        writer.attachVertexData(*phasePresence, "phase presence");
-        writer.attachVertexData(*boxVolume, "boxVolume");
-
-
-        for (int i = 0; i < numSPhases; ++i)
-        {
-            std::ostringstream oss;
-            oss << "precipitateVolumeFraction_"
-                << FluidSystem::phaseName(numPhases + i);
-            writer.attachDofData(*precipitateVolumeFraction[i], oss.str().c_str(), isBox);
-        }
-
-        writer.attachVertexData(*Perm[0], "Kxx");
-        if (dim >= 2)
-            writer.attachVertexData(*Perm[1], "Kyy");
-        if (dim == 3)
-            writer.attachVertexData(*Perm[2], "Kzz");
-
-        for (int i = 0; i < numPhases; ++i)
-        {
-            for (int j = 0; j < numComponents; ++j)
-            {
-                std::ostringstream oss;
-                oss << "X^"
-                << FluidSystem::phaseName(i)
-                << "_"
-                << FluidSystem::componentName(j);
-                writer.attachVertexData(*massFraction[i][j], oss.str().c_str());
-            }
-        }
-
-        for (int j = 0; j < numComponents; ++j)
-        {
-            std::ostringstream oss;
-            oss << "m^w_"
-                << FluidSystem::componentName(j);
-            writer.attachVertexData(*molarity[j], oss.str().c_str());
-        }
-
-        if (velocityOutput.enableOutput()) // check if velocity output is demanded
-        {
-            writer.attachDofData(*velocityW,  "velocityW", isBox, dim);
-            writer.attachDofData(*velocityN,  "velocityN", isBox, dim);
-        }
-
-        writer.attachCellData(*rank, "process rank");
-    }
-
-    /*!
-     * \brief Update the static data of all vertices in the grid.
-     *
-     * \param curGlobalSol The current global solution
-     * \param oldGlobalSol The previous global solution
-     */
-    void updateStaticData(SolutionVector &curGlobalSol,
-                          const SolutionVector &oldGlobalSol)
-    {
-        bool wasSwitched = false;
-
-        for (unsigned i = 0; i < this->staticDat_.size(); ++i)
-            this->staticDat_[i].visited = false;
-
-        FVElementGeometry fvGeometry;
-        static VolumeVariables volVars;
-        for (const auto& element : Dune::elements(this->gridView_()))
-        {
-            fvGeometry.update(this->gridView_(), element);
-            for (int i = 0; i < fvGeometry.numScv; ++i)
-            {
-                int globalIdx = this->vertexMapper().subIndex(element, i, dim);
-
-                if (this->staticDat_[globalIdx].visited)
-                    continue;
-
-                this->staticDat_[globalIdx].visited = true;
-                volVars.update(curGlobalSol[globalIdx],
-                               this->problem_(),
-                               element,
-                               fvGeometry,
-                               i,
-                               false);
-                const GlobalPosition &global = element.geometry().corner(i);
-                if (primaryVarSwitch_(curGlobalSol,
-                                      volVars,
-                                      globalIdx,
-                                      global))
-                { wasSwitched = true;
-                }
-            }
-        }
-
-        // make sure that if there was a variable switch in an
-        // other partition we will also set the switch flag
-        // for our partition.
-        if (this->gridView_().comm().size() > 1)
-        wasSwitched = this->gridView_().comm().max(wasSwitched);
-
-        setSwitched_(wasSwitched);
-    }
-protected:
-
-    /*!
-     * \brief Set whether there was a primary variable switch after in
-     *        the last timestep.
-     */
-    void setSwitched_(bool yesno)
-    {
-        switchFlag_ = yesno;
-    }
-
-    /*!
-     * \copydoc 2pnc::primaryVarSwitch_
-     */
-    bool primaryVarSwitch_(SolutionVector &globalSol,
-                           const VolumeVariables &volVars, int globalIdx,
-                           const GlobalPosition &globalPos)
-    {
-            // evaluate primary variable switch
-            bool wouldSwitch = false;
-            int phasePresence = this->staticDat_[globalIdx].phasePresence;
-            int newPhasePresence = phasePresence;
-
-            //check if a primary variable switch is necessary
-            if (phasePresence == bothPhases)
-            {
-                Scalar Smin = 0.0; //saturation threshold
-                if (this->staticDat_[globalIdx].wasSwitched)
-                    Smin = -0.01;
-
-                //if saturation of liquid phase is smaller 0 switch
-                if (volVars.saturation(wPhaseIdx) <= Smin)
-                {
-                    wouldSwitch = true;
-                    //liquid phase has to disappear
-                    std::cout << "Liquid Phase disappears at vertex " << globalIdx
-                                << ", coordinated: " << globalPos << ", Sl: "
-                                << volVars.saturation(wPhaseIdx) << std::endl;
-                    newPhasePresence = nPhaseOnly;
-
-                    //switch not depending on formulation
-                    //switch "Sl" to "xgH20"
-                    globalSol[globalIdx][switchIdx]
-                            = volVars.moleFraction(nPhaseIdx, wCompIdx /*H2O*/);
-                    //Here unlike 2pnc model we do not switch all components to to mole fraction in gas phase
-                }
-                //if saturation of gas phase is smaller than 0 switch
-                else if (volVars.saturation(nPhaseIdx) <= Smin)
-                {
-                    wouldSwitch = true;
-                    //gas phase has to disappear
-                    std::cout << "Gas Phase disappears at vertex " << globalIdx
-                                << ", coordinated: " << globalPos << ", Sg: "
-                                << volVars.saturation(nPhaseIdx) << std::endl;
-                    newPhasePresence = wPhaseOnly;
-
-                    //switch "Sl" to "xlN2"
-                    globalSol[globalIdx][switchIdx]
-                            = volVars.moleFraction(wPhaseIdx, nCompIdx /*N2*/);
-                }
-            }
-            else if (phasePresence == nPhaseOnly)
-            {
-            Scalar sumxl = 0;
-            //Calculate sum of mole fractions (water and air) in the hypothetical liquid phase
-            //WARNING: Here numComponents is replaced by numMajorComponents as the solutes
-            //are only present in the liquid phase and cannot condense as the liquid (water).
-            for (int compIdx = 0; compIdx < numComponents; compIdx++)
-                {
-                    sumxl += volVars.moleFraction(wPhaseIdx, compIdx);
-                }
-                    Scalar xlmax = 1.0;
-                    if (sumxl > xlmax)
-                wouldSwitch = true;
-                    if (this->staticDat_[globalIdx].wasSwitched)
-                xlmax *=1.02;
-
-            //if the sum of the mole fractions would be larger than
-            //1, wetting phase appears
-                    if (sumxl/*sum of mole fractions*/ > xlmax/*1*/)
-                    {
-                        // liquid phase appears
-                        std::cout << "Liquid Phase appears at vertex " << globalIdx
-                                << ", coordinated: " << globalPos << ", sumxl: "
-                                << sumxl << std::endl;
-                        newPhasePresence = bothPhases;
-                        if (formulation == pgSl)
-                            globalSol[globalIdx][switchIdx] = 0.0;
-                        else if (formulation == plSg)
-                            globalSol[globalIdx][switchIdx] = 1.0;
-                    //Here unlike 2pnc model we do not switch all components to to mole fraction in gas phase
-                    }
-            }
-            else if (phasePresence == wPhaseOnly)
-            {
-                Scalar xgmax = 1;
-                Scalar sumxg = 0;
-                //Calculate sum of mole fractions in the hypothetical gas phase
-                for (int compIdx = 0; compIdx < numComponents; compIdx++)
-                {
-                    sumxg += volVars.moleFraction(nPhaseIdx, compIdx);
-                }
-                if (sumxg > xgmax)
-                    wouldSwitch = true;
-                if (this->staticDat_[globalIdx].wasSwitched)
-                    xgmax *=1.02;
-                //liquid phase appears if sum is larger than one
-                if (sumxg > xgmax)
-                {
-                    std::cout << "Gas Phase appears at vertex " << globalIdx
-                            << ", coordinated: " << globalPos << ", sumxg: "
-                            << sumxg << std::endl;
-                    newPhasePresence = bothPhases;
-                    //saturation of the liquid phase set to 0.9999 (if formulation pgSl and vice versa)
-                    if (formulation == pgSl)
-                        globalSol[globalIdx][switchIdx] = 0.999;
-                    else if (formulation == plSg)
-                        globalSol[globalIdx][switchIdx] = 0.001;
-
-                }
-            }
-            this->staticDat_[globalIdx].phasePresence = newPhasePresence;
-            this->staticDat_[globalIdx].wasSwitched = wouldSwitch;
-            return phasePresence != newPhasePresence;
-        }
-        // parameters given in constructor
-        bool switchFlag_;
-};
-
-}
-
-#include "2pncminpropertydefaults.hh"
+#include <dumux/porousmediumflow/2pncmin/implicit/model.hh>
 
 #endif
diff --git a/dumux/implicit/2pncmin/2pncminproperties.hh b/dumux/implicit/2pncmin/2pncminproperties.hh
index 9f410f690c..623b90b31e 100644
--- a/dumux/implicit/2pncmin/2pncminproperties.hh
+++ b/dumux/implicit/2pncmin/2pncminproperties.hh
@@ -1,65 +1,8 @@
-// -**- 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/>.   *
- *****************************************************************************/
-/*!
- * \ingroup Properties
- * \ingroup ImplicitProperties
- * \ingroup TwoPNCMinModel
- *
- * \file
- *
- * \brief Defines the properties required for the two-phase n-component mineralization
- *        fully implicit model.
- */
-#ifndef DUMUX_2PNCMIN_PROPERTIES_HH
-#define DUMUX_2PNCMIN_PROPERTIES_HH
+#ifndef DUMUX_2PNCMIN_PROPERTIES_HH_OLD
+#define DUMUX_2PNCMIN_PROPERTIES_HH_OLD
 
-#include <dumux/implicit/2pnc/2pncproperties.hh>
+#warning this header is deprecated, use dumux/porousmediumflow/2pncmin/implicit/properties.hh instead
 
-namespace Dumux
-{
-
-namespace Properties
-{
-//////////////////////////////////////////////////////////////////
-// Type tags
-//////////////////////////////////////////////////////////////////
-
-//! The type tag for the isothermal two phase n component mineralisation problems
-NEW_TYPE_TAG(TwoPNCMin, INHERITS_FROM(TwoPNC));
-NEW_TYPE_TAG(BoxTwoPNCMin, INHERITS_FROM(BoxModel, TwoPNCMin));
-NEW_TYPE_TAG(CCTwoPNCMin, INHERITS_FROM(CCModel, TwoPNCMin));
-
-//////////////////////////////////////////////////////////////////
-// Property tags
-//////////////////////////////////////////////////////////////////
-
-NEW_PROP_TAG(NumSPhases); //!< Number of solid phases in the system
-NEW_PROP_TAG(NumFSPhases); //!< Number of fluid and solid phases in the system
-NEW_PROP_TAG(NumSComponents); //!< Number of solid components in the system
-NEW_PROP_TAG(NumPSComponents); //!< Number of fluid and solid components in the system
-NEW_PROP_TAG(NumTraceComponents); //!< Number of trace fluid components which are not considered in the calculation of the phase density
-NEW_PROP_TAG(NumSecComponents); //!< Number of secondary components which are not primary variables
-NEW_PROP_TAG(TwoPNCMinIndices); //!< Enumerations for the 2pncMin models
-NEW_PROP_TAG(useSalinity); //!< Determines if salinity is used
-NEW_PROP_TAG(SpatialParamsForchCoeff); //!< Property for the forchheimer coefficient
-
-}
-}
+#include <dumux/porousmediumflow/2pncmin/implicit/properties.hh>
 
 #endif
diff --git a/dumux/implicit/2pncmin/2pncminpropertydefaults.hh b/dumux/implicit/2pncmin/2pncminpropertydefaults.hh
index 63a3b03439..64cf62f4b3 100644
--- a/dumux/implicit/2pncmin/2pncminpropertydefaults.hh
+++ b/dumux/implicit/2pncmin/2pncminpropertydefaults.hh
@@ -1,143 +1,8 @@
-// -**- 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/>.   *
- *****************************************************************************/
-/*!
- * \ingroup Properties
- * \ingroup ImplicitProperties
- * \ingroup TwoPNCMinModel
- * \file
- *
- * \brief Defines default values for most properties required by the
- *        two-phase n-component mineralization fully implicit model.
- */
-#ifndef DUMUX_2PNCMIN_PROPERTY_DEFAULTS_HH
-#define DUMUX_2PNCMIN_PROPERTY_DEFAULTS_HH
+#ifndef DUMUX_2PNCMIN_PROPERTY_DEFAULTS_HH_OLD
+#define DUMUX_2PNCMIN_PROPERTY_DEFAULTS_HH_OLD
 
-#include "2pncminindices.hh"
-#include "2pncminmodel.hh"
-#include "2pncminindices.hh"
-#include "2pncminfluxvariables.hh"
-#include "2pncminvolumevariables.hh"
-#include "2pncminproperties.hh"
+#warning this header is deprecated, use dumux/porousmediumflow/2pncmin/implicit/propertydefaults.hh instead
 
-#include <dumux/implicit/2pnc/2pncnewtoncontroller.hh>
-#include <dumux/porousmediumflow/implicit/darcyfluxvariables.hh>
-#include <dumux/material/spatialparams/implicitspatialparams.hh>
-
-namespace Dumux
-{
-
-namespace Properties {
-//////////////////////////////////////////////////////////////////
-// Property values
-//////////////////////////////////////////////////////////////////
-
-/*!
- * \brief Set the property for the number of secondary components.
- * Secondary components are components calculated from
- * primary components by equilibrium relations and
- * do not have mass balance equation on their own.
- * These components are important in the context of bio-mineralization applications.
- * We just forward the number from the fluid system
- *
- */
-SET_PROP(TwoPNCMin, NumSecComponents)
-{
-private:
-    typedef typename GET_PROP_TYPE(TypeTag, PTAG(FluidSystem)) FluidSystem;
-
-public:
-    static const int value = FluidSystem::numSecComponents;
-
-};
-/*!
- * \brief Set the property for the number of solid phases, excluding the non-reactive matrix.
- *
- * We just forward the number from the fluid system
- *
- */
-SET_PROP(TwoPNCMin, NumSPhases)
-{
-private:
-    typedef typename GET_PROP_TYPE(TypeTag, PTAG(FluidSystem)) FluidSystem;
-
-public:
-    static const int value = FluidSystem::numSPhases;
-};
-
-/*!
- * \brief Set the property for the number of equations.
- * For each component and each precipitated mineral/solid phase one equation has to
- * be solved.
- */
-SET_PROP(TwoPNCMin, NumEq)
-{
-private:
-    typedef typename GET_PROP_TYPE(TypeTag, PTAG(FluidSystem)) FluidSystem;
-
-public:
-    static const int value = FluidSystem::numComponents + FluidSystem::numSPhases;
-};
-
-/*!
- * \brief The fluid state which is used by the volume variables to
- *        store the thermodynamic state. This should be chosen
- *        appropriately for the model ((non-)isothermal, equilibrium, ...).
- *        This can be done in the problem.
- */
-SET_PROP(TwoPNCMin, FluidState){
-    private:
-        typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
-        typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
-    public:
-        typedef Dumux::CompositionalFluidState<Scalar, FluidSystem> type;
-};
-
-//! Use the 2pncmin local residual operator
-SET_TYPE_PROP(TwoPNCMin,
-              LocalResidual,
-              TwoPNCMinLocalResidual<TypeTag>);
-
-//! the Model property
-SET_TYPE_PROP(TwoPNCMin, Model, TwoPNCMinModel<TypeTag>);
-
-//! the VolumeVariables property
-SET_TYPE_PROP(TwoPNCMin, VolumeVariables, TwoPNCMinVolumeVariables<TypeTag>);
-
-//! the FluxVariables property
-SET_TYPE_PROP(TwoPNCMin, FluxVariables, TwoPNCMinFluxVariables<TypeTag>);
-
-//! The indices required by the isothermal 2pNcMin model
-SET_TYPE_PROP(TwoPNCMin, Indices, TwoPNCMinIndices <TypeTag, /*PVOffset=*/0>);
-
-//! disable useSalinity for the calculation of osmotic pressure by default
-SET_BOOL_PROP(TwoPNCMin, useSalinity, false);
-
-
-//! default value for the forchheimer coefficient
-// Source: Ward, J.C. 1964 Turbulent flow in porous media. ASCE J. Hydraul. Div 90.
-//        Actually the Forchheimer coefficient is also a function of the dimensions of the
-//        porous medium. Taking it as a constant is only a first approximation
-//        (Nield, Bejan, Convection in porous media, 2006, p. 10)
-SET_SCALAR_PROP(TwoPNCMin, SpatialParamsForchCoeff, 0.55);
-
-}
-
-}
+#include <dumux/porousmediumflow/2pncmin/implicit/propertydefaults.hh>
 
 #endif
diff --git a/dumux/implicit/2pncmin/2pncminvolumevariables.hh b/dumux/implicit/2pncmin/2pncminvolumevariables.hh
index 4e11fd1f48..1c31f964a2 100644
--- a/dumux/implicit/2pncmin/2pncminvolumevariables.hh
+++ b/dumux/implicit/2pncmin/2pncminvolumevariables.hh
@@ -1,549 +1,8 @@
-// -**- 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/>.   *
- *****************************************************************************/
-/*!
- * \file
- *
- * \brief Contains the quantities which are constant within a
- *        finite volume in the two-phase, n-component mineralization model.
- */
-#ifndef DUMUX_2PNCMin_VOLUME_VARIABLES_HH
-#define DUMUX_2PNCMin_VOLUME_VARIABLES_HH
+#ifndef DUMUX_2PNCMin_VOLUME_VARIABLES_HH_OLD
+#define DUMUX_2PNCMin_VOLUME_VARIABLES_HH_OLD
 
-#include <dumux/implicit/model.hh>
-#include <dumux/material/fluidstates/compositionalfluidstate.hh>
-#include <dumux/common/math.hh>
-#include <vector>
-#include <iostream>
+#warning this header is deprecated, use dumux/porousmediumflow/2pncmin/implicit/volumevariables.hh instead
 
-#include "2pncminproperties.hh"
-#include "2pncminindices.hh"
-#include <dumux/material/constraintsolvers/computefromreferencephase2pncmin.hh>
-#include <dumux/material/constraintsolvers/miscible2pnccomposition.hh>
-#include <dumux/implicit/2pnc/2pncvolumevariables.hh>
-
-namespace Dumux
-{
-
-/*!
- * \ingroup TwoPNCMinModel
- * \ingroup ImplicitVolumeVariables
- * \brief Contains the quantities which are are constant within a
- *        finite volume in the two-phase, n-component model.
- */
-template <class TypeTag>
-class TwoPNCMinVolumeVariables : public TwoPNCVolumeVariables<TypeTag>
-{
-    typedef TwoPNCVolumeVariables<TypeTag> ParentType;
-    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) Implementation;
-
-    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
-    typedef typename GET_PROP_TYPE(TypeTag, Grid) Grid;
-    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
-    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
-    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
-    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
-    typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw;
-    typedef typename GET_PROP_TYPE(TypeTag, MaterialLawParams) MaterialLawParams;
-    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
-
-    enum
-    {
-        dim = GridView::dimension,
-        dimWorld=GridView::dimensionworld,
-
-        numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
-        numSPhases =  GET_PROP_VALUE(TypeTag, NumSPhases),
-        numComponents = GET_PROP_VALUE(TypeTag, NumComponents),
-        numMajorComponents = GET_PROP_VALUE(TypeTag, NumMajorComponents),
-
-        // formulations
-        formulation = GET_PROP_VALUE(TypeTag, Formulation),
-        plSg = TwoPNCFormulation::plSg,
-        pgSl = TwoPNCFormulation::pgSl,
-
-        // phase indices
-        wPhaseIdx = FluidSystem::wPhaseIdx,
-        nPhaseIdx = FluidSystem::nPhaseIdx,
-
-        // component indices
-        wCompIdx = FluidSystem::wCompIdx,
-        nCompIdx = FluidSystem::nCompIdx,
-
-        // phase presence enums
-        nPhaseOnly = Indices::nPhaseOnly,
-        wPhaseOnly = Indices::wPhaseOnly,
-        bothPhases = Indices::bothPhases,
-
-        // primary variable indices
-        pressureIdx = Indices::pressureIdx,
-        switchIdx = Indices::switchIdx,
-
-        useSalinity = GET_PROP_VALUE(TypeTag, useSalinity)
-    };
-
-    typedef typename GridView::template Codim<0>::Entity Element;
-    typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition;
-    typedef typename Grid::ctype CoordScalar;
-    typedef Dumux::Miscible2pNCComposition<Scalar, FluidSystem> Miscible2pNCComposition;
-    typedef Dumux::ComputeFromReferencePhase2pNCMin<Scalar, FluidSystem> ComputeFromReferencePhase2pNCMin;
-
-    enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) };
-    enum { dofCodim = isBox ? dim : 0 };
-public:
-
-    typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState;
-
-    /*!
-     * \copydoc ImplicitVolumeVariables::update
-     */
-    void update(const PrimaryVariables &priVars,
-                const Problem &problem,
-                const Element &element,
-                const FVElementGeometry &fvGeometry,
-                int scvIdx,
-                bool isOldSol)
-    {
-        ParentType::update(priVars,
-                           problem,
-                           element,
-                           fvGeometry,
-                           scvIdx,
-                           isOldSol);
-
-        completeFluidState(priVars, problem, element, fvGeometry, scvIdx, this->fluidState_, isOldSol);
-
-    /////////////
-        // calculate the remaining quantities
-        /////////////
-
-    // porosity evaluation
-    initialPorosity_ = problem.spatialParams().porosity(element, fvGeometry, scvIdx);
-    minimumPorosity_ = problem.spatialParams().porosityMin(element, fvGeometry, scvIdx);
-
-
-    sumPrecipitates_ = 0.0;
-    for(int sPhaseIdx = 0; sPhaseIdx < numSPhases; ++sPhaseIdx)
-    {
-       precipitateVolumeFraction_[sPhaseIdx] = priVars[numComponents + sPhaseIdx];
-       sumPrecipitates_+= precipitateVolumeFraction_[sPhaseIdx];
-    }
-
-//         for(int sPhaseIdx = 0; sPhaseIdx < numSPhases; ++sPhaseIdx)
-//     {
-//         Chemistry chemistry; // the non static functions can not be called without abject
-//         saturationIdx_[sPhaseIdx] = chemistry.omega(sPhaseIdx);
-//     }
-// TODO/FIXME: The salt crust porosity is not clearly defined. However form literature review it is
-//    found that the salt crust have porosity of approx. 10 %. Thus we restrict the decrease in porosity
-//    to this limit. Moreover in the Problem files the precipitation should also be made dependent on local
-//    porosity value, as the porous media media properties change related to salt precipitation will not be
-//    accounted otherwise.
-
-//      this->porosity_ = initialPorosity_ - sumPrecipitates_;
-
-     this->porosity_ = std::max(minimumPorosity_, std::max(0.0, initialPorosity_ - sumPrecipitates_));
-
-   salinity_= 0.0;
-   moleFractionSalinity_ = 0.0;
-   for (int compIdx = numMajorComponents; compIdx< numComponents; compIdx++)    //sum of the mass fraction of the components
-   {
-       if(this->fluidState_.moleFraction(wPhaseIdx, compIdx)> 0)
-       {
-          salinity_+= this->fluidState_.massFraction(wPhaseIdx, compIdx);
-          moleFractionSalinity_ += this->fluidState_.moleFraction(wPhaseIdx, compIdx);
-       }
-    }
-
-// TODO/FIXME: Different relations for the porosoty-permeability changes are given here. We have to fins a way
-//    so that one can select the relation form the input file.
-
-    // kozeny-Carman relation
-    permeabilityFactor_  =  std::pow(((1-initialPorosity_)/(1-this->porosity_)),2)
-            * std::pow((this->porosity_/initialPorosity_),3);
-
-    // Verma-Pruess relation
-//  permeabilityFactor_  =  100 * std::pow(((this->porosity_/initialPorosity_)-0.9),2);
-
-    // Modified Fair-Hatch relation with final porosity set to 0.2 and E1=1
-//  permeabilityFactor_  =  std::pow((this->porosity_/initialPorosity_),3)
-//         * std::pow((std::pow((1 - initialPorosity_),2/3))+(std::pow((0.2 - initialPorosity_),2/3)),2)
-//         / std::pow((std::pow((1 -this->porosity_),2/3))+(std::pow((0.2 -this->porosity_),2/3)),2);
-
-    //Timur relation with residual water saturation set to 0.001
-//    permeabilityFactor_ =  0.136 * (std::pow(this->porosity_,4.4)) / (2000 * (std::pow(0.001,2)));
-
-    //Timur relation1 with residual water saturation set to 0.001
-//    permeabilityFactor_ =  0.136 * (std::pow(this->porosity_,4.4)) / (200000 * (std::pow(0.001,2)));
-
-
-    //Bern. relation
-   // permeabilityFactor_ = std::pow((this->porosity_/initialPorosity_),8);
-
-    //Tixier relation with residual water saturation set to 0.001
-    //permeabilityFactor_ = (std::pow((250 * (std::pow(this->porosity_,3)) / 0.001),2)) / initialPermeability_;
-
-    //Coates relation with residual water saturation set to 0.001
-    //permeabilityFactor_ = (std::pow((100 * (std::pow(this->porosity_,2)) * (1-0.001) / 0.001,2))) / initialPermeability_ ;
-
-
-    // energy related quantities not contained in the fluid state
-    //asImp_().updateEnergy_(priVars, problem,element, fvGeometry, scvIdx, isOldSol);
-    }
-
-   /*!
-    * \copydoc ImplicitModel::completeFluidState
-    * \param isOldSol Specifies whether this is the previous solution or the current one
-    */
-  static void completeFluidState(const PrimaryVariables& priVars,
-                                 const Problem& problem,
-                                 const Element& element,
-                                 const FVElementGeometry& fvGeometry,
-                                 int scvIdx,
-                                 FluidState& fluidState,
-                                 bool isOldSol = false)
-
-    {
-        Scalar t = Implementation::temperature_(priVars, problem, element,fvGeometry, scvIdx);
-        fluidState.setTemperature(t);
-
-        int dofIdxGlobal = problem.model().dofMapper().subIndex(element, scvIdx, dofCodim);
-        int phasePresence = problem.model().phasePresence(dofIdxGlobal, isOldSol);
-
-        /////////////
-        // set the saturations
-        /////////////
-
-        Scalar Sg;
-        if (phasePresence == nPhaseOnly)
-            Sg = 1.0;
-        else if (phasePresence == wPhaseOnly) {
-            Sg = 0.0;
-        }
-        else if (phasePresence == bothPhases) {
-            if (formulation == plSg)
-                Sg = priVars[switchIdx];
-            else if (formulation == pgSl)
-                Sg = 1.0 - priVars[switchIdx];
-            else DUNE_THROW(Dune::InvalidStateException, "Formulation: " << formulation << " is invalid.");
-        }
-        else DUNE_THROW(Dune::InvalidStateException, "phasePresence: " << phasePresence << " is invalid.");
-        fluidState.setSaturation(nPhaseIdx, Sg);
-        fluidState.setSaturation(wPhaseIdx, 1.0 - Sg);
-
-        /////////////
-        // set the pressures of the fluid phases
-        /////////////
-
-        // calculate capillary pressure
-        const MaterialLawParams &materialParams = problem.spatialParams().materialLawParams(element, fvGeometry, scvIdx);
-        Scalar pc = MaterialLaw::pc(materialParams, 1 - Sg);
-
-        // extract the pressures
-        if (formulation == plSg) {
-            fluidState.setPressure(wPhaseIdx, priVars[pressureIdx]);
-            fluidState.setPressure(nPhaseIdx, priVars[pressureIdx] + pc);
-        }
-        else if (formulation == pgSl) {
-            fluidState.setPressure(nPhaseIdx, priVars[pressureIdx]);
-            fluidState.setPressure(wPhaseIdx, priVars[pressureIdx] - pc);
-        }
-        else DUNE_THROW(Dune::InvalidStateException, "Formulation: " << formulation << " is invalid.");
-
-        /////////////
-        // calculate the phase compositions
-        /////////////
-
-    typename FluidSystem::ParameterCache paramCache;
-
-        // now comes the tricky part: calculate phase composition
-        if (phasePresence == bothPhases) {
-            // both phases are present, phase composition results from
-            // the gas <-> liquid equilibrium. This is
-            // the job of the "MiscibleMultiPhaseComposition"
-            // constraint solver
-
-            // set the known mole fractions in the fluidState so that they
-            // can be used by the Miscible2pNcComposition constraint solver
-            for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx)
-            {
-                fluidState.setMoleFraction(wPhaseIdx, compIdx, priVars[compIdx]);
-            }
-
-            Miscible2pNCComposition::solve(fluidState,
-                                            paramCache,
-                                            wPhaseIdx,  //known phaseIdx
-                                            /*setViscosity=*/true,
-                                            /*setInternalEnergy=*/false);
-        }
-        else if (phasePresence == nPhaseOnly){
-
-            Dune::FieldVector<Scalar, numComponents> moleFrac;
-            Dune::FieldVector<Scalar, numComponents> fugCoeffL;
-            Dune::FieldVector<Scalar, numComponents> fugCoeffG;
-
-            for (int compIdx=0; compIdx<numComponents; ++compIdx)
-            {
-                fugCoeffL[compIdx] = FluidSystem::fugacityCoefficient(fluidState,
-                                        paramCache,
-                                        wPhaseIdx,
-                                        compIdx);
-                fugCoeffG[compIdx] = FluidSystem::fugacityCoefficient(fluidState,
-                                        paramCache,
-                                        nPhaseIdx,
-                                        compIdx);
-            }
-            for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx)
-                moleFrac[compIdx] = (priVars[compIdx]*fugCoeffL[compIdx]*fluidState.pressure(wPhaseIdx))
-                /(fugCoeffG[compIdx]*fluidState.pressure(nPhaseIdx));
-
-            moleFrac[wCompIdx] =  priVars[switchIdx];
-            Scalar sumMoleFracNotGas = 0;
-            for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx)
-            {
-                    sumMoleFracNotGas+=moleFrac[compIdx];
-            }
-            sumMoleFracNotGas += moleFrac[wCompIdx];
-            moleFrac[nCompIdx] = 1 - sumMoleFracNotGas;
-
-//          typedef Dune::FieldMatrix<Scalar, numComponents, numComponents> Matrix;
-//          typedef Dune::FieldVector<Scalar, numComponents> Vector;
-
-
-            // Set fluid state mole fractions
-            for (int compIdx=0; compIdx<numComponents; ++compIdx)
-            {
-                fluidState.setMoleFraction(nPhaseIdx, compIdx, moleFrac[compIdx]);
-            }
-
-            // calculate the composition of the remaining phases (as
-            // well as the densities of all phases). this is the job
-            // of the "ComputeFromReferencePhase2pNc" constraint solver
-            ComputeFromReferencePhase2pNCMin::solve(fluidState,
-                                                    paramCache,
-                                                    nPhaseIdx,
-                                                    nPhaseOnly,
-                                                    /*setViscosity=*/true,
-                                                    /*setInternalEnergy=*/false);
-
-            }
-        else if (phasePresence == wPhaseOnly){
-
-        // only the liquid phase is present, i.e. liquid phase
-        // composition is stored explicitly.
-        // extract _mass_ fractions in the gas phase
-            Dune::FieldVector<Scalar, numComponents> moleFrac;
-
-            for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx)
-            {
-                moleFrac[compIdx] = priVars[compIdx];
-            }
-            moleFrac[nCompIdx] = priVars[switchIdx];
-            Scalar sumMoleFracNotWater = 0;
-            for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx)
-            {
-                    sumMoleFracNotWater+=moleFrac[compIdx];
-            }
-            sumMoleFracNotWater += moleFrac[nCompIdx];
-            moleFrac[wCompIdx] = 1 -sumMoleFracNotWater;
-
-//             convert mass to mole fractions and set the fluid state
-            for (int compIdx=0; compIdx<numComponents; ++compIdx)
-            {
-                fluidState.setMoleFraction(wPhaseIdx, compIdx, moleFrac[compIdx]);
-            }
-
-//             calculate the composition of the remaining phases (as
-//             well as the densities of all phases). this is the job
-//             of the "ComputeFromReferencePhase2pNc" constraint solver
-            ComputeFromReferencePhase2pNCMin::solve(fluidState,
-                                                    paramCache,
-                                                    wPhaseIdx,
-                                                    wPhaseOnly,
-                                                    /*setViscosity=*/true,
-                                                    /*setInternalEnergy=*/false);
-        }
-        paramCache.updateAll(fluidState);
-        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
-        {
-            Scalar h = Implementation::enthalpy_(fluidState, paramCache, phaseIdx);
-            fluidState.setEnthalpy(phaseIdx, h);
-        }
-    }
-    /*!
-     * \brief Returns the volume fraction of the precipitate (solid phase)
-     * for the given phaseIdx
-     *
-     * \param phaseIdx the index of the solid phase
-     */
-    Scalar precipitateVolumeFraction(int phaseIdx) const
-    { return precipitateVolumeFraction_[phaseIdx - numPhases]; }
-
-    /*!
-     * \brief Returns the inital porosity of the
-     * pure, precipitate-free porous medium
-     */
-    Scalar initialPorosity() const
-    { return initialPorosity_;}
-
-    /*!
-     * \brief Returns the inital permeability of the
-     * pure, precipitate-free porous medium
-     */
-    Scalar initialPermeability() const
-    { return initialPermeability_;}
-
-    /*!
-     * \brief Returns the factor for the reduction of the initial permeability
-     * due precipitates in the porous medium
-     */
-    Scalar permeabilityFactor() const
-    { return permeabilityFactor_; }
-
-//    /*!
-//     * \brief Returns the mole fraction of a component in the phase
-//     *
-//     * \param phaseIdx the index of the fluid phase
-//     * \param compIdx the index of the component
-//     */
-//    Scalar moleFraction(int phaseIdx, int compIdx) const
-//    {
-//       return this->fluidState_.moleFraction(phaseIdx, compIdx);
-//    }
-
-    /*!
-     * \brief Returns the mole fraction of the salinity in the liquid phase
-     */
-    Scalar moleFracSalinity() const
-    {
-        return moleFractionSalinity_;
-    }
-
-    /*!
-     * \brief Returns the salinity (mass fraction) in the liquid phase
-     */
-    Scalar salinity() const
-    {
-        return salinity_;
-    }
-
-    /*!
-     * \brief Returns the density of the phase for all fluid and solid phases
-     *
-     * \param phaseIdx the index of the fluid phase
-     */
-    Scalar density(int phaseIdx) const
-    {
-        if (phaseIdx < numPhases)
-            return this->fluidState_.density(phaseIdx);
-        else if (phaseIdx >= numPhases)
-            return FluidSystem::precipitateDensity(phaseIdx);
-        else
-            DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx);
-    }
-    /*!
-     * \brief Returns the mass density of a given phase within the
-     *        control volume.
-     *
-     * \param phaseIdx The phase index
-     */
-    Scalar molarDensity(int phaseIdx) const
-    {
-        if (phaseIdx < numPhases)
-            return this->fluidState_.molarDensity(phaseIdx);
-        else if (phaseIdx >= numPhases)
-            return FluidSystem::precipitateMolarDensity(phaseIdx);
-        else
-            DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx);
-    }
-
-    /*!
-     * \brief Returns the molality of a component in the phase
-     *
-     * \param phaseIdx the index of the fluid phase
-     * \param compIdx the index of the component
-     * molality=\frac{n_{component}}{m_{solvent}}
-     * =\frac{n_{component}}{n_{solvent}*M_{solvent}}
-     * compIdx of the main component (solvent) in the
-     * phase is equal to the phaseIdx
-     */
-     Scalar molality(int phaseIdx, int compIdx) const // [moles/Kg]
-    { return this->fluidState_.moleFraction(phaseIdx, compIdx)
-                  /(fluidState_.moleFraction(phaseIdx, phaseIdx)
-                  * FluidSystem::molarMass(phaseIdx));}
-
-protected:
-    friend class TwoPNCVolumeVariables<TypeTag>;
-    static Scalar temperature_(const PrimaryVariables &priVars,
-                                const Problem& problem,
-                                const Element &element,
-                                const FVElementGeometry &fvGeometry,
-                                int scvIdx)
-    {
-        return problem.temperatureAtPos(fvGeometry.subContVol[scvIdx].global);
-    }
-
-    template<class ParameterCache>
-    static Scalar enthalpy_(const FluidState& fluidState,
-                            const ParameterCache& paramCache,
-                            int phaseIdx)
-    {
-        return 0;
-    }
-
-   /*!
-    * \brief Update all quantities for a given control volume.
-    *
-    * \param priVars The solution primary variables
-    * \param problem The problem
-    * \param element The element
-    * \param fvGeometry Evaluate function with solution of current or previous time step
-    * \param scvIdx The local index of the SCV (sub-control volume)
-    * \param isOldSol Evaluate function with solution of current or previous time step
-    */
-        void updateEnergy_(const PrimaryVariables &priVars,
-                           const Problem &problem,
-                           const Element &element,
-                           const FVElementGeometry &fvGeometry,
-                           const int scvIdx,
-                           bool isOldSol)
-        { };
-
-    Scalar precipitateVolumeFraction_[numSPhases];
-//     Scalar saturationIdx_[numSPhases];
-    Scalar permeabilityFactor_;
-    Scalar initialPorosity_;
-    Scalar initialPermeability_;
-    Scalar minimumPorosity_;
-    Scalar sumPrecipitates_;
-    Scalar salinity_;
-    Scalar moleFractionSalinity_;
-    FluidState fluidState_;
-
-private:
-    Implementation &asImp_()
-    { return *static_cast<Implementation*>(this); }
-
-    const Implementation &asImp_() const
-    { return *static_cast<const Implementation*>(this); }
-};
-
-} // end namespace
+#include <dumux/porousmediumflow/2pncmin/implicit/volumevariables.hh>
 
 #endif
diff --git a/dumux/implicit/3p3c/3p3cfluxvariables.hh b/dumux/implicit/3p3c/3p3cfluxvariables.hh
index f3c3d62d8d..25830baebb 100644
--- a/dumux/implicit/3p3c/3p3cfluxvariables.hh
+++ b/dumux/implicit/3p3c/3p3cfluxvariables.hh
@@ -1,386 +1,8 @@
-// -*- 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/>.   *
- *****************************************************************************/
-/*!
- * \file
- * \brief This file contains the data which is required to calculate
- *        all fluxes of components over a face of a finite volume for
- *        the three-phase three-component model.
- */
-#ifndef DUMUX_3P3C_FLUX_VARIABLES_HH
-#define DUMUX_3P3C_FLUX_VARIABLES_HH
+#ifndef DUMUX_3P3C_FLUX_VARIABLES_HH_OLD
+#define DUMUX_3P3C_FLUX_VARIABLES_HH_OLD
 
-#include <dumux/common/math.hh>
-#include <dumux/common/spline.hh>
+#warning this header is deprecated, use dumux/porousmediumflow/3p3c/implicit/fluxvariables.hh instead
 
-#include "3p3cproperties.hh"
-
-namespace Dumux
-{
-
-/*!
- * \ingroup ThreePThreeCModel
- * \ingroup ImplicitFluxVariables
- * \brief This template class contains the data which is required to
- *        calculate all fluxes of components over a face of a finite
- *        volume for the three-phase three-component model.
- *
- * This means pressure and concentration gradients, phase densities at
- * the integration point, etc.
- */
-template <class TypeTag>
-class ThreePThreeCFluxVariables : public GET_PROP_TYPE(TypeTag, BaseFluxVariables)
-{
-    typedef typename GET_PROP_TYPE(TypeTag, BaseFluxVariables) BaseFluxVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
-    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
-
-    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
-    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
-
-    typedef typename GridView::template Codim<0>::Entity Element;
-    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, EffectiveDiffusivityModel) EffectiveDiffusivityModel;
-
-    enum {
-        dim = GridView::dimension,
-        dimWorld = GridView::dimensionworld,
-        numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
-        numComponents = GET_PROP_VALUE(TypeTag, NumComponents)
-    };
-
-    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
-
-    typedef Dune::FieldVector<Scalar, dim>  DimVector;
-    typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition;
-
-    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
-    enum {
-        wPhaseIdx = Indices::wPhaseIdx,
-        nPhaseIdx = Indices::nPhaseIdx,
-        gPhaseIdx = Indices::gPhaseIdx,
-
-        wCompIdx = Indices::wCompIdx,
-        nCompIdx = Indices::nCompIdx,
-        gCompIdx = Indices::gCompIdx
-    };
-
-public:
-    /*!
-     * \brief The constructor
-     *
-     * \param problem The problem
-     * \param element The finite element
-     * \param fvGeometry The finite-volume geometry in the fully implicit scheme
-     * \param fIdx The local index of the SCV (sub-control-volume) face
-     * \param elemVolVars The volume variables of the current element
-     * \param onBoundary Evaluate flux at inner sub-control-volume face or on a boundary face
-     */
-    ThreePThreeCFluxVariables(const Problem &problem,
-                              const Element &element,
-                              const FVElementGeometry &fvGeometry,
-                              const int fIdx,
-                              const ElementVolumeVariables &elemVolVars,
-                              const bool onBoundary = false)
-    : BaseFluxVariables(problem, element, fvGeometry, fIdx, elemVolVars, onBoundary)
-    {
-        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
-            density_[phaseIdx] = Scalar(0);
-            molarDensity_[phaseIdx] = Scalar(0);
-            massFractionCompWGrad_[phaseIdx] = Scalar(0);
-            massFractionCompNGrad_[phaseIdx] = Scalar(0);
-            massFractionCompGGrad_[phaseIdx] = Scalar(0);
-            moleFractionCompWGrad_[phaseIdx] = Scalar(0);
-            moleFractionCompNGrad_[phaseIdx] = Scalar(0);
-            moleFractionCompGGrad_[phaseIdx] = Scalar(0);
-        }
-
-        calculateGradients_(problem, element, elemVolVars);
-        calculatePorousDiffCoeff_(problem, element, elemVolVars);
-    };
-
-private:
-    void calculateGradients_(const Problem &problem,
-                             const Element &element,
-                             const ElementVolumeVariables &elemVolVars)
-    {
-        // calculate gradients
-        GlobalPosition tmp(0.0);
-        for (unsigned int idx = 0;
-             idx < this->face().numFap;
-             idx++) // loop over adjacent vertices
-        {
-            // FE gradient at vertex idx
-            const GlobalPosition &feGrad = this->face().grad[idx];
-
-            // index for the element volume variables
-            int volVarsIdx = this->face().fapIndices[idx];
-
-            // the concentration gradient of the components
-            // component in the phases
-            tmp = feGrad;
-            tmp *= elemVolVars[volVarsIdx].massFraction(wPhaseIdx, wCompIdx);
-            massFractionCompWGrad_[wPhaseIdx] += tmp;
-
-            tmp = feGrad;
-            tmp *= elemVolVars[volVarsIdx].massFraction(nPhaseIdx, wCompIdx);
-            massFractionCompWGrad_[nPhaseIdx] += tmp;
-
-            tmp = feGrad;
-            tmp *= elemVolVars[volVarsIdx].massFraction(gPhaseIdx, wCompIdx);
-            massFractionCompWGrad_[gPhaseIdx] += tmp;
-
-            tmp = feGrad;
-            tmp *= elemVolVars[volVarsIdx].massFraction(wPhaseIdx, nCompIdx);
-            massFractionCompNGrad_[wPhaseIdx] += tmp;
-
-            tmp = feGrad;
-            tmp *= elemVolVars[volVarsIdx].massFraction(nPhaseIdx, nCompIdx);
-            massFractionCompNGrad_[nPhaseIdx] += tmp;
-
-            tmp = feGrad;
-            tmp *= elemVolVars[volVarsIdx].massFraction(gPhaseIdx, nCompIdx);
-            massFractionCompNGrad_[gPhaseIdx] += tmp;
-
-            tmp = feGrad;
-            tmp *= elemVolVars[volVarsIdx].massFraction(wPhaseIdx, gCompIdx);
-            massFractionCompGGrad_[wPhaseIdx] += tmp;
-
-            tmp = feGrad;
-            tmp *= elemVolVars[volVarsIdx].massFraction(nPhaseIdx, gCompIdx);
-            massFractionCompGGrad_[nPhaseIdx] += tmp;
-
-            tmp = feGrad;
-            tmp *= elemVolVars[volVarsIdx].massFraction(gPhaseIdx, gCompIdx);
-            massFractionCompGGrad_[gPhaseIdx] += tmp;
-
-            // the molar concentration gradients of the components
-            // in the phases
-            tmp = feGrad;
-            tmp *= elemVolVars[volVarsIdx].moleFraction(wPhaseIdx, wCompIdx);
-            moleFractionCompWGrad_[wPhaseIdx] += tmp;
-
-            tmp = feGrad;
-            tmp *= elemVolVars[volVarsIdx].moleFraction(nPhaseIdx, wCompIdx);
-            moleFractionCompWGrad_[nPhaseIdx] += tmp;
-
-            tmp = feGrad;
-            tmp *= elemVolVars[volVarsIdx].moleFraction(gPhaseIdx, wCompIdx);
-            moleFractionCompWGrad_[gPhaseIdx] += tmp;
-
-            tmp = feGrad;
-            tmp *= elemVolVars[volVarsIdx].moleFraction(wPhaseIdx, nCompIdx);
-            moleFractionCompNGrad_[wPhaseIdx] += tmp;
-
-            tmp = feGrad;
-            tmp *= elemVolVars[volVarsIdx].moleFraction(nPhaseIdx, nCompIdx);
-            moleFractionCompNGrad_[nPhaseIdx] += tmp;
-
-            tmp = feGrad;
-            tmp *= elemVolVars[volVarsIdx].moleFraction(gPhaseIdx, nCompIdx);
-            moleFractionCompNGrad_[gPhaseIdx] += tmp;
-
-            tmp = feGrad;
-            tmp *= elemVolVars[volVarsIdx].moleFraction(wPhaseIdx, gCompIdx);
-            moleFractionCompGGrad_[wPhaseIdx] += tmp;
-
-            tmp = feGrad;
-            tmp *= elemVolVars[volVarsIdx].moleFraction(nPhaseIdx, gCompIdx);
-            moleFractionCompGGrad_[nPhaseIdx] += tmp;
-
-            tmp = feGrad;
-            tmp *= elemVolVars[volVarsIdx].moleFraction(gPhaseIdx, gCompIdx);
-            moleFractionCompGGrad_[gPhaseIdx] += tmp;
-        }
-    }
-
-    Scalar rhoFactor_(int phaseIdx, int scvIdx, const ElementVolumeVariables &elemVolVars)
-    {
-        static const Scalar eps = 1e-2;
-        const Scalar sat = elemVolVars[scvIdx].density(phaseIdx);
-        if (sat > eps)
-            return 0.5;
-        if (sat <= 0)
-            return 0;
-
-        static const Dumux::Spline<Scalar> sp(0, eps, // x0, x1
-                                              0, 0.5, // y0, y1
-                                              0, 0); // m0, m1
-        return sp.eval(sat);
-    }
-
-    void calculatePorousDiffCoeff_(const Problem &problem,
-                               const Element &element,
-                               const ElementVolumeVariables &elemVolVars)
-    {
-
-        const VolumeVariables &volVarsI = elemVolVars[this->face().i];
-        const VolumeVariables &volVarsJ = elemVolVars[this->face().j];
-
-        Dune::FieldMatrix<Scalar, numPhases, numComponents> diffusionCoefficientMatrix_i = volVarsI.diffusionCoefficient();
-        Dune::FieldMatrix<Scalar, numPhases, numComponents> diffusionCoefficientMatrix_j = volVarsJ.diffusionCoefficient();
-
-        // the effective diffusion coefficients at vertex i and j
-        Scalar diffCoeffI;
-        Scalar diffCoeffJ;
-
-        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
-        {
-            // make sure to calculate only diffusion coefficents
-            // for phases which exist in both finite volumes
-            /* \todo take care: This should be discussed once again
-             * as long as a meaningful value can be found for the required mole fraction
-             * diffusion should work even without this one here */
-            if (volVarsI.saturation(phaseIdx) <= 0 ||
-                volVarsJ.saturation(phaseIdx) <= 0)
-            {
-                porousDiffCoeff_[phaseIdx][wCompIdx] = 0.0;
-                porousDiffCoeff_[phaseIdx][nCompIdx] = 0.0;
-                porousDiffCoeff_[phaseIdx][gCompIdx] = 0.0;
-                continue;
-            }
-
-            // Diffusion coefficient in the porous medium
-            diffCoeffI = EffectiveDiffusivityModel::effectiveDiffusivity(volVarsI.porosity(),
-                                                                         volVarsI.saturation(phaseIdx),
-                                                                         diffusionCoefficientMatrix_i[phaseIdx][wCompIdx]);
-            diffCoeffJ = EffectiveDiffusivityModel::effectiveDiffusivity(volVarsJ.porosity(),
-                                                                         volVarsJ.saturation(phaseIdx),
-                                                                         diffusionCoefficientMatrix_j[phaseIdx][wCompIdx]);
-
-            // -> harmonic mean
-            porousDiffCoeff_[phaseIdx][wCompIdx] = harmonicMean(diffCoeffI, diffCoeffJ);
-
-            // Diffusion coefficient in the porous medium
-            diffCoeffI = EffectiveDiffusivityModel::effectiveDiffusivity(volVarsI.porosity(),
-                                                                         volVarsI.saturation(phaseIdx),
-                                                                         diffusionCoefficientMatrix_i[phaseIdx][nCompIdx]);
-            diffCoeffJ = EffectiveDiffusivityModel::effectiveDiffusivity(volVarsJ.porosity(),
-                                                                         volVarsJ.saturation(phaseIdx),
-                                                                         diffusionCoefficientMatrix_j[phaseIdx][nCompIdx]);
-
-            // -> harmonic mean
-            porousDiffCoeff_[phaseIdx][nCompIdx] = harmonicMean(diffCoeffI, diffCoeffJ);
-
-            // Diffusion coefficient in the porous medium
-            diffCoeffI = EffectiveDiffusivityModel::effectiveDiffusivity(volVarsI.porosity(),
-                                                                         volVarsI.saturation(phaseIdx),
-                                                                         diffusionCoefficientMatrix_i[phaseIdx][gCompIdx]);
-            diffCoeffJ = EffectiveDiffusivityModel::effectiveDiffusivity(volVarsJ.porosity(),
-                                                                         volVarsJ.saturation(phaseIdx),
-                                                                         diffusionCoefficientMatrix_j[phaseIdx][gCompIdx]);
-
-            // -> harmonic mean
-            porousDiffCoeff_[phaseIdx][gCompIdx] = harmonicMean(diffCoeffI, diffCoeffJ);
-        }
-    }
-
-public:
-    /*!
-     * \brief The diffusivity matrix
-     *
-     * \tparam Scalar Field type
-     * \tparam numPhases The number of phases of the problem
-     * \tparam numComponents The number of components of the problem
-     */
-    Dune::FieldMatrix<Scalar, numPhases, numComponents> porousDiffCoeff() const
-    { return porousDiffCoeff_; };
-
-    /*!
-     * \brief Return density \f$\mathrm{[kg/m^3]}\f$ of a phase.
-     *
-     * \param phaseIdx The phase index
-     */
-    Scalar density(int phaseIdx) const
-    { return density_[phaseIdx]; }
-
-    /*!
-     * \brief Return molar density \f$\mathrm{[mol/m^3]}\f$ of a phase.
-     *
-     * \param phaseIdx The phase index
-     */
-    Scalar molarDensity(int phaseIdx) const
-    { return molarDensity_[phaseIdx]; }
-
-    /*!
-     * \brief The mass fraction gradient of the water in a phase.
-     *
-     * \param phaseIdx The phase index
-     */
-    const GlobalPosition &massFractionCompWGrad(int phaseIdx) const
-    {return massFractionCompWGrad_[phaseIdx];}
-
-    /*!
-     * \brief The mass fraction gradient of the contaminant in a phase.
-     *
-     * \param phaseIdx The phase index
-     */
-    const GlobalPosition &massFractionCompNGrad(int phaseIdx) const
-    { return massFractionCompNGrad_[phaseIdx]; };
-
-    /*!
-     * \brief The mass fraction gradient of gas in a phase.
-     *
-     * \param phaseIdx The phase index
-     */
-    const GlobalPosition &massFractionCompGGrad(int phaseIdx) const
-    { return massFractionCompGGrad_[phaseIdx]; };
-
-    /*!
-     * \brief The mole fraction gradient of the water in a phase.
-     *
-     * \param phaseIdx The phase index
-     */
-    const GlobalPosition &moleFractionCompWGrad(int phaseIdx) const
-    { return moleFractionCompWGrad_[phaseIdx]; };
-
-    /*!
-     * \brief The mole fraction gradient of the contaminant in a phase.
-     *
-     * \param phaseIdx The phase index
-     */
-    const GlobalPosition &moleFractionCompNGrad(int phaseIdx) const
-    { return moleFractionCompNGrad_[phaseIdx]; };
-
-    /*!
-     * \brief The mole fraction gradient of gas in a phase.
-     *
-     * \param phaseIdx The phase index
-     */
-    const GlobalPosition &moleFractionCompGGrad(int phaseIdx) const
-    { return moleFractionCompGGrad_[phaseIdx]; };
-
-protected:
-    // gradients
-    GlobalPosition massFractionCompWGrad_[numPhases];
-    GlobalPosition massFractionCompNGrad_[numPhases];
-    GlobalPosition massFractionCompGGrad_[numPhases];
-    GlobalPosition moleFractionCompWGrad_[numPhases];
-    GlobalPosition moleFractionCompNGrad_[numPhases];
-    GlobalPosition moleFractionCompGGrad_[numPhases];
-
-    // density of each face at the integration point
-    Scalar density_[numPhases], molarDensity_[numPhases];
-
-    // the diffusivity matrix for the porous medium
-    Dune::FieldMatrix<Scalar, numPhases, numComponents> porousDiffCoeff_;
-};
-
-} // end namespace
+#include <dumux/porousmediumflow/3p3c/implicit/fluxvariables.hh>
 
 #endif
diff --git a/dumux/implicit/3p3c/3p3cindices.hh b/dumux/implicit/3p3c/3p3cindices.hh
index e203747f7c..74f9ed7cd8 100644
--- a/dumux/implicit/3p3c/3p3cindices.hh
+++ b/dumux/implicit/3p3c/3p3cindices.hh
@@ -1,90 +1,8 @@
-// -*- 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/>.   *
- *****************************************************************************/
-/*!
- * \file
- * \brief Defines the indices required for the three-phase three-component
- *        fully implicit model.
- */
-#ifndef DUMUX_3P3C_INDICES_HH
-#define DUMUX_3P3C_INDICES_HH
+#ifndef DUMUX_3P3C_INDICES_HH_OLD
+#define DUMUX_3P3C_INDICES_HH_OLD
 
-#include "3p3cproperties.hh"
+#warning this header is deprecated, use dumux/porousmediumflow/3p3c/implicit/indices.hh instead
 
-namespace Dumux
-{
-
-/*!
- * \ingroup ThreePThreeCModel
- * \ingroup ImplicitIndices
- * \brief The indices for the isothermal three-phase three-component model.
- *
- * \tparam formulation The formulation, only pgSwSn is available.
- * \tparam PVOffset The first index in a primary variable vector.
- */
-template <class TypeTag, int PVOffset = 0>
-class ThreePThreeCIndices
-{
-    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
-
-public:
-    // Phase indices
-    static const int wPhaseIdx = FluidSystem::wPhaseIdx; //!< index of the wetting liquid phase
-    static const int nPhaseIdx = FluidSystem::nPhaseIdx; //!< index of the nonwetting liquid phase
-    static const int gPhaseIdx = FluidSystem::gPhaseIdx; //!< index of the gas phase
-
-    // Component indices to indicate the main component
-    // of the corresponding phase at atmospheric pressure 1 bar
-    // and room temperature 20°C:
-    static const int wCompIdx = FluidSystem::wCompIdx;
-    static const int nCompIdx = FluidSystem::nCompIdx;
-    static const int gCompIdx = FluidSystem::gCompIdx;
-
-    // present phases (-> 'pseudo' primary variable)
-    static const int threePhases = 1; //!< All three phases are present
-    static const int wPhaseOnly = 2; //!< Only the water phase is present
-    static const int gnPhaseOnly = 3; //!< Only gas and NAPL phases are present
-    static const int wnPhaseOnly = 4; //!< Only water and NAPL phases are present
-    static const int gPhaseOnly = 5; //!< Only gas phase is present
-    static const int wgPhaseOnly = 6; //!< Only water and gas phases are present
-
-    // Primary variable indices
-    static const int pressureIdx = PVOffset + 0; //!< Index for gas phase pressure in a solution vector
-    static const int switch1Idx = PVOffset + 1; //!< Index 1 of saturation or mole fraction
-    static const int switch2Idx = PVOffset + 2; //!< Index 2 of saturation or mole fraction
-
-    //! Index for gas phase pressure in a solution vector
-    static const int pgIdx = pressureIdx;
-    //! Index of either the saturation of the wetting phase or the mole fraction secondary component if a phase is not present
-    static const int sOrX1Idx = switch1Idx;
-    //! Index of either the saturation of the nonwetting phase or the mole fraction secondary component if a phase is not present
-    static const int sOrX2Idx = switch2Idx;
-
-    // equation indices
-    static const int conti0EqIdx = PVOffset    + wCompIdx; //!< Index of the mass conservation equation for the water component
-    static const int conti1EqIdx = conti0EqIdx + nCompIdx; //!< Index of the mass conservation equation for the contaminant component
-    static const int conti2EqIdx = conti0EqIdx + gCompIdx; //!< Index of the mass conservation equation for the gas component
-
-    static const int contiWEqIdx = conti0EqIdx + wCompIdx; //!< index of the mass conservation equation for the water component
-    static const int contiNEqIdx = conti0EqIdx + nCompIdx; //!< index of the mass conservation equation for the contaminant component
-    static const int contiGEqIdx = conti0EqIdx + gCompIdx; //!< index of the mass conservation equation for the air component
-};
-
-}
+#include <dumux/porousmediumflow/3p3c/implicit/indices.hh>
 
 #endif
diff --git a/dumux/implicit/3p3c/3p3clocalresidual.hh b/dumux/implicit/3p3c/3p3clocalresidual.hh
index e1abefc1e8..29a4ac9e7f 100644
--- a/dumux/implicit/3p3c/3p3clocalresidual.hh
+++ b/dumux/implicit/3p3c/3p3clocalresidual.hh
@@ -1,238 +1,8 @@
-// -*- 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/>.   *
- *****************************************************************************/
-/*!
- * \file
- *
- * \brief Element-wise calculation of the Jacobian matrix for problems
- *        using the three-phase three-component fully implicit model.
- */
-#ifndef DUMUX_3P3C_LOCAL_RESIDUAL_HH
-#define DUMUX_3P3C_LOCAL_RESIDUAL_HH
+#ifndef DUMUX_3P3C_LOCAL_RESIDUAL_HH_OLD
+#define DUMUX_3P3C_LOCAL_RESIDUAL_HH_OLD
 
-#include "3p3cproperties.hh"
+#warning this header is deprecated, use dumux/porousmediumflow/3p3c/implicit/localresidual.hh instead
 
-namespace Dumux
-{
-/*!
- * \ingroup ThreePThreeCModel
- * \ingroup ImplicitLocalResidual
- * \brief Element-wise calculation of the Jacobian matrix for problems
- *        using the three-phase three-component fully implicit model.
- *
- * This class is used to fill the gaps in BoxLocalResidual for the 3P3C flow.
- */
-template<class TypeTag>
-class ThreePThreeCLocalResidual: public GET_PROP_TYPE(TypeTag, BaseLocalResidual)
-{
-protected:
-    typedef typename GET_PROP_TYPE(TypeTag, LocalResidual) Implementation;
-
-    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
-    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
-
-    enum {
-        numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
-        numComponents = GET_PROP_VALUE(TypeTag, NumComponents),
-
-        conti0EqIdx = Indices::conti0EqIdx,//!< Index of the mass conservation equation for the water component
-        conti1EqIdx = Indices::conti1EqIdx,//!< Index of the mass conservation equation for the contaminant component
-        conti2EqIdx = Indices::conti2EqIdx,//!< Index of the mass conservation equation for the gas component
-
-        wPhaseIdx = Indices::wPhaseIdx,
-        nPhaseIdx = Indices::nPhaseIdx,
-        gPhaseIdx = Indices::gPhaseIdx,
-
-        wCompIdx = Indices::wCompIdx,
-        nCompIdx = Indices::nCompIdx,
-        gCompIdx = Indices::gCompIdx
-    };
-
-    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables;
-
-public:
-    /*!
-     * \brief Evaluate the amount of all conservation quantities
-     *        (e.g. phase mass) within a sub-control volume.
-     *
-     * The result should be averaged over the volume (e.g. phase mass
-     * inside a sub control volume divided by the volume)
-     *
-     *  \param storage The mass of the component within the sub-control volume
-     *  \param scvIdx The SCV (sub-control-volume) index
-     *  \param usePrevSol Evaluate function with solution of current or previous time step
-     */
-    void computeStorage(PrimaryVariables &storage, const int scvIdx, bool usePrevSol) const
-    {
-        // 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 &elemVolVars =
-            usePrevSol
-            ? this->prevVolVars_()
-            : this->curVolVars_();
-        const VolumeVariables &volVars = elemVolVars[scvIdx];
-
-        // compute storage term of all components within all phases
-        storage = 0;
-        for (int compIdx = 0; compIdx < numComponents; ++compIdx)
-        {
-            for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
-            {
-                storage[conti0EqIdx + compIdx] +=
-                    volVars.porosity()
-                    * volVars.saturation(phaseIdx)
-                    * volVars.molarDensity(phaseIdx)
-                    * volVars.moleFraction(phaseIdx, compIdx);
-            }
-        }
-    }
-
-    /*!
-     * \brief Evaluates the total flux of all conservation quantities
-     *        over a face of a sub-control volume.
-     *
-     * \param flux The flux over the SCV (sub-control-volume) face for each component
-     * \param fIdx The index of the SCV face
-     * \param onBoundary A boolean variable to specify whether the flux variables
-     *        are calculated for interior SCV faces or boundary faces, default=false
-     */
-    void computeFlux(PrimaryVariables &flux, const int fIdx, const bool onBoundary=false) const
-    {
-        FluxVariables fluxVars(this->problem_(),
-                           this->element_(),
-                           this->fvGeometry_(),
-                           fIdx,
-                           this->curVolVars_(),
-                           onBoundary);
-
-        flux = 0;
-        asImp_()->computeAdvectiveFlux(flux, fluxVars);
-        asImp_()->computeDiffusiveFlux(flux, fluxVars);
-    }
-
-    /*!
-     * \brief Evaluates the advective mass flux of all components over
-     *        a face of a subcontrol volume.
-     *
-     * \param flux The advective flux over the sub-control-volume face for each component
-     * \param fluxVars The flux variables at the current SCV
-     */
-
-    void computeAdvectiveFlux(PrimaryVariables &flux, const FluxVariables &fluxVars) const
-    {
-        Scalar massUpwindWeight = GET_PARAM_FROM_GROUP(TypeTag, Scalar, Implicit, MassUpwindWeight);
-
-        ////////
-        // advective fluxes of all components in all phases
-        ////////
-        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
-        {
-            // data attached to upstream and the downstream vertices
-            // of the current phase
-            const VolumeVariables &up = this->curVolVars_(fluxVars.upstreamIdx(phaseIdx));
-            const VolumeVariables &dn = this->curVolVars_(fluxVars.downstreamIdx(phaseIdx));
-
-            for (int compIdx = 0; compIdx < numComponents; ++compIdx)
-            {
-                // add advective flux of current component in current
-                // phase
-                // if alpha > 0 and alpha < 1 then both upstream and downstream
-                // nodes need their contribution
-                // if alpha == 1 (which is mostly the case) then, the downstream
-                // node is not evaluated
-                int eqIdx = conti0EqIdx + compIdx;
-                flux[eqIdx] += fluxVars.volumeFlux(phaseIdx)
-                    * (massUpwindWeight
-                       * up.molarDensity(phaseIdx)
-                       * up.moleFraction(phaseIdx, compIdx)
-                       +
-                       (1.0 - massUpwindWeight)
-                       * dn.molarDensity(phaseIdx)
-                       * dn.moleFraction(phaseIdx, compIdx));
-            }
-        }
-    }
-
-    /*!
-     * \brief Adds the diffusive mass flux of all components over
-     *        a face of a subcontrol volume.
-     *
-     * \param flux The diffusive flux over the sub-control-volume face for each component
-     * \param fluxVars The flux variables at the current SCV
-     */
-
-    void computeDiffusiveFlux(PrimaryVariables &flux, const FluxVariables &fluxVars) const
-    {
-        // TODO: reference!?  Dune::FieldMatrix<Scalar, numPhases, numComponents> averagedPorousDiffCoeffMatrix = fluxVars.porousDiffCoeff();
-        // add diffusive flux of gas component in liquid phase
-        Scalar tmp = - fluxVars.porousDiffCoeff()[wPhaseIdx][gCompIdx] * fluxVars.molarDensity(wPhaseIdx);
-        tmp *= (fluxVars.moleFractionCompGGrad(wPhaseIdx) * fluxVars.face().normal);
-        Scalar jGW = tmp;
-
-        tmp = - fluxVars.porousDiffCoeff()[wPhaseIdx][nCompIdx] * fluxVars.molarDensity(wPhaseIdx);
-        tmp *= (fluxVars.moleFractionCompNGrad(wPhaseIdx) * fluxVars.face().normal);
-        Scalar jNW = tmp;
-
-        Scalar jWW = -(jGW+jNW);
-
-        tmp = - fluxVars.porousDiffCoeff()[gPhaseIdx][wCompIdx] * fluxVars.molarDensity(gPhaseIdx);
-        tmp *= (fluxVars.moleFractionCompWGrad(gPhaseIdx) * fluxVars.face().normal);
-        Scalar jWG = tmp;
-
-        tmp = - fluxVars.porousDiffCoeff()[gPhaseIdx][nCompIdx] * fluxVars.molarDensity(gPhaseIdx);
-        tmp *= (fluxVars.moleFractionCompNGrad(gPhaseIdx) * fluxVars.face().normal);
-        Scalar jNG = tmp;
-
-        Scalar jGG = -(jWG+jNG);
-
-        tmp = - fluxVars.porousDiffCoeff()[nPhaseIdx][wCompIdx] * fluxVars.molarDensity(nPhaseIdx);
-        tmp *= (fluxVars.moleFractionCompWGrad(nPhaseIdx) * fluxVars.face().normal);
-        Scalar jWN = tmp;
-
-        tmp = - fluxVars.porousDiffCoeff()[nPhaseIdx][gCompIdx] * fluxVars.molarDensity(nPhaseIdx);
-        tmp *= (fluxVars.moleFractionCompGGrad(nPhaseIdx) * fluxVars.face().normal);
-        Scalar jGN = tmp;
-
-        Scalar jNN = -(jGN+jWN);
-
-        flux[conti0EqIdx] += jWW+jWG+jWN;
-        flux[conti1EqIdx] += jNW+jNG+jNN;
-        flux[conti2EqIdx] += jGW+jGG+jGN;
-    }
-
-protected:
-    Implementation *asImp_()
-    {
-        return static_cast<Implementation *> (this);
-    }
-
-    const Implementation *asImp_() const
-    {
-        return static_cast<const Implementation *> (this);
-    }
-};
-
-} // end namespace
+#include <dumux/porousmediumflow/3p3c/implicit/localresidual.hh>
 
 #endif
diff --git a/dumux/implicit/3p3c/3p3cmodel.hh b/dumux/implicit/3p3c/3p3cmodel.hh
index dacdf5d80b..faaca36f3a 100644
--- a/dumux/implicit/3p3c/3p3cmodel.hh
+++ b/dumux/implicit/3p3c/3p3cmodel.hh
@@ -1,1020 +1,8 @@
-// -*- 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/>.   *
- *****************************************************************************/
-/*!
- * \file
- *
- * \brief Adaption of the fully implicit scheme to the three-phase three-component
- *        flow model.
- *
- * The model is designed for simulating three fluid phases with water, gas, and
- * a liquid contaminant (NAPL - non-aqueous phase liquid)
- */
-#ifndef DUMUX_3P3C_MODEL_HH
-#define DUMUX_3P3C_MODEL_HH
+#ifndef DUMUX_3P3C_MODEL_HH_OLD
+#define DUMUX_3P3C_MODEL_HH_OLD
 
-#include <dumux/porousmediumflow/implicit/velocityoutput.hh>
-#include "3p3cproperties.hh"
+#warning this header is deprecated, use dumux/porousmediumflow/3p3c/implicit/model.hh instead
 
-namespace Dumux
-{
-/*!
- * \ingroup ThreePThreeCModel
- * \brief Adaption of the fully implicit scheme to the three-phase three-component
- *        flow model.
- *
- * This model implements three-phase three-component flow of three fluid phases
- * \f$\alpha \in \{ water, gas, NAPL \}\f$ each composed of up to three components
- * \f$\kappa \in \{ water, air, contaminant \}\f$. The standard multiphase Darcy
- * approach is used as the equation for the conservation of momentum:
- * \f[
- v_\alpha = - \frac{k_{r\alpha}}{\mu_\alpha} \mathbf{K}
- \left(\textbf{grad}\, p_\alpha - \varrho_{\alpha} \mbox{\bf g} \right)
- * \f]
- *
- * By inserting this into the equations for the conservation of the
- * components, one transport equation for each component is obtained as
- * \f{eqnarray*}
- && \phi \frac{\partial (\sum_\alpha \varrho_{\alpha,mol} x_\alpha^\kappa
- S_\alpha )}{\partial t}
- - \sum\limits_\alpha \text{div} \left\{ \frac{k_{r\alpha}}{\mu_\alpha}
- \varrho_{\alpha,mol} x_\alpha^\kappa \mathbf{K}
- (\textbf{grad}\, p_\alpha - \varrho_{\alpha,mass} \mbox{\bf g}) \right\}
- \nonumber \\
- \nonumber \\
- && - \sum\limits_\alpha \text{div} \left\{ D_\text{pm}^\kappa \varrho_{\alpha,mol}
- \textbf{grad} x^\kappa_{\alpha} \right\}
- - q^\kappa = 0 \qquad \forall \kappa , \; \forall \alpha
- \f}
- *
- * Note that these balance equations are molar.
- *
- * All equations are discretized using a vertex-centered finite volume (box)
- * or cell-centered finite volume scheme as spatial
- * and the implicit Euler method as time discretization.
- *
- * The model uses commonly applied auxiliary conditions like
- * \f$S_w + S_n + S_g = 1\f$ for the saturations and
- * \f$x^w_\alpha + x^a_\alpha + x^c_\alpha = 1\f$ for the mole fractions.
- * Furthermore, the phase pressures are related to each other via
- * capillary pressures between the fluid phases, which are functions of
- * the saturation, e.g. according to the approach of Parker et al.
- *
- * The used primary variables are dependent on the locally present fluid phases.
- * An adaptive primary variable switch is included. The phase state is stored for all nodes
- * of the system. The following cases can be distinguished:
- * <ul>
- *  <li> All three phases are present: Primary variables are two saturations \f$(S_w\f$ and \f$S_n)\f$,
- *       and a pressure, in this case \f$p_g\f$. </li>
- *  <li> Only the water phase is present: Primary variables are now the mole fractions of air and
- *       contaminant in the water phase \f$(x_w^a\f$ and \f$x_w^c)\f$, as well as the gas pressure, which is,
- *       of course, in a case where only the water phase is present, just the same as the water pressure. </li>
- *  <li> Gas and NAPL phases are present: Primary variables \f$(S_n\f$, \f$x_g^w\f$, \f$p_g)\f$. </li>
- *  <li> Water and NAPL phases are present: Primary variables \f$(S_n\f$, \f$x_w^a\f$, \f$p_g)\f$. </li>
- *  <li> Only gas phase is present: Primary variables \f$(x_g^w\f$, \f$x_g^c\f$, \f$p_g)\f$. </li>
- *  <li> Water and gas phases are present: Primary variables \f$(S_w\f$, \f$x_w^g\f$, \f$p_g)\f$. </li>
- * </ul>
- */
-template<class TypeTag>
-class ThreePThreeCModel: public GET_PROP_TYPE(TypeTag, BaseModel)
-{
-    typedef typename GET_PROP_TYPE(TypeTag, BaseModel) ParentType;
-
-    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
-    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
-    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
-    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
-
-    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
-    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector;
-    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
-
-    enum {
-        dim = GridView::dimension,
-        dimWorld = GridView::dimensionworld,
-
-        numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
-        numComponents = GET_PROP_VALUE(TypeTag, NumComponents),
-
-        switch1Idx = Indices::switch1Idx,
-        switch2Idx = Indices::switch2Idx,
-
-
-        wPhaseIdx = Indices::wPhaseIdx,
-        nPhaseIdx = Indices::nPhaseIdx,
-        gPhaseIdx = Indices::gPhaseIdx,
-
-        wCompIdx = Indices::wCompIdx,
-        nCompIdx = Indices::nCompIdx,
-        gCompIdx = Indices::gCompIdx,
-
-        threePhases = Indices::threePhases,
-        wPhaseOnly  = Indices::wPhaseOnly,
-        gnPhaseOnly = Indices::gnPhaseOnly,
-        wnPhaseOnly = Indices::wnPhaseOnly,
-        gPhaseOnly  = Indices::gPhaseOnly,
-        wgPhaseOnly = Indices::wgPhaseOnly
-
-    };
-
-    typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition;
-    enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) };
-    enum { dofCodim = isBox ? dim : 0 };
-
-public:
-    /*!
-     * \brief Initialize the static data with the initial solution.
-     *
-     * \param problem The problem to be solved
-     */
-    void init(Problem &problem)
-    {
-        ParentType::init(problem);
-
-        staticDat_.resize(this->numDofs());
-
-        setSwitched_(false);
-
-        if (isBox)
-        {
-            for (const auto& vertex : Dune::vertices(this->gridView_()))
-            {
-                int vIdxGlobal = this->dofMapper().index(vertex);
-
-                const GlobalPosition &globalPos = vertex.geometry().corner(0);
-
-                // initialize phase presence
-                staticDat_[vIdxGlobal].phasePresence
-                    = this->problem_().initialPhasePresence(vertex, vIdxGlobal,
-                                                        globalPos);
-                staticDat_[vIdxGlobal].wasSwitched = false;
-
-                staticDat_[vIdxGlobal].oldPhasePresence
-                    = staticDat_[vIdxGlobal].phasePresence;
-            }
-        }
-        else
-        {
-            for (const auto& element : Dune::elements(this->gridView_()))
-            {
-                int eIdxGlobal = this->dofMapper().index(element);
-                const GlobalPosition &globalPos = element.geometry().center();
-
-                // initialize phase presence
-                staticDat_[eIdxGlobal].phasePresence
-                    = this->problem_().initialPhasePresence(*this->gridView_().template begin<dim> (),
-                                                            eIdxGlobal, globalPos);
-                staticDat_[eIdxGlobal].wasSwitched = false;
-
-                staticDat_[eIdxGlobal].oldPhasePresence
-                    = staticDat_[eIdxGlobal].phasePresence;
-            }
-        }
-    }
-
-    /*!
-     * \brief Compute the total storage inside one phase of all
-     *        conservation quantities.
-     *
-     * \param storage Contains the storage of each component for one phase
-     * \param phaseIdx The phase index
-     */
-    void globalPhaseStorage(PrimaryVariables &storage, const int phaseIdx)
-    {
-        storage = 0;
-
-        for (const auto& element : Dune::elements(this->gridView_())) {
-            if(element.partitionType() == Dune::InteriorEntity)
-            {
-                this->localResidual().evalPhaseStorage(element, phaseIdx);
-
-                for (unsigned int i = 0; i < this->localResidual().storageTerm().size(); ++i)
-                    storage += this->localResidual().storageTerm()[i];
-            }
-        }
-        if (this->gridView_().comm().size() > 1)
-            storage = this->gridView_().comm().sum(storage);
-    }
-
-
-    /*!
-     * \brief Called by the update() method if applying the newton
-     *        method was unsuccessful.
-     */
-    void updateFailed()
-    {
-        ParentType::updateFailed();
-
-        setSwitched_(false);
-        resetPhasePresence_();
-    };
-
-    /*!
-     * \brief Called by the problem if a time integration was
-     *        successful, post processing of the solution is done and the
-     *        result has been written to disk.
-     *
-     * This should prepare the model for the next time integration.
-     */
-    void advanceTimeLevel()
-    {
-        ParentType::advanceTimeLevel();
-
-        // update the phase state
-        updateOldPhasePresence_();
-        setSwitched_(false);
-    }
-
-    /*!
-     * \brief Return true if the primary variables were switched for
-     *        at least one vertex after the last timestep.
-     */
-    bool switched() const
-    {
-        return switchFlag_;
-    }
-
-    /*!
-     * \brief Returns the phase presence of the current or the old solution of a degree of freedom.
-     *
-     * \param dofIdxGlobal The global index of the degree of freedom
-     * \param oldSol Evaluate function with solution of current or previous time step
-     */
-    int phasePresence(int dofIdxGlobal, bool oldSol) const
-    {
-        return
-            oldSol
-            ? staticDat_[dofIdxGlobal].oldPhasePresence
-            : staticDat_[dofIdxGlobal].phasePresence;
-    }
-
-    /*!
-     * \brief Append all quantities of interest which can be derived
-     *        from the solution of the current time step to the VTK
-     *        writer.
-     *
-     * \param sol The solution vector
-     * \param writer The writer for multi-file VTK datasets
-     */
-    template<class MultiWriter>
-    void addOutputVtkFields(const SolutionVector &sol,
-                            MultiWriter &writer)
-    {
-        typedef Dune::BlockVector<Dune::FieldVector<double, 1> > ScalarField;
-        typedef Dune::BlockVector<Dune::FieldVector<double, dimWorld> > VectorField;
-
-        // get the number of degrees of freedom
-        unsigned numDofs = this->numDofs();
-
-        // create the required scalar fields
-        ScalarField *saturation[numPhases];
-        ScalarField *pressure[numPhases];
-        ScalarField *density[numPhases];
-
-        for (int phaseIdx = 0; phaseIdx < numPhases; ++ phaseIdx) {
-            saturation[phaseIdx] = writer.allocateManagedBuffer(numDofs);
-            pressure[phaseIdx] = writer.allocateManagedBuffer(numDofs);
-            density[phaseIdx] = writer.allocateManagedBuffer(numDofs);
-        }
-
-        ScalarField *phasePresence = writer.allocateManagedBuffer (numDofs);
-        ScalarField *moleFraction[numPhases][numComponents];
-        for (int i = 0; i < numPhases; ++i)
-            for (int j = 0; j < numComponents; ++j)
-                moleFraction[i][j] = writer.allocateManagedBuffer (numDofs);
-        ScalarField *temperature = writer.allocateManagedBuffer (numDofs);
-        ScalarField *poro = writer.allocateManagedBuffer(numDofs);
-        VectorField *velocityN = writer.template allocateManagedBuffer<double, dimWorld>(numDofs);
-        VectorField *velocityW = writer.template allocateManagedBuffer<double, dimWorld>(numDofs);
-        VectorField *velocityG = writer.template allocateManagedBuffer<double, dimWorld>(numDofs);
-        ImplicitVelocityOutput<TypeTag> velocityOutput(this->problem_());
-
-        if (velocityOutput.enableOutput()) // check if velocity output is demanded
-        {
-            // initialize velocity fields
-            for (unsigned int i = 0; i < numDofs; ++i)
-            {
-                (*velocityN)[i] = Scalar(0);
-                (*velocityW)[i] = Scalar(0);
-                (*velocityG)[i] = Scalar(0);
-            }
-        }
-
-        unsigned numElements = this->gridView_().size(0);
-        ScalarField *rank = writer.allocateManagedBuffer (numElements);
-
-        for (const auto& element : Dune::elements(this->gridView_()))
-        {
-            if(element.partitionType() == Dune::InteriorEntity)
-            {
-                int eIdx = this->problem_().elementMapper().index(element);
-                (*rank)[eIdx] = this->gridView_().comm().rank();
-
-                FVElementGeometry fvGeometry;
-                fvGeometry.update(this->gridView_(), element);
-
-
-                ElementVolumeVariables elemVolVars;
-                elemVolVars.update(this->problem_(),
-                                   element,
-                                   fvGeometry,
-                                   false /* oldSol? */);
-
-                for (int scvIdx = 0; scvIdx < fvGeometry.numScv; ++scvIdx)
-                {
-                    int dofIdxGlobal = this->dofMapper().subIndex(element, scvIdx, dofCodim);
-
-                    for (int phaseIdx = 0; phaseIdx < numPhases; ++ phaseIdx) {
-                        (*saturation[phaseIdx])[dofIdxGlobal] = elemVolVars[scvIdx].saturation(phaseIdx);
-                        (*pressure[phaseIdx])[dofIdxGlobal] = elemVolVars[scvIdx].pressure(phaseIdx);
-                        (*density[phaseIdx])[dofIdxGlobal] = elemVolVars[scvIdx].density(phaseIdx);
-                    }
-
-                    for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
-                        for (int compIdx = 0; compIdx < numComponents; ++compIdx) {
-                            (*moleFraction[phaseIdx][compIdx])[dofIdxGlobal] =
-                                elemVolVars[scvIdx].moleFraction(phaseIdx,
-                                                                  compIdx);
-
-                            Valgrind::CheckDefined((*moleFraction[phaseIdx][compIdx])[dofIdxGlobal]);
-                        }
-                    }
-
-                    (*poro)[dofIdxGlobal] = elemVolVars[scvIdx].porosity();
-                    (*temperature)[dofIdxGlobal] = elemVolVars[scvIdx].temperature();
-                    (*phasePresence)[dofIdxGlobal] = staticDat_[dofIdxGlobal].phasePresence;
-                }
-
-                // velocity output
-                velocityOutput.calculateVelocity(*velocityW, elemVolVars, fvGeometry, element, wPhaseIdx);
-                velocityOutput.calculateVelocity(*velocityN, elemVolVars, fvGeometry, element, nPhaseIdx);
-                velocityOutput.calculateVelocity(*velocityN, elemVolVars, fvGeometry, element, gPhaseIdx);
-            }
-        }
-
-        writer.attachDofData(*saturation[wPhaseIdx], "Sw", isBox);
-        writer.attachDofData(*saturation[nPhaseIdx], "Sn", isBox);
-        writer.attachDofData(*saturation[gPhaseIdx], "Sg", isBox);
-        writer.attachDofData(*pressure[wPhaseIdx], "pw", isBox);
-        writer.attachDofData(*pressure[nPhaseIdx], "pn", isBox);
-        writer.attachDofData(*pressure[gPhaseIdx], "pg", isBox);
-        writer.attachDofData(*density[wPhaseIdx], "rhow", isBox);
-        writer.attachDofData(*density[nPhaseIdx], "rhon", isBox);
-        writer.attachDofData(*density[gPhaseIdx], "rhog", isBox);
-
-        for (int i = 0; i < numPhases; ++i)
-        {
-            for (int j = 0; j < numComponents; ++j)
-            {
-                std::ostringstream oss;
-                oss << "x^"
-                    << FluidSystem::componentName(j)
-                    << "_"
-                    << FluidSystem::phaseName(i);
-                writer.attachDofData(*moleFraction[i][j], oss.str().c_str(), isBox);
-            }
-        }
-        writer.attachDofData(*poro, "porosity", isBox);
-        writer.attachDofData(*temperature, "temperature", isBox);
-        writer.attachDofData(*phasePresence, "phase presence", isBox);
-
-        if (velocityOutput.enableOutput()) // check if velocity output is demanded
-        {
-            writer.attachDofData(*velocityW,  "velocityW", isBox, dim);
-            writer.attachDofData(*velocityN,  "velocityN", isBox, dim);
-            writer.attachDofData(*velocityG,  "velocityG", isBox, dim);
-        }
-
-        writer.attachCellData(*rank, "process rank");
-    }
-
-    /*!
-     * \brief Write the current solution to a restart file.
-     *
-     * \param outStream The output stream of one entity for the restart file
-     * \param entity The entity, either a vertex or an element
-     */
-    template<class Entity>
-    void serializeEntity(std::ostream &outStream, const Entity &entity)
-    {
-        // write primary variables
-        ParentType::serializeEntity(outStream, entity);
-
-        int dofIdxGlobal = this->dofMapper().index(entity);
-
-        if (!outStream.good())
-            DUNE_THROW(Dune::IOError, "Could not serialize entity " << dofIdxGlobal);
-
-        outStream << staticDat_[dofIdxGlobal].phasePresence << " ";
-    }
-
-    /*!
-     * \brief Reads the current solution from a restart file.
-     *
-     * \param inStream The input stream of one entity from the restart file
-     * \param entity The entity, either a vertex or an element
-     */
-    template<class Entity>
-    void deserializeEntity(std::istream &inStream, const Entity &entity)
-    {
-        // read primary variables
-        ParentType::deserializeEntity(inStream, entity);
-
-        // read phase presence
-        int dofIdxGlobal = this->dofMapper().index(entity);
-
-        if (!inStream.good())
-            DUNE_THROW(Dune::IOError,
-                       "Could not deserialize entity " << dofIdxGlobal);
-
-        inStream >> staticDat_[dofIdxGlobal].phasePresence;
-        staticDat_[dofIdxGlobal].oldPhasePresence
-            = staticDat_[dofIdxGlobal].phasePresence;
-
-    }
-
-    /*!
-     * \brief Update the static data of all vertices in the grid.
-     *
-     * \param curGlobalSol The current global solution
-     * \param oldGlobalSol The previous global solution
-     */
-    void updateStaticData(SolutionVector &curGlobalSol,
-                          const SolutionVector &oldGlobalSol)
-    {
-        bool wasSwitched = false;
-        int succeeded;
-        try {
-
-            for (unsigned i = 0; i < staticDat_.size(); ++i)
-                staticDat_[i].visited = false;
-
-            FVElementGeometry fvGeometry;
-            static VolumeVariables volVars;
-            for (const auto& element : Dune::elements(this->gridView_()))
-            {
-                fvGeometry.update(this->gridView_(), element);
-                for (int scvIdx = 0; scvIdx < fvGeometry.numScv; ++scvIdx)
-                {
-                    int dofIdxGlobal = this->dofMapper().subIndex(element, scvIdx, dofCodim);
-
-                    if (staticDat_[dofIdxGlobal].visited)
-                        continue;
-
-                    staticDat_[dofIdxGlobal].visited = true;
-                    volVars.update(curGlobalSol[dofIdxGlobal],
-                            this->problem_(),
-                            element,
-                            fvGeometry,
-                            scvIdx,
-                            false);
-                    const GlobalPosition &globalPos = fvGeometry.subContVol[scvIdx].global;
-                    if (primaryVarSwitch_(curGlobalSol,
-                            volVars,
-                            dofIdxGlobal,
-                            globalPos))
-                    {
-                        this->jacobianAssembler().markDofRed(dofIdxGlobal);
-                        wasSwitched = true;
-                    }
-                }
-            }
-            succeeded = 1;
-        }
-        catch (Dumux::NumericalProblem &e)
-        {
-            std::cout << "\n"
-                      << "Rank " << this->problem_().gridView().comm().rank()
-                      << " caught an exception while updating the static data." << e.what()
-                      << "\n";
-            succeeded = 0;
-        }
-        //make sure that all processes succeeded. If not throw a NumericalProblem to decrease the time step size.
-        if (this->gridView_().comm().size() > 1)
-            succeeded = this->gridView_().comm().min(succeeded);
-
-        if (!succeeded) {
-                DUNE_THROW(NumericalProblem,
-                        "A process did not succeed in updating the static data.");
-            return;
-        }
-
-        // make sure that if there was a variable switch in an
-        // other partition we will also set the switch flag
-        // for our partition.
-        if (this->gridView_().comm().size() > 1)
-            wasSwitched = this->gridView_().comm().max(wasSwitched);
-
-        setSwitched_(wasSwitched);
-    }
-
-protected:
-    /*!
-     * \brief Data which is attached to each vertex and is not only
-     *        stored locally.
-     */
-    struct StaticVars
-    {
-        int phasePresence;
-        bool wasSwitched;
-
-        int oldPhasePresence;
-        bool visited;
-    };
-
-    /*!
-     * \brief Reset the current phase presence of all vertices to the old one.
-     *
-     * This is done after an update failed.
-     */
-    void resetPhasePresence_()
-    {
-        for (unsigned int i = 0; i < this->numDofs(); ++i)
-        {
-            staticDat_[i].phasePresence
-                = staticDat_[i].oldPhasePresence;
-            staticDat_[i].wasSwitched = false;
-        }
-    }
-
-    /*!
-     * \brief Set the old phase of all verts state to the current one.
-     */
-    void updateOldPhasePresence_()
-    {
-        for (unsigned int i = 0; i < this->numDofs(); ++i)
-        {
-            staticDat_[i].oldPhasePresence
-                = staticDat_[i].phasePresence;
-            staticDat_[i].wasSwitched = false;
-        }
-    }
-
-    /*!
-     * \brief Set whether there was a primary variable switch after in
-     *        the last timestep.
-     */
-    void setSwitched_(bool yesno)
-    {
-        switchFlag_ = yesno;
-    }
-
-    //  perform variable switch at a vertex; Returns true if a
-    //  variable switch was performed.
-    bool primaryVarSwitch_(SolutionVector &globalSol,
-                           const VolumeVariables &volVars,
-                           int dofIdxGlobal,
-                           const GlobalPosition &globalPos)
-    {
-        // evaluate primary variable switch
-        bool wouldSwitch = false;
-        int phasePresence = staticDat_[dofIdxGlobal].phasePresence;
-        int newPhasePresence = phasePresence;
-
-        // check if a primary var switch is necessary
-        if (phasePresence == threePhases)
-        {
-            Scalar Smin = 0;
-            if (staticDat_[dofIdxGlobal].wasSwitched)
-                Smin = -0.01;
-
-            if (volVars.saturation(gPhaseIdx) <= Smin)
-            {
-                wouldSwitch = true;
-                // gas phase disappears
-                std::cout << "Gas phase disappears at vertex " << dofIdxGlobal
-                          << ", coordinates: " << globalPos << ", sg: "
-                          << volVars.saturation(gPhaseIdx) << std::endl;
-                newPhasePresence = wnPhaseOnly;
-
-                globalSol[dofIdxGlobal][switch1Idx]
-                    = volVars.moleFraction(wPhaseIdx, gCompIdx);
-            }
-            else if (volVars.saturation(wPhaseIdx) <= Smin)
-            {
-                wouldSwitch = true;
-                // water phase disappears
-                std::cout << "Water phase disappears at vertex " << dofIdxGlobal
-                          << ", coordinates: " << globalPos << ", sw: "
-                          << volVars.saturation(wPhaseIdx) << std::endl;
-                newPhasePresence = gnPhaseOnly;
-
-                globalSol[dofIdxGlobal][switch1Idx]
-                    = volVars.moleFraction(gPhaseIdx, wCompIdx);
-            }
-            else if (volVars.saturation(nPhaseIdx) <= Smin)
-            {
-                wouldSwitch = true;
-                // NAPL phase disappears
-                std::cout << "NAPL phase disappears at vertex " << dofIdxGlobal
-                          << ", coordinates: " << globalPos << ", sn: "
-                          << volVars.saturation(nPhaseIdx) << std::endl;
-                newPhasePresence = wgPhaseOnly;
-
-                globalSol[dofIdxGlobal][switch2Idx]
-                    = volVars.moleFraction(gPhaseIdx, nCompIdx);
-            }
-        }
-        else if (phasePresence == wPhaseOnly)
-        {
-            bool gasFlag = 0;
-            bool nonwettingFlag = 0;
-            // calculate fractions of the partial pressures in the
-            // hypothetical gas phase
-            Scalar xwg = volVars.moleFraction(gPhaseIdx, wCompIdx);
-            Scalar xgg = volVars.moleFraction(gPhaseIdx, gCompIdx);
-            Scalar xng = volVars.moleFraction(gPhaseIdx, nCompIdx);
-            /* take care:
-               for xgg in case wPhaseOnly we compute xgg=henry_air*x2w
-               for xwg in case wPhaseOnly we compute xwg=pwsat
-               for xng in case wPhaseOnly we compute xng=henry_NAPL*x1w
-            */
-
-            Scalar xgMax = 1.0;
-            if (xwg + xgg + xng > xgMax)
-                wouldSwitch = true;
-            if (staticDat_[dofIdxGlobal].wasSwitched)
-                xgMax *= 1.02;
-
-            // if the sum of the mole fractions would be larger than
-            // 100%, gas phase appears
-            if (xwg + xgg + xng > xgMax)
-            {
-                // gas phase appears
-                std::cout << "gas phase appears at vertex " << dofIdxGlobal
-                          << ", coordinates: " << globalPos << ", xwg + xgg + xng: "
-                          << xwg + xgg + xng << std::endl;
-                gasFlag = 1;
-            }
-
-            // calculate fractions in the hypothetical NAPL phase
-            Scalar xnn = volVars.moleFraction(nPhaseIdx, nCompIdx);
-            /* take care:
-               for xnn in case wPhaseOnly we compute xnn=henry_mesitylene*x1w,
-               where a hypothetical gas pressure is assumed for the Henry
-               x0n is set to NULL  (all NAPL phase is dirty)
-               x2n is set to NULL  (all NAPL phase is dirty)
-            */
-
-            Scalar xnMax = 1.0;
-            if (xnn > xnMax)
-                wouldSwitch = true;
-            if (staticDat_[dofIdxGlobal].wasSwitched)
-                xnMax *= 1.02;
-
-            // if the sum of the hypothetical mole fractions would be larger than
-            // 100%, NAPL phase appears
-            if (xnn > xnMax)
-            {
-                // NAPL phase appears
-                std::cout << "NAPL phase appears at vertex " << dofIdxGlobal
-                          << ", coordinates: " << globalPos << ", xnn: "
-                          << xnn << std::endl;
-                nonwettingFlag = 1;
-            }
-
-            if ((gasFlag == 1) && (nonwettingFlag == 0))
-            {
-                newPhasePresence = wgPhaseOnly;
-                globalSol[dofIdxGlobal][switch1Idx] = 0.9999;
-                globalSol[dofIdxGlobal][switch2Idx] = 0.0001;
-            }
-            else if ((gasFlag == 1) && (nonwettingFlag == 1))
-            {
-                newPhasePresence = threePhases;
-                globalSol[dofIdxGlobal][switch1Idx] = 0.9999;
-                globalSol[dofIdxGlobal][switch2Idx] = 0.0001;
-            }
-            else if ((gasFlag == 0) && (nonwettingFlag == 1))
-            {
-                newPhasePresence = wnPhaseOnly;
-                globalSol[dofIdxGlobal][switch1Idx]
-                    = volVars.moleFraction(wPhaseIdx, gCompIdx);
-                globalSol[dofIdxGlobal][switch2Idx] = 0.0001;
-            }
-        }
-        else if (phasePresence == gnPhaseOnly)
-        {
-            bool nonwettingFlag = 0;
-            bool wettingFlag = 0;
-
-            Scalar Smin = 0.0;
-            if (staticDat_[dofIdxGlobal].wasSwitched)
-                Smin = -0.01;
-
-            if (volVars.saturation(nPhaseIdx) <= Smin)
-            {
-                wouldSwitch = true;
-                // NAPL phase disappears
-                std::cout << "NAPL phase disappears at vertex " << dofIdxGlobal
-                          << ", coordinates: " << globalPos << ", sn: "
-                          << volVars.saturation(nPhaseIdx) << std::endl;
-                nonwettingFlag = 1;
-            }
-
-
-            // calculate fractions of the hypothetical water phase
-            Scalar xww = volVars.moleFraction(wPhaseIdx, wCompIdx);
-            /*
-              take care:, xww, if no water is present, then take xww=xwg*pg/pwsat .
-              If this is larger than 1, then water appears
-            */
-            Scalar xwMax = 1.0;
-            if (xww > xwMax)
-                wouldSwitch = true;
-            if (staticDat_[dofIdxGlobal].wasSwitched)
-                xwMax *= 1.02;
-
-            // if the sum of the mole fractions would be larger than
-            // 100%, gas phase appears
-            if (xww > xwMax)
-            {
-                // water phase appears
-                std::cout << "water phase appears at vertex " << dofIdxGlobal
-                          << ", coordinates: " << globalPos << ", xww=xwg*pg/pwsat : "
-                          << xww << std::endl;
-                wettingFlag = 1;
-            }
-
-            if ((wettingFlag == 1) && (nonwettingFlag == 0))
-            {
-                newPhasePresence = threePhases;
-                globalSol[dofIdxGlobal][switch1Idx] = 0.0001;
-                globalSol[dofIdxGlobal][switch2Idx] = volVars.saturation(nPhaseIdx);
-            }
-            else if ((wettingFlag == 1) && (nonwettingFlag == 1))
-            {
-                newPhasePresence = wgPhaseOnly;
-                globalSol[dofIdxGlobal][switch1Idx] = 0.0001;
-                globalSol[dofIdxGlobal][switch2Idx]
-                    = volVars.moleFraction(gPhaseIdx, nCompIdx);
-            }
-            else if ((wettingFlag == 0) && (nonwettingFlag == 1))
-            {
-                newPhasePresence = gPhaseOnly;
-                globalSol[dofIdxGlobal][switch1Idx]
-                    = volVars.moleFraction(gPhaseIdx, wCompIdx);
-                globalSol[dofIdxGlobal][switch2Idx]
-                    = volVars.moleFraction(gPhaseIdx, nCompIdx);
-            }
-        }
-        else if (phasePresence == wnPhaseOnly)
-        {
-            bool nonwettingFlag = 0;
-            bool gasFlag = 0;
-
-            Scalar Smin = 0.0;
-            if (staticDat_[dofIdxGlobal].wasSwitched)
-                Smin = -0.01;
-
-            if (volVars.saturation(nPhaseIdx) <= Smin)
-            {
-                wouldSwitch = true;
-                // NAPL phase disappears
-                std::cout << "NAPL phase disappears at vertex " << dofIdxGlobal
-                          << ", coordinates: " << globalPos << ", sn: "
-                          << volVars.saturation(nPhaseIdx) << std::endl;
-                nonwettingFlag = 1;
-            }
-
-            // calculate fractions of the partial pressures in the
-            // hypothetical gas phase
-            Scalar xwg = volVars.moleFraction(gPhaseIdx, wCompIdx);
-            Scalar xgg = volVars.moleFraction(gPhaseIdx, gCompIdx);
-            Scalar xng = volVars.moleFraction(gPhaseIdx, nCompIdx);
-            /* take care:
-               for xgg in case wPhaseOnly we compute xgg=henry_air*x2w
-               for xwg in case wPhaseOnly we compute xwg=pwsat
-               for xng in case wPhaseOnly we compute xng=henry_NAPL*x1w
-            */
-            Scalar xgMax = 1.0;
-            if (xwg + xgg + xng > xgMax)
-                wouldSwitch = true;
-            if (staticDat_[dofIdxGlobal].wasSwitched)
-                xgMax *= 1.02;
-
-            // if the sum of the mole fractions would be larger than
-            // 100%, gas phase appears
-            if (xwg + xgg + xng > xgMax)
-            {
-                // gas phase appears
-                std::cout << "gas phase appears at vertex " << dofIdxGlobal
-                          << ", coordinates: " << globalPos << ", xwg + xgg + xng: "
-                          << xwg + xgg + xng << std::endl;
-                gasFlag = 1;
-            }
-
-            if ((gasFlag == 1) && (nonwettingFlag == 0))
-            {
-                newPhasePresence = threePhases;
-                globalSol[dofIdxGlobal][switch1Idx] = volVars.saturation(wPhaseIdx);
-                globalSol[dofIdxGlobal][switch2Idx] = volVars.saturation(nPhaseIdx);
-            }
-            else if ((gasFlag == 1) && (nonwettingFlag == 1))
-            {
-                newPhasePresence = wgPhaseOnly;
-                globalSol[dofIdxGlobal][switch1Idx] = volVars.saturation(wPhaseIdx);
-                globalSol[dofIdxGlobal][switch2Idx]
-                    = volVars.moleFraction(gPhaseIdx, nCompIdx);
-            }
-            else if ((gasFlag == 0) && (nonwettingFlag == 1))
-            {
-                newPhasePresence = wPhaseOnly;
-                globalSol[dofIdxGlobal][switch1Idx]
-                    = volVars.moleFraction(wPhaseIdx, gCompIdx);
-                globalSol[dofIdxGlobal][switch2Idx]
-                    = volVars.moleFraction(wPhaseIdx, nCompIdx);
-            }
-        }
-        else if (phasePresence == gPhaseOnly)
-        {
-            bool nonwettingFlag = 0;
-            bool wettingFlag = 0;
-
-            // calculate fractions in the hypothetical NAPL phase
-            Scalar xnn = volVars.moleFraction(nPhaseIdx, nCompIdx);
-            /*
-              take care:, xnn, if no NAPL phase is there, take xnn=xng*pg/pcsat
-              if this is larger than 1, then NAPL appears
-            */
-
-            Scalar xnMax = 1.0;
-            if (xnn > xnMax)
-                wouldSwitch = true;
-            if (staticDat_[dofIdxGlobal].wasSwitched)
-                xnMax *= 1.02;
-
-            // if the sum of the hypothetical mole fraction would be larger than
-            // 100%, NAPL phase appears
-            if (xnn > xnMax)
-            {
-                // NAPL phase appears
-                std::cout << "NAPL phase appears at vertex " << dofIdxGlobal
-                          << ", coordinates: " << globalPos << ", xnn: "
-                          << xnn << std::endl;
-                nonwettingFlag = 1;
-            }
-            // calculate fractions of the hypothetical water phase
-            Scalar xww = volVars.moleFraction(wPhaseIdx, wCompIdx);
-            /*
-              take care:, xww, if no water is present, then take xww=xwg*pg/pwsat .
-              If this is larger than 1, then water appears
-            */
-            Scalar xwMax = 1.0;
-            if (xww > xwMax)
-                wouldSwitch = true;
-            if (staticDat_[dofIdxGlobal].wasSwitched)
-                xwMax *= 1.02;
-
-            // if the sum of the mole fractions would be larger than
-            // 100%, gas phase appears
-            if (xww > xwMax)
-            {
-                // water phase appears
-                std::cout << "water phase appears at vertex " << dofIdxGlobal
-                          << ", coordinates: " << globalPos << ", xww=xwg*pg/pwsat : "
-                          << xww << std::endl;
-                wettingFlag = 1;
-            }
-            if ((wettingFlag == 1) && (nonwettingFlag == 0))
-            {
-                newPhasePresence = wgPhaseOnly;
-                globalSol[dofIdxGlobal][switch1Idx] = 0.0001;
-                globalSol[dofIdxGlobal][switch2Idx]
-                    = volVars.moleFraction(gPhaseIdx, nCompIdx);
-            }
-            else if ((wettingFlag == 1) && (nonwettingFlag == 1))
-            {
-                newPhasePresence = threePhases;
-                globalSol[dofIdxGlobal][switch1Idx] = 0.0001;
-                globalSol[dofIdxGlobal][switch2Idx] = 0.0001;
-            }
-            else if ((wettingFlag == 0) && (nonwettingFlag == 1))
-            {
-                newPhasePresence = gnPhaseOnly;
-                globalSol[dofIdxGlobal][switch1Idx]
-                    = volVars.moleFraction(gPhaseIdx, wCompIdx);
-                globalSol[dofIdxGlobal][switch2Idx] = 0.0001;
-            }
-        }
-        else if (phasePresence == wgPhaseOnly)
-        {
-            bool nonwettingFlag = 0;
-            bool gasFlag = 0;
-            bool wettingFlag = 0;
-
-            // get the fractions in the hypothetical NAPL phase
-            Scalar xnn = volVars.moleFraction(nPhaseIdx, nCompIdx);
-
-            // take care: if the NAPL phase is not present, take
-            // xnn=xng*pg/pcsat if this is larger than 1, then NAPL
-            // appears
-            Scalar xnMax = 1.0;
-            if (xnn > xnMax)
-                wouldSwitch = true;
-            if (staticDat_[dofIdxGlobal].wasSwitched)
-                xnMax *= 1.02;
-
-            // if the sum of the hypothetical mole fraction would be larger than
-            // 100%, NAPL phase appears
-            if (xnn > xnMax)
-            {
-                // NAPL phase appears
-                std::cout << "NAPL phase appears at vertex " << dofIdxGlobal
-                          << ", coordinates: " << globalPos << ", xnn: "
-                          << xnn << std::endl;
-                nonwettingFlag = 1;
-            }
-
-            Scalar Smin = -1.e-6;
-            if (staticDat_[dofIdxGlobal].wasSwitched)
-                Smin = -0.01;
-
-            if (volVars.saturation(gPhaseIdx) <= Smin)
-            {
-                wouldSwitch = true;
-                // gas phase disappears
-                std::cout << "Gas phase disappears at vertex " << dofIdxGlobal
-                          << ", coordinates: " << globalPos << ", sg: "
-                          << volVars.saturation(gPhaseIdx) << std::endl;
-                gasFlag = 1;
-            }
-
-            Smin = 0.0;
-            if (staticDat_[dofIdxGlobal].wasSwitched)
-                Smin = -0.01;
-
-            if (volVars.saturation(wPhaseIdx) <= Smin)
-            {
-                wouldSwitch = true;
-                // gas phase disappears
-                std::cout << "Water phase disappears at vertex " << dofIdxGlobal
-                          << ", coordinates: " << globalPos << ", sw: "
-                          << volVars.saturation(wPhaseIdx) << std::endl;
-                wettingFlag = 1;
-            }
-
-            if ((gasFlag == 0) && (nonwettingFlag == 1) && (wettingFlag == 1))
-            {
-                newPhasePresence = gnPhaseOnly;
-                globalSol[dofIdxGlobal][switch1Idx]
-                    = volVars.moleFraction(gPhaseIdx, wCompIdx);
-                globalSol[dofIdxGlobal][switch2Idx] = 0.0001;
-            }
-            else if ((gasFlag == 0) && (nonwettingFlag == 1) && (wettingFlag == 0))
-            {
-                newPhasePresence = threePhases;
-                globalSol[dofIdxGlobal][switch1Idx] = volVars.saturation(wPhaseIdx);
-                globalSol[dofIdxGlobal][switch2Idx] = 0.0;
-            }
-            else if ((gasFlag == 1) && (nonwettingFlag == 0) && (wettingFlag == 0))
-            {
-                newPhasePresence = wPhaseOnly;
-                globalSol[dofIdxGlobal][switch1Idx]
-                    = volVars.moleFraction(wPhaseIdx, gCompIdx);
-                globalSol[dofIdxGlobal][switch2Idx]
-                    = volVars.moleFraction(wPhaseIdx, nCompIdx);
-            }
-            else if ((gasFlag == 0) && (nonwettingFlag == 0) && (wettingFlag == 1))
-            {
-                newPhasePresence = gPhaseOnly;
-                globalSol[dofIdxGlobal][switch1Idx]
-                    = volVars.moleFraction(gPhaseIdx, wCompIdx);
-                globalSol[dofIdxGlobal][switch2Idx]
-                    = volVars.moleFraction(gPhaseIdx, nCompIdx);
-            }
-        }
-
-        staticDat_[dofIdxGlobal].phasePresence = newPhasePresence;
-        staticDat_[dofIdxGlobal].wasSwitched = wouldSwitch;
-        return phasePresence != newPhasePresence;
-    }
-
-    // parameters given in constructor
-    std::vector<StaticVars> staticDat_;
-    bool switchFlag_;
-};
-
-}
-
-#include "3p3cpropertydefaults.hh"
+#include <dumux/porousmediumflow/3p3c/implicit/model.hh>
 
 #endif
diff --git a/dumux/implicit/3p3c/3p3cnewtoncontroller.hh b/dumux/implicit/3p3c/3p3cnewtoncontroller.hh
index 11ea75942e..06c9aa33fd 100644
--- a/dumux/implicit/3p3c/3p3cnewtoncontroller.hh
+++ b/dumux/implicit/3p3c/3p3cnewtoncontroller.hh
@@ -1,86 +1,8 @@
-// -*- 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/>.   *
- *****************************************************************************/
-/*!
- * \file
- * \brief A three-phase three-component specific controller for the newton solver.
- *
- * This controller 'knows' what a 'physically meaningful' solution is
- * which allows the newton method to abort quicker if the solution is
- * way out of bounds.
- */
-#ifndef DUMUX_3P3C_NEWTON_CONTROLLER_HH
-#define DUMUX_3P3C_NEWTON_CONTROLLER_HH
+#ifndef DUMUX_3P3C_NEWTON_CONTROLLER_HH_OLD
+#define DUMUX_3P3C_NEWTON_CONTROLLER_HH_OLD
 
-#include "3p3cproperties.hh"
+#warning this header is deprecated, use dumux/porousmediumflow/3p3c/implicit/newtoncontroller.hh instead
 
-#include <dumux/nonlinear/newtoncontroller.hh>
-
-namespace Dumux {
-/*!
- * \ingroup Newton
- * \ingroup ThreePThreeCModel
- * \brief A three-phase three-component specific controller for the newton solver.
- *
- * This controller 'knows' what a 'physically meaningful' solution is
- * which allows the newton method to abort quicker if the solution is
- * way out of bounds.
- */
-template <class TypeTag>
-class ThreePThreeCNewtonController : public NewtonController<TypeTag>
-{
-    typedef NewtonController<TypeTag> ParentType;
-    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
-    typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector;
-
-public:
-    ThreePThreeCNewtonController(const Problem &problem)
-        : ParentType(problem)
-    {};
-
-
-    /*!
-     * \brief Called after each Newton update
-     *
-     * \param uCurrentIter The current global solution vector
-     * \param uLastIter The previous global solution vector
-     */
-    void newtonEndStep(SolutionVector &uCurrentIter,
-                       const SolutionVector &uLastIter)
-    {
-        // call the method of the base class
-        this->method().model().updateStaticData(uCurrentIter, uLastIter);
-        ParentType::newtonEndStep(uCurrentIter, uLastIter);
-    }
-
-
-    /*!
-     * \brief Returns true if the current solution can be considered to
-     *        be accurate enough
-     */
-    bool newtonConverged()
-    {
-        if (this->method().model().switched())
-            return false;
-
-        return ParentType::newtonConverged();
-    };
-};
-}
+#include <dumux/porousmediumflow/3p3c/implicit/newtoncontroller.hh>
 
 #endif
diff --git a/dumux/implicit/3p3c/3p3cproperties.hh b/dumux/implicit/3p3c/3p3cproperties.hh
index 52a2762e8c..8dfef88f6e 100644
--- a/dumux/implicit/3p3c/3p3cproperties.hh
+++ b/dumux/implicit/3p3c/3p3cproperties.hh
@@ -1,82 +1,8 @@
-// -*- 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/>.   *
- *****************************************************************************/
-/*!
- * \ingroup Properties
- * \ingroup ImplicitProperties
- * \ingroup ThreePThreeCModel
- */
-/*!
- * \file
- *
- * \brief Defines the properties required for the three-phase three-component
- *        fully implicit model.
- */
-#ifndef DUMUX_3P3C_PROPERTIES_HH
-#define DUMUX_3P3C_PROPERTIES_HH
+#ifndef DUMUX_3P3C_PROPERTIES_HH_OLD
+#define DUMUX_3P3C_PROPERTIES_HH_OLD
 
-#include <dumux/implicit/box/properties.hh>
-#include <dumux/implicit/cellcentered/properties.hh>
-#include <dumux/porousmediumflow/nonisothermal/implicit/properties.hh>
+#warning this header is deprecated, use dumux/porousmediumflow/3p3c/implicit/properties.hh instead
 
-
-namespace Dumux
-{
-
-namespace Properties
-{
-//////////////////////////////////////////////////////////////////
-// Type tags
-//////////////////////////////////////////////////////////////////
-
-//! The type tags for the implicit three-phase three-component problems
-NEW_TYPE_TAG(ThreePThreeC);
-NEW_TYPE_TAG(BoxThreePThreeC, INHERITS_FROM(BoxModel, ThreePThreeC));
-NEW_TYPE_TAG(CCThreePThreeC, INHERITS_FROM(CCModel, ThreePThreeC));
-
-//! The type tags for the corresponding non-isothermal problems
-NEW_TYPE_TAG(ThreePThreeCNI, INHERITS_FROM(ThreePThreeC, NonIsothermal));
-NEW_TYPE_TAG(BoxThreePThreeCNI, INHERITS_FROM(BoxModel, ThreePThreeCNI));
-NEW_TYPE_TAG(CCThreePThreeCNI, INHERITS_FROM(CCModel, ThreePThreeCNI));
-
-//////////////////////////////////////////////////////////////////
-// Property tags
-//////////////////////////////////////////////////////////////////
-
-NEW_PROP_TAG(NumPhases);   //!< Number of fluid phases in the system
-NEW_PROP_TAG(NumComponents); //!< Number of fluid components in the system
-NEW_PROP_TAG(Indices); //!< Enumerations for the model
-NEW_PROP_TAG(SpatialParams); //!< The type of the spatial parameters
-NEW_PROP_TAG(FluidSystem); //!< Type of the multi-component relations
-NEW_PROP_TAG(FluidState); //!< Type of the fluid state to be used
-
-NEW_PROP_TAG(MaterialLaw);   //!< The material law which ought to be used (extracted from the spatial parameters)
-NEW_PROP_TAG(MaterialLawParams); //!< The parameters of the material law (extracted from the spatial parameters)
-NEW_PROP_TAG(EffectiveDiffusivityModel); //!< The employed model for the computation of the effective diffusivity
-
-NEW_PROP_TAG(ProblemEnableGravity); //!< Returns whether gravity is considered in the problem
-NEW_PROP_TAG(ImplicitMassUpwindWeight); //!< The value of the upwind parameter for the mobility
-NEW_PROP_TAG(ImplicitMobilityUpwindWeight); //!< Weight for the upwind mobility in the velocity calculation
-NEW_PROP_TAG(UseConstraintSolver); //!< Determines whether a constraint solver should be used explicitly
-NEW_PROP_TAG(BaseFluxVariables); //! The base flux variables
-NEW_PROP_TAG(SpatialParamsForchCoeff); //!< Property for the forchheimer coefficient
-NEW_PROP_TAG(VtkAddVelocity); //!< Returns whether velocity vectors are written into the vtk output
-}
-}
+#include <dumux/porousmediumflow/3p3c/implicit/properties.hh>
 
 #endif
diff --git a/dumux/implicit/3p3c/3p3cpropertydefaults.hh b/dumux/implicit/3p3c/3p3cpropertydefaults.hh
index 187c15beed..26bfa705d8 100644
--- a/dumux/implicit/3p3c/3p3cpropertydefaults.hh
+++ b/dumux/implicit/3p3c/3p3cpropertydefaults.hh
@@ -1,211 +1,8 @@
-// -*- 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/>.   *
- *****************************************************************************/
-/*!
- * \ingroup Properties
- * \ingroup ImplicitProperties
- * \ingroup ThreePThreeCModel
- * \file
- *
- * \brief Defines default values for most properties required by the
- *        three-phase three-component fully implicit model.
- */
-#ifndef DUMUX_3P3C_PROPERTY_DEFAULTS_HH
-#define DUMUX_3P3C_PROPERTY_DEFAULTS_HH
+#ifndef DUMUX_3P3C_PROPERTY_DEFAULTS_HH_OLD
+#define DUMUX_3P3C_PROPERTY_DEFAULTS_HH_OLD
 
-#include "3p3cindices.hh"
+#warning this header is deprecated, use dumux/porousmediumflow/3p3c/implicit/propertydefaults.hh instead
 
-#include "3p3cmodel.hh"
-#include "3p3cindices.hh"
-#include "3p3cfluxvariables.hh"
-#include "3p3cvolumevariables.hh"
-#include "3p3cproperties.hh"
-#include "3p3cnewtoncontroller.hh"
-#include "3p3clocalresidual.hh"
-
-#include <dumux/porousmediumflow/nonisothermal/implicit/propertydefaults.hh>
-#include <dumux/material/fluidmatrixinteractions/diffusivitymillingtonquirk.hh>
-#include <dumux/porousmediumflow/implicit/darcyfluxvariables.hh>
-#include <dumux/material/spatialparams/implicitspatialparams.hh>
-#include <dumux/material/fluidmatrixinteractions/3p/thermalconductivitysomerton3p.hh>
-
-namespace Dumux
-{
-
-namespace Properties {
-//////////////////////////////////////////////////////////////////
-// Property values
-//////////////////////////////////////////////////////////////////
-
-/*!
- * \brief Set the property for the number of components.
- *
- * We just forward the number from the fluid system and use an static
- * assert to make sure it is 3.
- */
-SET_PROP(ThreePThreeC, NumComponents)
-{
- private:
-    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
-
- public:
-    static const int value = FluidSystem::numComponents;
-
-    static_assert(value == 3,
-                  "Only fluid systems with 3 components are supported by the 3p3c model!");
-};
-
-/*!
- * \brief Set the property for the number of fluid phases.
- *
- * We just forward the number from the fluid system and use an static
- * assert to make sure it is 3.
- */
-SET_PROP(ThreePThreeC, NumPhases)
-{
- private:
-    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
-
- public:
-    static const int value = FluidSystem::numPhases;
-    static_assert(value == 3,
-                  "Only fluid systems with 3 phases are supported by the 3p3c model!");
-};
-
-/*!
- * \brief The fluid state which is used by the volume variables to
- *        store the thermodynamic state. This should be chosen
- *        appropriately for the model ((non-)isothermal, equilibrium, ...).
- *        This can be done in the problem.
- */
-SET_PROP(ThreePThreeC, FluidState){
-    private:
-        typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
-        typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
-    public:
-        typedef Dumux::CompositionalFluidState<Scalar, FluidSystem> type;
-};
-
-SET_INT_PROP(ThreePThreeC, NumEq, 3); //!< set the number of equations to 2
-
-/*!
- * \brief Set the property for the material parameters by extracting
- *        it from the material law.
- */
-SET_TYPE_PROP(ThreePThreeC, MaterialLawParams, typename GET_PROP_TYPE(TypeTag, MaterialLaw)::Params);
-
-//! The local residual function of the conservation equations
-SET_TYPE_PROP(ThreePThreeC, LocalResidual, ThreePThreeCLocalResidual<TypeTag>);
-
-//! Use the 3p3c specific newton controller for the 3p3c model
-SET_TYPE_PROP(ThreePThreeC, NewtonController, ThreePThreeCNewtonController<TypeTag>);
-
-//! the Model property
-SET_TYPE_PROP(ThreePThreeC, Model, ThreePThreeCModel<TypeTag>);
-
-//! the VolumeVariables property
-SET_TYPE_PROP(ThreePThreeC, VolumeVariables, ThreePThreeCVolumeVariables<TypeTag>);
-
-//! the FluxVariables property
-SET_TYPE_PROP(ThreePThreeC, FluxVariables, ThreePThreeCFluxVariables<TypeTag>);
-
-//! define the base flux variables to realize Darcy flow
-SET_TYPE_PROP(ThreePThreeC, BaseFluxVariables, ImplicitDarcyFluxVariables<TypeTag>);
-
-//! the upwind factor for the mobility.
-SET_SCALAR_PROP(ThreePThreeC, ImplicitMassUpwindWeight, 1.0);
-
-//! set default mobility upwind weight to 1.0, i.e. fully upwind
-SET_SCALAR_PROP(ThreePThreeC, ImplicitMobilityUpwindWeight, 1.0);
-
-//! Determines whether a constraint solver should be used explicitly
-SET_BOOL_PROP(ThreePThreeC, UseConstraintSolver, false);
-
-//! The indices required by the isothermal 3p3c model
-SET_TYPE_PROP(ThreePThreeC, Indices, ThreePThreeCIndices<TypeTag, /*PVOffset=*/0>);
-
-//! The spatial parameters to be employed.
-//! Use ImplicitSpatialParams by default.
-SET_TYPE_PROP(ThreePThreeC, SpatialParams, ImplicitSpatialParams<TypeTag>);
-
-//! The model after Millington (1961) is used for the effective diffusivity
-SET_PROP(ThreePThreeC, EffectiveDiffusivityModel)
-{ private :
-    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
- public:
-    typedef DiffusivityMillingtonQuirk<Scalar> type;
-};
-
-// disable velocity output by default
-SET_BOOL_PROP(ThreePThreeC, VtkAddVelocity, false);
-
-// enable gravity by default
-SET_BOOL_PROP(ThreePThreeC, ProblemEnableGravity, true);
-
-//! default value for the forchheimer coefficient
-// Source: Ward, J.C. 1964 Turbulent flow in porous media. ASCE J. Hydraul. Div 90.
-//        Actually the Forchheimer coefficient is also a function of the dimensions of the
-//        porous medium. Taking it as a constant is only a first approximation
-//        (Nield, Bejan, Convection in porous media, 2006, p. 10)
-SET_SCALAR_PROP(BoxModel, SpatialParamsForchCoeff, 0.55);
-
-//! Somerton is used as default model to compute the effective thermal heat conductivity
-SET_PROP(ThreePThreeCNI, ThermalConductivityModel)
-{
-private:
-    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
-    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
-public:
-    typedef ThermalConductivitySomerton<Scalar, Indices> type;
-};
-
-//! temperature is already written by the isothermal model
-SET_BOOL_PROP(ThreePThreeCNI, NiOutputLevel, 0);
-
-//////////////////////////////////////////////////////////////////
-// Property values for isothermal model required for the general non-isothermal model
-//////////////////////////////////////////////////////////////////
-
-// set isothermal Model
-SET_TYPE_PROP(ThreePThreeCNI, IsothermalModel, ThreePThreeCModel<TypeTag>);
-
-// set isothermal FluxVariables
-SET_TYPE_PROP(ThreePThreeCNI, IsothermalFluxVariables, ThreePThreeCFluxVariables<TypeTag>);
-
-//set isothermal VolumeVariables
-SET_TYPE_PROP(ThreePThreeCNI, IsothermalVolumeVariables, ThreePThreeCVolumeVariables<TypeTag>);
-
-//set isothermal LocalResidual
-SET_TYPE_PROP(ThreePThreeCNI, IsothermalLocalResidual, ThreePThreeCLocalResidual<TypeTag>);
-
-//set isothermal Indices
-SET_PROP(ThreePThreeCNI, IsothermalIndices)
-{
-
-public:
-    typedef ThreePThreeCIndices<TypeTag, /*PVOffset=*/0> type;
-};
-
-//set isothermal NumEq
-SET_INT_PROP(ThreePThreeCNI, IsothermalNumEq, 3);
-
-}
-
-}
+#include <dumux/porousmediumflow/3p3c/implicit/propertydefaults.hh>
 
 #endif
diff --git a/dumux/implicit/3p3c/3p3cvolumevariables.hh b/dumux/implicit/3p3c/3p3cvolumevariables.hh
index 58a71d6ea8..f538b0b6cc 100644
--- a/dumux/implicit/3p3c/3p3cvolumevariables.hh
+++ b/dumux/implicit/3p3c/3p3cvolumevariables.hh
@@ -1,750 +1,8 @@
-// -*- 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/>.   *
- *****************************************************************************/
-/*!
- * \file
- *
- * \brief Contains the quantities which are constant within a
- *        finite volume in the three-phase three-component model.
- */
-#ifndef DUMUX_3P3C_VOLUME_VARIABLES_HH
-#define DUMUX_3P3C_VOLUME_VARIABLES_HH
+#ifndef DUMUX_3P3C_VOLUME_VARIABLES_HH_OLD
+#define DUMUX_3P3C_VOLUME_VARIABLES_HH_OLD
 
-#include <dumux/implicit/model.hh>
-#include <dumux/material/constants.hh>
-#include <dumux/material/fluidstates/compositionalfluidstate.hh>
-#include <dumux/material/constraintsolvers/computefromreferencephase.hh>
-#include <dumux/material/constraintsolvers/misciblemultiphasecomposition.hh>
-#include "3p3cproperties.hh"
+#warning this header is deprecated, use dumux/porousmediumflow/3p3c/implicit/volumevariables.hh instead
 
-namespace Dumux
-{
-
-/*!
- * \ingroup ThreePThreeCModel
- * \ingroup ImplicitVolumeVariables
- * \brief Contains the quantities which are are constant within a
- *        finite volume in the three-phase three-component model.
- */
-template <class TypeTag>
-class ThreePThreeCVolumeVariables : public ImplicitVolumeVariables<TypeTag>
-{
-    typedef ImplicitVolumeVariables<TypeTag> ParentType;
-    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) Implementation;
-
-    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
-    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
-    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
-    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
-    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
-    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
-    typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw;
-    typedef typename GET_PROP_TYPE(TypeTag, MaterialLawParams) MaterialLawParams;
-
-    // constraint solvers
-    typedef Dumux::MiscibleMultiPhaseComposition<Scalar, FluidSystem> MiscibleMultiPhaseComposition;
-    typedef Dumux::ComputeFromReferencePhase<Scalar, FluidSystem> ComputeFromReferencePhase;
-
-    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
-    enum {
-        dim = GridView::dimension,
-
-        numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
-        numComponents = GET_PROP_VALUE(TypeTag, NumComponents),
-
-        wCompIdx = Indices::wCompIdx,
-        gCompIdx = Indices::gCompIdx,
-        nCompIdx = Indices::nCompIdx,
-
-        wPhaseIdx = Indices::wPhaseIdx,
-        gPhaseIdx = Indices::gPhaseIdx,
-        nPhaseIdx = Indices::nPhaseIdx,
-
-        switch1Idx = Indices::switch1Idx,
-        switch2Idx = Indices::switch2Idx,
-        pressureIdx = Indices::pressureIdx
-    };
-
-    // present phases
-    enum {
-        threePhases = Indices::threePhases,
-        wPhaseOnly  = Indices::wPhaseOnly,
-        gnPhaseOnly = Indices::gnPhaseOnly,
-        wnPhaseOnly = Indices::wnPhaseOnly,
-        gPhaseOnly  = Indices::gPhaseOnly,
-        wgPhaseOnly = Indices::wgPhaseOnly
-    };
-
-    typedef typename GridView::template Codim<0>::Entity Element;
-
-    static const Scalar R; // universial gas constant
-
-    enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) };
-    enum { dofCodim = isBox ? dim : 0 };
-
-public:
-
-   typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState;
-
-    /*!
-     * \copydoc ImplicitVolumeVariables::update
-     */
-    void update(const PrimaryVariables &priVars,
-                const Problem &problem,
-                const Element &element,
-                const FVElementGeometry &fvGeometry,
-                const int scvIdx,
-                bool isOldSol)
-    {
-        ParentType::update(priVars,
-                           problem,
-                           element,
-                           fvGeometry,
-                           scvIdx,
-                           isOldSol);
-
-        bool useConstraintSolver = GET_PROP_VALUE(TypeTag, UseConstraintSolver);
-
-        // capillary pressure parameters
-        const MaterialLawParams &materialParams =
-            problem.spatialParams().materialLawParams(element, fvGeometry, scvIdx);
-
-        int dofIdxGlobal = problem.model().dofMapper().subIndex(element, scvIdx, dofCodim);
-        int phasePresence = problem.model().phasePresence(dofIdxGlobal, isOldSol);
-
-        Scalar temp = Implementation::temperature_(priVars, problem, element, fvGeometry, scvIdx);
-        fluidState_.setTemperature(temp);
-
-        /* first the saturations */
-        if (phasePresence == threePhases)
-        {
-            sw_ = priVars[switch1Idx];
-            sn_ = priVars[switch2Idx];
-            sg_ = 1. - sw_ - sn_;
-        }
-        else if (phasePresence == wPhaseOnly)
-        {
-            sw_ = 1.;
-            sn_ = 0.;
-            sg_ = 0.;
-        }
-        else if (phasePresence == gnPhaseOnly)
-        {
-            sw_ = 0.;
-            sn_ = priVars[switch2Idx];
-            sg_ = 1. - sn_;
-        }
-        else if (phasePresence == wnPhaseOnly)
-        {
-            sn_ = priVars[switch2Idx];
-            sw_ = 1. - sn_;
-            sg_ = 0.;
-        }
-        else if (phasePresence == gPhaseOnly)
-        {
-            sw_ = 0.;
-            sn_ = 0.;
-            sg_ = 1.;
-        }
-        else if (phasePresence == wgPhaseOnly)
-        {
-            sw_ = priVars[switch1Idx];
-            sn_ = 0.;
-            sg_ = 1. - sw_;
-        }
-        else DUNE_THROW(Dune::InvalidStateException, "phasePresence: " << phasePresence << " is invalid.");
-        Valgrind::CheckDefined(sg_);
-
-        fluidState_.setSaturation(wPhaseIdx, sw_);
-        fluidState_.setSaturation(gPhaseIdx, sg_);
-        fluidState_.setSaturation(nPhaseIdx, sn_);
-
-        /* now the pressures */
-        pg_ = priVars[pressureIdx];
-
-        // calculate capillary pressures
-        Scalar pcgw = MaterialLaw::pcgw(materialParams, sw_);
-        Scalar pcnw = MaterialLaw::pcnw(materialParams, sw_);
-        Scalar pcgn = MaterialLaw::pcgn(materialParams, sw_ + sn_);
-
-        Scalar pcAlpha = MaterialLaw::pcAlpha(materialParams, sn_);
-        Scalar pcNW1 = 0.0; // TODO: this should be possible to assign in the problem file
-
-        pn_ = pg_- pcAlpha * pcgn - (1.-pcAlpha)*(pcgw - pcNW1);
-        pw_ = pn_ - pcAlpha * pcnw - (1.-pcAlpha)*pcNW1;
-
-        fluidState_.setPressure(wPhaseIdx, pw_);
-        fluidState_.setPressure(gPhaseIdx, pg_);
-        fluidState_.setPressure(nPhaseIdx, pn_);
-
-        // calculate and set all fugacity coefficients. this is
-        // possible because we require all phases to be an ideal
-        // mixture, i.e. fugacity coefficients are not supposed to
-        // depend on composition!
-        typename FluidSystem::ParameterCache paramCache;
-        // assert(FluidSystem::isIdealGas(gPhaseIdx));
-        for (int phaseIdx = 0; phaseIdx < numPhases; ++ phaseIdx) {
-            assert(FluidSystem::isIdealMixture(phaseIdx));
-
-            for (int compIdx = 0; compIdx < numComponents; ++ compIdx) {
-                Scalar phi = FluidSystem::fugacityCoefficient(fluidState_, paramCache, phaseIdx, compIdx);
-                fluidState_.setFugacityCoefficient(phaseIdx, compIdx, phi);
-            }
-        }
-
-        // now comes the tricky part: calculate phase composition
-        if (phasePresence == threePhases) {
-            // all phases are present, phase compositions are a
-            // result of the the gas <-> liquid equilibrium. This is
-            // the job of the "MiscibleMultiPhaseComposition"
-            // constraint solver ...
-            if (useConstraintSolver) {
-                MiscibleMultiPhaseComposition::solve(fluidState_,
-                                                     paramCache,
-                                                     /*setViscosity=*/true,
-                                                     /*setInternalEnergy=*/false);
-            }
-            // ... or calculated explicitly this way ...
-            else {
-                Scalar partPressH2O = FluidSystem::fugacityCoefficient(fluidState_,
-                                                                      wPhaseIdx,
-                                                                      wCompIdx) * pw_;
-                Scalar partPressNAPL = FluidSystem::fugacityCoefficient(fluidState_,
-                                                                       nPhaseIdx,
-                                                                       nCompIdx) * pn_;
-                Scalar partPressAir = pg_ - partPressH2O - partPressNAPL;
-
-                Scalar xgn = partPressNAPL/pg_;
-                Scalar xgw = partPressH2O/pg_;
-                Scalar xgg = partPressAir/pg_;
-
-                // actually, it's nothing else than Henry coefficient
-                Scalar xwn = partPressNAPL
-                             / (FluidSystem::fugacityCoefficient(fluidState_,
-                                                                 wPhaseIdx,nCompIdx)
-                                * pw_);
-                Scalar xwg = partPressAir
-                             / (FluidSystem::fugacityCoefficient(fluidState_,
-                                                                 wPhaseIdx,gCompIdx)
-                                * pw_);
-                Scalar xww = 1.-xwg-xwn;
-
-                Scalar xnn = 1.-2.e-10;
-                Scalar xna = 1.e-10;
-                Scalar xnw = 1.e-10;
-
-                fluidState_.setMoleFraction(wPhaseIdx, wCompIdx, xww);
-                fluidState_.setMoleFraction(wPhaseIdx, gCompIdx, xwg);
-                fluidState_.setMoleFraction(wPhaseIdx, nCompIdx, xwn);
-                fluidState_.setMoleFraction(gPhaseIdx, wCompIdx, xgw);
-                fluidState_.setMoleFraction(gPhaseIdx, gCompIdx, xgg);
-                fluidState_.setMoleFraction(gPhaseIdx, nCompIdx, xgn);
-                fluidState_.setMoleFraction(nPhaseIdx, wCompIdx, xnw);
-                fluidState_.setMoleFraction(nPhaseIdx, gCompIdx, xna);
-                fluidState_.setMoleFraction(nPhaseIdx, nCompIdx, xnn);
-
-                Scalar rhoW = FluidSystem::density(fluidState_, wPhaseIdx);
-                Scalar rhoG = FluidSystem::density(fluidState_, gPhaseIdx);
-                Scalar rhoN = FluidSystem::density(fluidState_, nPhaseIdx);
-
-                fluidState_.setDensity(wPhaseIdx, rhoW);
-                fluidState_.setDensity(gPhaseIdx, rhoG);
-                fluidState_.setDensity(nPhaseIdx, rhoN);
-            }
-        }
-        else if (phasePresence == wPhaseOnly) {
-            // only the water phase is present, water phase composition is
-            // stored explicitly.
-
-            // extract mole fractions in the water phase
-            Scalar xwg = priVars[switch1Idx];
-            Scalar xwn = priVars[switch2Idx];
-            Scalar xww = 1 - xwg - xwn;
-
-            // write water mole fractions in the fluid state
-            fluidState_.setMoleFraction(wPhaseIdx, wCompIdx, xww);
-            fluidState_.setMoleFraction(wPhaseIdx, gCompIdx, xwg);
-            fluidState_.setMoleFraction(wPhaseIdx, nCompIdx, xwn);
-
-            // calculate the composition of the remaining phases (as
-            // well as the densities of all phases). this is the job
-            // of the "ComputeFromReferencePhase" constraint solver ...
-            if (useConstraintSolver)
-            {
-                ComputeFromReferencePhase::solve(fluidState_,
-                                                 paramCache,
-                                                 wPhaseIdx,
-                                                 /*setViscosity=*/true,
-                                                 /*setInternalEnergy=*/false);
-            }
-            // ... or calculated explicitly this way ...
-            else {
-                // note that the gas phase is actually not existing!
-                // thus, this is used as phase switch criterion
-                Scalar xgg = xwg * FluidSystem::fugacityCoefficient(fluidState_,
-                                                                    wPhaseIdx,gCompIdx)
-                                   * pw_ / pg_;
-                Scalar xgn = xwn * FluidSystem::fugacityCoefficient(fluidState_,
-                                                                    wPhaseIdx,nCompIdx)
-                                   * pw_ / pg_;
-                Scalar xgw = FluidSystem::fugacityCoefficient(fluidState_,
-                                                              wPhaseIdx,wCompIdx)
-                                   * pw_ / pg_;
-
-
-                // note that the gas phase is actually not existing!
-                // thus, this is used as phase switch criterion
-                Scalar xnn = xwn * FluidSystem::fugacityCoefficient(fluidState_,
-                                                                    wPhaseIdx,nCompIdx)
-                                   * pw_;
-                Scalar xna = 1.e-10;
-                Scalar xnw = 1.e-10;
-
-                fluidState_.setMoleFraction(gPhaseIdx, wCompIdx, xgw);
-                fluidState_.setMoleFraction(gPhaseIdx, gCompIdx, xgg);
-                fluidState_.setMoleFraction(gPhaseIdx, nCompIdx, xgn);
-                fluidState_.setMoleFraction(nPhaseIdx, wCompIdx, xnw);
-                fluidState_.setMoleFraction(nPhaseIdx, gCompIdx, xna);
-                fluidState_.setMoleFraction(nPhaseIdx, nCompIdx, xnn);
-
-                Scalar rhoW = FluidSystem::density(fluidState_, wPhaseIdx);
-                Scalar rhoG = FluidSystem::density(fluidState_, gPhaseIdx);
-                Scalar rhoN = FluidSystem::density(fluidState_, nPhaseIdx);
-
-                fluidState_.setDensity(wPhaseIdx, rhoW);
-                fluidState_.setDensity(gPhaseIdx, rhoG);
-                fluidState_.setDensity(nPhaseIdx, rhoN);
-            }
-        }
-        else if (phasePresence == gnPhaseOnly) {
-            // only gas and NAPL phases are present
-            // we have all (partly hypothetical) phase pressures
-            // and temperature and the mole fraction of water in
-            // the gas phase
-
-            // we have all (partly hypothetical) phase pressures
-            // and temperature and the mole fraction of water in
-            // the gas phase
-            Scalar partPressNAPL = fluidState_.fugacityCoefficient(nPhaseIdx, nCompIdx)*pn_;
-
-            Scalar xgw = priVars[switch1Idx];
-            Scalar xgn = partPressNAPL/pg_;
-            Scalar xgg = 1.-xgw-xgn;
-
-            // write mole fractions in the fluid state
-            fluidState_.setMoleFraction(gPhaseIdx, wCompIdx, xgw);
-            fluidState_.setMoleFraction(gPhaseIdx, gCompIdx, xgg);
-            fluidState_.setMoleFraction(gPhaseIdx, nCompIdx, xgn);
-
-            // calculate the composition of the remaining phases (as
-            // well as the densities of all phases). this is the job
-            // of the "ComputeFromReferencePhase" constraint solver
-            ComputeFromReferencePhase::solve(fluidState_,
-                                             paramCache,
-                                             gPhaseIdx,
-                                             /*setViscosity=*/true,
-                                             /*setInternalEnergy=*/false);
-        }
-        else if (phasePresence == wnPhaseOnly) {
-            // only water and NAPL phases are present
-            Scalar pPartialC = fluidState_.fugacityCoefficient(nPhaseIdx,nCompIdx)*pn_;
-            Scalar henryC = fluidState_.fugacityCoefficient(wPhaseIdx,nCompIdx)*pw_;
-
-            Scalar xwg = priVars[switch1Idx];
-            Scalar xwn = pPartialC/henryC;
-            Scalar xww = 1.-xwg-xwn;
-
-            // write mole fractions in the fluid state
-            fluidState_.setMoleFraction(wPhaseIdx, wCompIdx, xww);
-            fluidState_.setMoleFraction(wPhaseIdx, gCompIdx, xwg);
-            fluidState_.setMoleFraction(wPhaseIdx, nCompIdx, xwn);
-
-            // calculate the composition of the remaining phases (as
-            // well as the densities of all phases). this is the job
-            // of the "ComputeFromReferencePhase" constraint solver
-            ComputeFromReferencePhase::solve(fluidState_,
-                                             paramCache,
-                                             wPhaseIdx,
-                                             /*setViscosity=*/true,
-                                             /*setInternalEnergy=*/false);
-        }
-        else if (phasePresence == gPhaseOnly) {
-            // only the gas phase is present, gas phase composition is
-            // stored explicitly here below.
-
-            const Scalar xgw = priVars[switch1Idx];
-            const Scalar xgn = priVars[switch2Idx];
-            Scalar xgg = 1 - xgw - xgn;
-
-            // write mole fractions in the fluid state
-            fluidState_.setMoleFraction(gPhaseIdx, wCompIdx, xgw);
-            fluidState_.setMoleFraction(gPhaseIdx, gCompIdx, xgg);
-            fluidState_.setMoleFraction(gPhaseIdx, nCompIdx, xgn);
-
-            // calculate the composition of the remaining phases (as
-            // well as the densities of all phases). this is the job
-            // of the "ComputeFromReferencePhase" constraint solver ...
-            if (useConstraintSolver)
-            {
-                ComputeFromReferencePhase::solve(fluidState_,
-                                                 paramCache,
-                                                 gPhaseIdx,
-                                                 /*setViscosity=*/true,
-                                                 /*setInternalEnergy=*/false);
-            }
-            // ... or calculated explicitly this way ...
-            else {
-
-                // note that the water phase is actually not existing!
-                // thus, this is used as phase switch criterion
-                Scalar xww = xgw * pg_
-                             / (FluidSystem::fugacityCoefficient(fluidState_,
-                                                                 wPhaseIdx,wCompIdx)
-                                * pw_);
-                Scalar xwn = 1.e-10;
-                Scalar xwg = 1.e-10;
-
-                // note that the NAPL phase is actually not existing!
-                // thus, this is used as phase switch criterion
-                Scalar xnn = xgn * pg_
-                             / (FluidSystem::fugacityCoefficient(fluidState_,
-                                                                 nPhaseIdx,nCompIdx)
-                                * pn_);
-                Scalar xna = 1.e-10;
-                Scalar xnw = 1.e-10;
-
-                fluidState_.setMoleFraction(wPhaseIdx, wCompIdx, xww);
-                fluidState_.setMoleFraction(wPhaseIdx, gCompIdx, xwg);
-                fluidState_.setMoleFraction(wPhaseIdx, nCompIdx, xwn);
-                fluidState_.setMoleFraction(nPhaseIdx, wCompIdx, xnw);
-                fluidState_.setMoleFraction(nPhaseIdx, gCompIdx, xna);
-                fluidState_.setMoleFraction(nPhaseIdx, nCompIdx, xnn);
-
-                Scalar rhoW = FluidSystem::density(fluidState_, wPhaseIdx);
-                Scalar rhoG = FluidSystem::density(fluidState_, gPhaseIdx);
-                Scalar rhoN = FluidSystem::density(fluidState_, nPhaseIdx);
-
-                fluidState_.setDensity(wPhaseIdx, rhoW);
-                fluidState_.setDensity(gPhaseIdx, rhoG);
-                fluidState_.setDensity(nPhaseIdx, rhoN);
-            }
-        }
-        else if (phasePresence == wgPhaseOnly) {
-            // only water and gas phases are present
-            Scalar xgn = priVars[switch2Idx];
-            Scalar partPressH2O = fluidState_.fugacityCoefficient(wPhaseIdx, wCompIdx)*pw_;
-
-            Scalar xgw = partPressH2O/pg_;
-            Scalar xgg = 1.-xgn-xgw;
-
-            // write mole fractions in the fluid state
-            fluidState_.setMoleFraction(gPhaseIdx, wCompIdx, xgw);
-            fluidState_.setMoleFraction(gPhaseIdx, gCompIdx, xgg);
-            fluidState_.setMoleFraction(gPhaseIdx, nCompIdx, xgn);
-
-            // calculate the composition of the remaining phases (as
-            // well as the densities of all phases). this is the job
-            // of the "ComputeFromReferencePhase" constraint solver ...
-            if (useConstraintSolver)
-            {
-                ComputeFromReferencePhase::solve(fluidState_,
-                                                 paramCache,
-                                                 gPhaseIdx,
-                                                 /*setViscosity=*/true,
-                                                 /*setInternalEnergy=*/false);
-            }
-            // ... or calculated explicitly this way ...
-            else {
-                // actually, it's nothing else than Henry coefficient
-                Scalar xwn = xgn * pg_
-                             / (FluidSystem::fugacityCoefficient(fluidState_,
-                                                                 wPhaseIdx,nCompIdx)
-                                * pw_);
-                Scalar xwg = xgg * pg_
-                             / (FluidSystem::fugacityCoefficient(fluidState_,
-                                                                 wPhaseIdx,gCompIdx)
-                                * pw_);
-                Scalar xww = 1.-xwg-xwn;
-
-                // note that the NAPL phase is actually not existing!
-                // thus, this is used as phase switch criterion
-                Scalar xnn = xgn * pg_
-                             / (FluidSystem::fugacityCoefficient(fluidState_,
-                                                                 nPhaseIdx,nCompIdx)
-                                * pn_);
-                Scalar xna = 1.e-10;
-                Scalar xnw = 1.e-10;
-
-                fluidState_.setMoleFraction(wPhaseIdx, wCompIdx, xww);
-                fluidState_.setMoleFraction(wPhaseIdx, gCompIdx, xwg);
-                fluidState_.setMoleFraction(wPhaseIdx, nCompIdx, xwn);
-                fluidState_.setMoleFraction(nPhaseIdx, wCompIdx, xnw);
-                fluidState_.setMoleFraction(nPhaseIdx, gCompIdx, xna);
-                fluidState_.setMoleFraction(nPhaseIdx, nCompIdx, xnn);
-
-                Scalar rhoW = FluidSystem::density(fluidState_, wPhaseIdx);
-                Scalar rhoG = FluidSystem::density(fluidState_, gPhaseIdx);
-                Scalar rhoN = FluidSystem::density(fluidState_, nPhaseIdx);
-
-                fluidState_.setDensity(wPhaseIdx, rhoW);
-                fluidState_.setDensity(gPhaseIdx, rhoG);
-                fluidState_.setDensity(nPhaseIdx, rhoN);
-            }
-        }
-        else
-            assert(false); // unhandled phase state
-
-        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
-            // Mobilities
-            const Scalar mu =
-                FluidSystem::viscosity(fluidState_,
-                                       paramCache,
-                                       phaseIdx);
-            fluidState_.setViscosity(phaseIdx,mu);
-
-            Scalar kr;
-            kr = MaterialLaw::kr(materialParams, phaseIdx,
-                                 fluidState_.saturation(wPhaseIdx),
-                                 fluidState_.saturation(nPhaseIdx),
-                                 fluidState_.saturation(gPhaseIdx));
-            mobility_[phaseIdx] = kr / mu;
-            Valgrind::CheckDefined(mobility_[phaseIdx]);
-        }
-
-        // material dependent parameters for NAPL adsorption
-        bulkDensTimesAdsorpCoeff_ =
-            MaterialLaw::bulkDensTimesAdsorpCoeff(materialParams);
-
-        /* ATTENTION: The conversion to effective diffusion parameters
-         *            for the porous media happens at another place!
-         */
-
-        // diffusivity coefficents
-        diffusionCoefficient_[gPhaseIdx][wCompIdx] =
-            FluidSystem::diffusionCoefficient(fluidState_,
-                                              paramCache,
-                                              gPhaseIdx,
-                                              wCompIdx);
-        diffusionCoefficient_[gPhaseIdx][nCompIdx] =
-            FluidSystem::diffusionCoefficient(fluidState_,
-                                              paramCache,
-                                              gPhaseIdx,
-                                              nCompIdx);
-        diffusionCoefficient_[gPhaseIdx][gCompIdx] = 0.0; // dummy, should not be used !
-
-        diffusionCoefficient_[wPhaseIdx][gCompIdx] =
-            FluidSystem::diffusionCoefficient(fluidState_,
-                                              paramCache,
-                                              wPhaseIdx,
-                                              gCompIdx);
-        diffusionCoefficient_[wPhaseIdx][nCompIdx] =
-            FluidSystem::diffusionCoefficient(fluidState_,
-                                              paramCache,
-                                              wPhaseIdx,
-                                              nCompIdx);
-        diffusionCoefficient_[wPhaseIdx][wCompIdx] = 0.0; // dummy, should not be used !
-
-        /* no diffusion in NAPL phase considered  at the moment */
-        diffusionCoefficient_[nPhaseIdx][nCompIdx] = 0.0;
-        diffusionCoefficient_[nPhaseIdx][wCompIdx] = 0.0;
-        diffusionCoefficient_[nPhaseIdx][gCompIdx] = 0.0;
-
-        Valgrind::CheckDefined(diffusionCoefficient_);
-
-        // porosity
-        porosity_ = problem.spatialParams().porosity(element,
-                                                         fvGeometry,
-                                                         scvIdx);
-        Valgrind::CheckDefined(porosity_);
-
-        // energy related quantities not contained in the fluid state
-        asImp_().updateEnergy_(priVars, problem, element, fvGeometry, scvIdx, isOldSol);
-        // compute and set the enthalpy
-        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
-        {
-            Scalar h = Implementation::enthalpy_(fluidState_, paramCache, phaseIdx);
-            fluidState_.setEnthalpy(phaseIdx, h);
-        }
-    }
-
-    /*!
-     * \brief Returns the phase state for the control volume.
-     */
-    const FluidState &fluidState() const
-    { return fluidState_; }
-
-    /*!
-     * \brief Returns the effective saturation of a given phase within
-     *        the control volume.
-     *
-     * \param phaseIdx The phase index
-     */
-    Scalar saturation(const int phaseIdx) const
-    { return fluidState_.saturation(phaseIdx); }
-
-    /*!
-     * \brief Returns the mass fraction of a given component in a
-     *        given phase within the control volume in \f$[-]\f$.
-     *
-     * \param phaseIdx The phase index
-     * \param compIdx The component index
-     */
-    Scalar massFraction(const int phaseIdx, const int compIdx) const
-    { return fluidState_.massFraction(phaseIdx, compIdx); }
-
-    /*!
-     * \brief Returns the mole fraction of a given component in a
-     *        given phase within the control volume in \f$[-]\f$.
-     *
-     * \param phaseIdx The phase index
-     * \param compIdx The component index
-     */
-    Scalar moleFraction(const int phaseIdx, const int compIdx) const
-    { return fluidState_.moleFraction(phaseIdx, compIdx); }
-
-    /*!
-     * \brief Returns the mass density of a given phase within the
-     *        control volume.
-     *
-     * \param phaseIdx The phase index
-     */
-    Scalar density(const int phaseIdx) const
-    { return fluidState_.density(phaseIdx); }
-
-    /*!
-     * \brief Returns the molar density of a given phase within the
-     *        control volume.
-     *
-     * \param phaseIdx The phase index
-     */
-    Scalar molarDensity(const int phaseIdx) const
-    { return fluidState_.density(phaseIdx) / fluidState_.averageMolarMass(phaseIdx); }
-
-    /*!
-     * \brief Returns the effective pressure of a given phase within
-     *        the control volume.
-     *
-     * \param phaseIdx The phase index
-     */
-    Scalar pressure(const int phaseIdx) const
-    { return fluidState_.pressure(phaseIdx); }
-
-    /*!
-     * \brief Returns temperature inside the sub-control volume.
-     *
-     * Note that we assume thermodynamic equilibrium, i.e. the
-     * temperatures of the rock matrix and of all fluid phases are
-     * identical.
-     */
-    Scalar temperature() const
-    { return fluidState_.temperature(/*phaseIdx=*/0); }
-
-    /*!
-     * \brief Returns the effective mobility of a given phase within
-     *        the control volume.
-     *
-     * \param phaseIdx The phase index
-     */
-    Scalar mobility(const int phaseIdx) const
-    {
-        return mobility_[phaseIdx];
-    }
-
-    /*!
-     * \brief Returns the effective capillary pressure within the control volume.
-     */
-    Scalar capillaryPressure() const
-    { return fluidState_.capillaryPressure(); }
-
-    /*!
-     * \brief Returns the average porosity within the control volume.
-     */
-    Scalar porosity() const
-    { return porosity_; }
-
-    /*!
-     * \brief Returns the diffusivity coefficient matrix.
-     */
-    Dune::FieldMatrix<Scalar, numPhases, numComponents> diffusionCoefficient() const
-    { return diffusionCoefficient_; }
-
-    /*!
-     * \brief Returns the adsorption information.
-     */
-    Scalar bulkDensTimesAdsorpCoeff() const
-    { return bulkDensTimesAdsorpCoeff_; }
-
-
-protected:
-
-    static Scalar temperature_(const PrimaryVariables &priVars,
-                               const Problem &problem,
-                               const Element &element,
-                               const FVElementGeometry &fvGeometry,
-                               const int scvIdx)
-    {
-        return problem.temperatureAtPos(fvGeometry.subContVol[scvIdx].global);
-    }
-
-    /*!
-     * \brief Called by update() to compute the energy related quantities
-     */
-    void updateEnergy_(const PrimaryVariables &priVars,
-                       const Problem &problem,
-                       const Element &element,
-                       const FVElementGeometry &fvGeometry,
-                       const int scvIdx,
-                       bool isOldSol)
-    { }
-
-    template<class ParameterCache>
-    static Scalar enthalpy_(const FluidState& fluidState,
-                            const ParameterCache& paramCache,
-                            const int phaseIdx)
-    {
-        return 0;
-    }
-
-    Scalar sw_, sg_, sn_, pg_, pw_, pn_;
-
-    Scalar moleFrac_[numPhases][numComponents];
-    Scalar massFrac_[numPhases][numComponents];
-
-    Scalar porosity_;        //!< Effective porosity within the control volume
-    Scalar mobility_[numPhases];  //!< Effective mobility within the control volume
-    Scalar bulkDensTimesAdsorpCoeff_; //!< the basis for calculating adsorbed NAPL
-    /* We need a tensor here !! */
-    //!< Binary diffusion coefficients of the 3 components in the phases
-    Dune::FieldMatrix<Scalar, numPhases, numComponents> diffusionCoefficient_;
-    FluidState fluidState_;
-
-private:
-    Implementation &asImp_()
-    { return *static_cast<Implementation*>(this); }
-
-    const Implementation &asImp_() const
-    { return *static_cast<const Implementation*>(this); }
-};
-
-template <class TypeTag>
-const typename ThreePThreeCVolumeVariables<TypeTag>::Scalar ThreePThreeCVolumeVariables<TypeTag>::R
-                 = Constants<typename GET_PROP_TYPE(TypeTag, Scalar)>::R;
-
-} // end namespace
+#include <dumux/porousmediumflow/3p3c/implicit/volumevariables.hh>
 
 #endif
diff --git a/dumux/implicit/co2/co2model.hh b/dumux/implicit/co2/co2model.hh
index c84592435f..f4e5867e04 100644
--- a/dumux/implicit/co2/co2model.hh
+++ b/dumux/implicit/co2/co2model.hh
@@ -24,7 +24,7 @@
 #ifndef DUMUX_CO2_MODEL_HH
 #define DUMUX_CO2_MODEL_HH
 
-#include <dumux/implicit/2p2c/2p2cmodel.hh>
+#include <dumux/porousmediumflow/2p2c/implicit/model.hh>
 
 namespace Dumux
 {
diff --git a/dumux/implicit/co2/co2volumevariables.hh b/dumux/implicit/co2/co2volumevariables.hh
index 5836b604d7..d54cd52f3c 100644
--- a/dumux/implicit/co2/co2volumevariables.hh
+++ b/dumux/implicit/co2/co2volumevariables.hh
@@ -25,7 +25,7 @@
 #ifndef DUMUX_CO2_VOLUME_VARIABLES_HH
 #define DUMUX_CO2_VOLUME_VARIABLES_HH
 
-#include <dumux/implicit/2p2c/2p2cvolumevariables.hh>
+#include <dumux/porousmediumflow/2p2c/implicit/volumevariables.hh>
 
 namespace Dumux
 {
diff --git a/dumux/multidomain/2cnistokes2p2cni/2p2cnicouplinglocalresidual.hh b/dumux/multidomain/2cnistokes2p2cni/2p2cnicouplinglocalresidual.hh
index b701597f45..b8b1df939f 100644
--- a/dumux/multidomain/2cnistokes2p2cni/2p2cnicouplinglocalresidual.hh
+++ b/dumux/multidomain/2cnistokes2p2cni/2p2cnicouplinglocalresidual.hh
@@ -27,7 +27,7 @@
 #include <dune/common/deprecated.hh>
 
 #include <dumux/porousmediumflow/nonisothermal/implicit/localresidual.hh>
-#include <dumux/implicit/2p2c/2p2cproperties.hh>
+#include <dumux/porousmediumflow/2p2c/implicit/properties.hh>
 
 namespace Dumux
 {
diff --git a/dumux/multidomain/2cstokes2p2c/2cstokes2p2clocaloperator.hh b/dumux/multidomain/2cstokes2p2c/2cstokes2p2clocaloperator.hh
index 853916be13..e07fc31950 100644
--- a/dumux/multidomain/2cstokes2p2c/2cstokes2p2clocaloperator.hh
+++ b/dumux/multidomain/2cstokes2p2c/2cstokes2p2clocaloperator.hh
@@ -37,7 +37,7 @@
 #include <dumux/freeflow/boundarylayermodel.hh>
 #include <dumux/freeflow/masstransfermodel.hh>
 #include <dumux/freeflow/stokesnc/stokesncmodel.hh>
-#include <dumux/implicit/2p2c/2p2cmodel.hh>
+#include <dumux/porousmediumflow/2p2c/implicit/model.hh>
 
 
 namespace Dumux {
diff --git a/dumux/multidomain/2cstokes2p2c/2p2ccouplinglocalresidual.hh b/dumux/multidomain/2cstokes2p2c/2p2ccouplinglocalresidual.hh
index 4cf3b7688a..69f154653a 100644
--- a/dumux/multidomain/2cstokes2p2c/2p2ccouplinglocalresidual.hh
+++ b/dumux/multidomain/2cstokes2p2c/2p2ccouplinglocalresidual.hh
@@ -26,8 +26,8 @@
 
 #include <dune/common/deprecated.hh>
 
-#include <dumux/implicit/2p2c/2p2clocalresidual.hh>
-#include <dumux/implicit/2p2c/2p2cproperties.hh>
+#include <dumux/porousmediumflow/2p2c/implicit/localresidual.hh>
+#include <dumux/porousmediumflow/2p2c/implicit/properties.hh>
 
 namespace Dumux
 {
diff --git a/dumux/porousmediumflow/1p2c/implicit/fluxvariables.hh b/dumux/porousmediumflow/1p2c/implicit/fluxvariables.hh
new file mode 100644
index 0000000000..bddb873565
--- /dev/null
+++ b/dumux/porousmediumflow/1p2c/implicit/fluxvariables.hh
@@ -0,0 +1,525 @@
+// -*- 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/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ * \brief This file contains the data which is required to calculate
+ *        all fluxes of fluid phases over a face of a finite volume.
+ *
+ * This means pressure and mole-fraction gradients, phase densities at
+ * the integration point, etc.
+ *
+ */
+#ifndef DUMUX_1P2C_FLUX_VARIABLES_HH
+#define DUMUX_1P2C_FLUX_VARIABLES_HH
+
+#include "properties.hh"
+
+#include <dumux/common/math.hh>
+#include <dumux/common/valgrind.hh>
+
+namespace Dumux
+{
+
+/*!
+ * \ingroup OnePTwoCModel
+ * \ingroup ImplicitFluxVariables
+ * \brief This template class contains the data which is required to
+ *        calculate the fluxes of the fluid phases over a face of a
+ *        finite volume for the one-phase, two-component model.
+ *
+ * This means pressure and mole-fraction gradients, phase densities at
+ * the intergration point, etc.
+ */
+template <class TypeTag>
+class OnePTwoCFluxVariables
+{
+    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
+    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, SpatialParams) SpatialParams;
+    typedef typename GET_PROP_TYPE(TypeTag, EffectiveDiffusivityModel) EffectiveDiffusivityModel;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+    enum {
+        transportCompIdx = Indices::transportCompIdx
+    };
+
+    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
+    typedef typename GridView::template Codim<0>::Entity Element;
+    enum {
+        dim = GridView::dimension,
+        dimWorld = GridView::dimensionworld
+    };
+
+    typedef typename GridView::ctype CoordScalar;
+    typedef Dune::FieldVector<CoordScalar, dimWorld> GlobalPosition;
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef Dune::FieldVector<Scalar, dim> DimVector;
+    typedef Dune::FieldMatrix<Scalar, dim, dim> DimMatrix;
+    typedef Dune::FieldMatrix<Scalar, dimWorld, dimWorld> DimWorldMatrix;
+
+    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
+    typedef typename FVElementGeometry::SubControlVolumeFace SCVFace;
+
+public:
+    /*
+     * \brief The constructor
+     *
+     * \param problem The problem
+     * \param element The finite element
+     * \param fvGeometry The finite-volume geometry in the fully implicit scheme
+     * \param scvfIdx The local index of the SCV (sub-control-volume) face
+     * \param elemVolVars The volume variables of the current element
+     * \param onBoundary A boolean variable to specify whether the flux variables
+     * are calculated for interior SCV faces or boundary faces, default=false
+     */
+    OnePTwoCFluxVariables(const Problem &problem,
+                          const Element &element,
+                          const FVElementGeometry &fvGeometry,
+                          const int fIdx,
+                          const ElementVolumeVariables &elemVolVars,
+                          const bool onBoundary = false)
+        : fvGeometry_(fvGeometry), faceIdx_(fIdx), onBoundary_(onBoundary)
+    {
+        mobilityUpwindWeight_ = GET_PARAM_FROM_GROUP(TypeTag, Scalar, Implicit, MobilityUpwindWeight);
+
+        viscosity_ = Scalar(0);
+        molarDensity_ = Scalar(0);
+        density_ = Scalar(0);
+        potentialGrad_ = Scalar(0);
+        moleFractionGrad_ = Scalar(0);
+
+        calculateGradients_(problem, element, elemVolVars);
+        calculateK_(problem, element, elemVolVars);
+        calculateVelocities_(problem, element, elemVolVars);
+        calculatePorousDiffCoeff_(problem, element, elemVolVars);
+        calculateDispersionTensor_(problem, element, elemVolVars);
+    };
+
+public:
+    /*!
+    * \brief Return the pressure potential multiplied with the
+    *        intrinsic permeability  and the face normal which
+    *        goes from vertex i to vertex j.
+    *
+    * Note that the length of the face's normal is the area of the
+    * phase, so this is not the actual velocity but the integral of
+    * the velocity over the face's area. Also note that the phase
+    * mobility is not yet included here since this would require a
+    * decision on the upwinding approach (which is done in the
+    * actual model).
+    */
+   Scalar KmvpNormal() const
+   { return KmvpNormal_; }
+
+   /*!
+    * \brief Return the pressure potential multiplied with the
+    *        intrinsic permeability as vector (for velocity output).
+    */
+   GlobalPosition Kmvp() const
+   { return Kmvp_; }
+
+   /*!
+    * \brief The face of the current sub-control volume. This may be either
+    *        an inner sub-control-volume face or a SCV face on the boundary.
+    */
+   const SCVFace &face() const
+   {
+       if (onBoundary_)
+           return fvGeometry_.boundaryFace[faceIdx_];
+       else
+           return fvGeometry_.subContVolFace[faceIdx_];
+   }
+
+    /*!
+     * \brief Return the intrinsic permeability tensor \f$\mathrm{[m^2]}\f$.
+     */
+    const DimWorldMatrix &intrinsicPermeability() const
+    { return K_; }
+
+    /*!
+     * \brief Return the dispersion tensor \f$\mathrm{[m^2/s]}\f$.
+     */
+    const DimWorldMatrix &dispersionTensor() const
+    { return dispersionTensor_; }
+
+    /*!
+     * \brief Return the pressure potential gradient \f$\mathrm{[Pa/m]}\f$.
+     */
+    const GlobalPosition &potentialGrad() const
+    { return potentialGrad_; }
+
+
+    /*!
+     * \brief Return the mole-fraction gradient of a component in a phase \f$\mathrm{[mol/mol/m)]}\f$.
+     *
+     * \param compIdx The index of the considered component
+     */
+    const GlobalPosition &moleFractionGrad(int compIdx) const
+    {
+       if (compIdx != 1)
+       { DUNE_THROW(Dune::InvalidStateException,
+                "The 1p2c model is supposed to need "
+                "only the concentration gradient of "
+                "the second component!"); }
+       return moleFractionGrad_;
+    };
+
+    /*!
+    * \brief The binary diffusion coefficient for each fluid phase in the porous medium \f$\mathrm{[m^2/s]}\f$.
+    */
+    Scalar porousDiffCoeff() const
+    {
+        // TODO: tensorial porousDiffCoeff_usion coefficients
+        return porousDiffCoeff_;
+    };
+
+    /*!
+    * \brief Return viscosity \f$\mathrm{[Pa s]}\f$ of a phase at the integration
+    *        point.
+    */
+    Scalar viscosity() const
+    { return viscosity_;}
+
+    /*!
+     * \brief Return molar density \f$\mathrm{[mol/m^3]}\f$ of a phase at the integration
+     *        point.
+     */
+    Scalar molarDensity() const
+    { return molarDensity_; }
+
+    /*!
+     * \brief Return density \f$\mathrm{[kg/m^3]}\f$ of a phase at the integration
+     *        point.
+     */
+    Scalar density() const
+    { return density_; }
+
+    /*!
+     * \brief Given the intrinsic permeability times the pressure
+     *        potential gradient and SCV face normal for a phase,
+     *        return the local index of the upstream control volume
+     *        for a given phase.
+     *
+     *        \param normalFlux The flux over a face of the sub-control volume
+     */
+    int upstreamIdx(Scalar normalFlux) const
+    { return (normalFlux >= 0)?face().i:face().j; }
+
+    /*!
+     * \brief Given the intrinsic permeability times the pressure
+     *        potential gradient and SCV face normal for a phase,
+     *        return the local index of the downstream control volume
+     *        for a given phase.
+     *
+     *        \param normalFlux The flux over a face of the sub-control volume
+     */
+    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.
+    */
+    int upstreamIdx() const
+    { return upstreamIdx_; }
+
+    /*!
+     * \brief Return the local index of the downstream control volume
+     *        for a given phase.
+     */
+    int downstreamIdx() const
+    { return downstreamIdx_; }
+
+    /*!
+    * \brief Return the local index of the upstream control volume
+    *        for a given phase.
+    */
+    int upstreamIdx(int phaseIdx) const
+    { return upstreamIdx_; }
+
+    /*!
+     * \brief Return the local index of the downstream control volume
+     *        for a given phase.
+     */
+    int downstreamIdx(int phaseIdx) const
+    { return downstreamIdx_; }
+
+    /*!
+     * \brief Return the volumetric flux over a face of a given phase.
+     *
+     *        This is the calculated velocity multiplied by the unit normal
+     *        and the area of the face.
+     *        face().normal
+     *        has already the magnitude of the area.
+     *
+     * \param phaseIdx index of the phase
+     */
+    Scalar volumeFlux(const unsigned int phaseIdx) const
+    {
+        assert (phaseIdx == Indices::phaseIdx);
+        return volumeFlux_;
+    }
+
+protected:
+
+    /*!
+     * \brief Calculation of the pressure and mole-/mass-fraction gradients.
+     *
+     *        \param problem The considered problem file
+     *        \param element The considered element of the grid
+     *        \param elemVolVars The parameters stored in the considered element
+     */
+    void calculateGradients_(const Problem &problem,
+                             const Element &element,
+                             const ElementVolumeVariables &elemVolVars)
+    {
+        // loop over flux approximation points
+        for (unsigned int idx = 0; idx < face().numFap; idx++)
+        {
+            // FE gradient at vertex idx
+            const GlobalPosition &feGrad = face().grad[idx];
+
+            // index for the element volume variables
+            int volVarsIdx = face().fapIndices[idx];
+
+            // the pressure gradient
+            GlobalPosition tmp = feGrad;
+            tmp *= elemVolVars[volVarsIdx].pressure();
+            potentialGrad_ += tmp;
+
+            // the mole-fraction gradient
+            tmp = feGrad;
+            tmp *= elemVolVars[volVarsIdx].moleFraction(transportCompIdx);
+            moleFractionGrad_ += tmp;
+
+            // phase viscosity
+            viscosity_ += elemVolVars[volVarsIdx].viscosity()*face().shapeValue[idx];
+
+            //phase molar density
+            molarDensity_ += elemVolVars[volVarsIdx].molarDensity()*face().shapeValue[idx];
+
+            //phase density
+            density_ += elemVolVars[volVarsIdx].density()*face().shapeValue[idx];
+        }
+
+
+        ///////////////
+        // correct the pressure gradients by the gravitational acceleration
+        ///////////////
+        if (GET_PARAM_FROM_GROUP(TypeTag, bool, Problem, EnableGravity)) {
+            // calculate the phase density at the integration point. we
+            // only do this if the wetting phase is present in both cells
+            Scalar rhoI = elemVolVars[face().i].density();
+            Scalar rhoJ = elemVolVars[face().j].density();
+            Scalar density = (rhoI + rhoJ)/2;
+
+            // ask for the gravitational acceleration at the given SCV face
+            GlobalPosition g(problem.gravityAtPos(face().ipGlobal));
+
+            // make it a force
+            g *= density;
+
+            // calculate the final potential gradient
+            potentialGrad_ -= g;
+        }
+    }
+
+    /*!
+    * \brief Calculation of the harmonic mean of the intrinsic permeability
+    *        uses the meanK function in the boxspatialparameters.hh file in the folder
+    *        material/spatialparameters
+    *
+    *        \param problem The considered problem file
+    *        \param element The considered element of the grid
+    *        \param elemVolVars The parameters stored in the considered element
+    */
+    void calculateK_(const Problem &problem,
+                     const Element &element,
+                     const ElementVolumeVariables &elemVolVars)
+    {
+        const SpatialParams &sp = problem.spatialParams();
+        if (GET_PROP_VALUE(TypeTag, ImplicitIsBox))
+        {
+            sp.meanK(K_,
+                     sp.intrinsicPermeability(element,
+                                              fvGeometry_,
+                                              face().i),
+                     sp.intrinsicPermeability(element,
+                                              fvGeometry_,
+                                              face().j));
+        }
+        else
+        {
+            const Element& elementI = fvGeometry_.neighbors[face().i];
+            FVElementGeometry fvGeometryI;
+            fvGeometryI.subContVol[0].global = elementI.geometry().center();
+
+            const Element& elementJ = fvGeometry_.neighbors[face().j];
+            FVElementGeometry fvGeometryJ;
+            fvGeometryJ.subContVol[0].global = elementJ.geometry().center();
+
+            sp.meanK(K_,
+                     sp.intrinsicPermeability(elementI, fvGeometryI, 0),
+                     sp.intrinsicPermeability(elementJ, fvGeometryJ, 0));
+        }
+    }
+
+    /*!
+      * \brief Calculation of the velocity normal to face using Darcy's law.
+      *     Tensorial permeability is multiplied with the potential gradient and the face normal.
+      *     Identify upstream node of face.
+      *
+      *        \param problem The considered problem file
+      *        \param element The considered element of the grid
+      *        \param elemVolVars The parameters stored in the considered element
+      */
+    void calculateVelocities_(const Problem &problem,
+                              const Element &element,
+                              const ElementVolumeVariables &elemVolVars)
+    {
+        K_.mv(potentialGrad_, Kmvp_);
+        KmvpNormal_ = -(Kmvp_*face().normal);
+
+        // set the upstream and downstream vertices
+        upstreamIdx_ = face().i;
+        downstreamIdx_ = face().j;
+
+        if (KmvpNormal_ < 0)
+        {
+            std::swap(upstreamIdx_,
+                      downstreamIdx_);
+        }
+
+        volumeFlux_ = KmvpNormal_;
+        volumeFlux_ *= mobilityUpwindWeight_/elemVolVars[upstreamIdx_].viscosity()
+                    + (1.0 - mobilityUpwindWeight_)/elemVolVars[downstreamIdx_].viscosity();
+    }
+    /*!
+    * \brief Calculation of the effective diffusion coefficient.
+    *
+    *        \param problem The considered problem file
+    *        \param element The considered element of the grid
+    *        \param elemVolVars The parameters stored in the considered element
+    */
+    void calculatePorousDiffCoeff_(const Problem &problem,
+                                   const Element &element,
+                                   const ElementVolumeVariables &elemVolVars)
+    {
+        const VolumeVariables &volVarsI = elemVolVars[face().i];
+        const VolumeVariables &volVarsJ = elemVolVars[face().j];
+
+        const Scalar diffCoeffI = EffectiveDiffusivityModel::effectiveDiffusivity(volVarsI.porosity(),
+                                                                     /*sat=*/1.0,
+                                                                     volVarsI.diffCoeff());
+
+        const Scalar diffCoeffJ = EffectiveDiffusivityModel::effectiveDiffusivity(volVarsJ.porosity(),
+                                                                     /*sat=*/1.0,
+                                                                     volVarsJ.diffCoeff());
+
+        // -> harmonic mean
+        porousDiffCoeff_ = harmonicMean(diffCoeffI, diffCoeffJ);
+    }
+
+    /*!
+    * \brief Calculation of the dispersion.
+    *
+    *        \param problem The considered problem file
+    *        \param element The considered element of the grid
+    *        \param elemVolVars The parameters stored in the considered element
+    */
+    void calculateDispersionTensor_(const Problem &problem,
+                                    const Element &element,
+                                    const ElementVolumeVariables &elemVolVars)
+    {
+        const VolumeVariables &volVarsI = elemVolVars[face().i];
+        const VolumeVariables &volVarsJ = elemVolVars[face().j];
+
+        //calculate dispersivity at the interface: [0]: alphaL = longitudinal disp. [m], [1] alphaT = transverse disp. [m]
+        Scalar dispersivity[2];
+        dispersivity[0] = 0.5 * (volVarsI.dispersivity()[0] +  volVarsJ.dispersivity()[0]);
+        dispersivity[1] = 0.5 * (volVarsI.dispersivity()[1] +  volVarsJ.dispersivity()[1]);
+
+        //calculate velocity at interface: v = -1/mu * vDarcy = -1/mu * K * grad(p)
+        GlobalPosition velocity;
+        Valgrind::CheckDefined(potentialGrad());
+        Valgrind::CheckDefined(K_);
+        K_.mv(potentialGrad(), velocity);
+        velocity /= - 0.5 * (volVarsI.viscosity() + volVarsJ.viscosity());
+
+        //matrix multiplication of the velocity at the interface: vv^T
+        dispersionTensor_ = 0;
+        for (int i=0; i<dim; i++)
+            for (int j = 0; j<dim; j++)
+                dispersionTensor_[i][j] = velocity[i]*velocity[j];
+
+        //normalize velocity product --> vv^T/||v||, [m/s]
+        Scalar vNorm = velocity.two_norm();
+
+        dispersionTensor_ /= vNorm;
+        if (vNorm < 1e-20)
+            dispersionTensor_ = 0;
+
+        //multiply with dispersivity difference: vv^T/||v||*(alphaL - alphaT), [m^2/s] --> alphaL = longitudinal disp., alphaT = transverse disp.
+        dispersionTensor_ *= (dispersivity[0] - dispersivity[1]);
+
+        //add ||v||*alphaT to the main diagonal:vv^T/||v||*(alphaL - alphaT) + ||v||*alphaT, [m^2/s]
+        for (int i = 0; i<dim; i++)
+            dispersionTensor_[i][i] += vNorm*dispersivity[1];
+    }
+
+    const FVElementGeometry &fvGeometry_;
+    const int faceIdx_;
+    const bool onBoundary_;
+
+    //! pressure potential gradient
+    GlobalPosition potentialGrad_;
+    //! mole-fraction gradient
+    GlobalPosition moleFractionGrad_;
+    //! the effective diffusion coefficent in the porous medium
+    Scalar porousDiffCoeff_;
+
+    //! the dispersion tensor in the porous medium
+    DimWorldMatrix dispersionTensor_;
+
+    //! the intrinsic permeability tensor
+    DimWorldMatrix K_;
+    // intrinsic permeability times pressure potential gradient
+    GlobalPosition Kmvp_;
+    // projected on the face normal
+    Scalar KmvpNormal_;
+
+    // local index of the upwind vertex for each phase
+    int upstreamIdx_;
+    // local index of the downwind vertex for each phase
+    int downstreamIdx_;
+
+    //! viscosity of the fluid at the integration point
+    Scalar viscosity_;
+
+    //! molar densities of the fluid at the integration point
+    Scalar molarDensity_, density_;
+
+    Scalar volumeFlux_; //!< Velocity multiplied with normal (magnitude=area)
+    Scalar mobilityUpwindWeight_; //!< Upwind weight for mobility. Set to one for full upstream weighting
+};
+
+} // end namespace
+
+#endif
diff --git a/dumux/porousmediumflow/1p2c/implicit/indices.hh b/dumux/porousmediumflow/1p2c/implicit/indices.hh
new file mode 100644
index 0000000000..274b58b30f
--- /dev/null
+++ b/dumux/porousmediumflow/1p2c/implicit/indices.hh
@@ -0,0 +1,63 @@
+// -*- 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/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ * \brief Defines the primary variable and equation indices used by
+ *        the 1p2c model
+ */
+
+#ifndef DUMUX_1P2C_INDICES_HH
+#define DUMUX_1P2C_INDICES_HH
+
+#include "properties.hh"
+
+namespace Dumux
+{
+// \{
+
+/*!
+ * \ingroup OnePTwoCModel
+ * \ingroup ImplicitIndices
+ * \brief The indices for the isothermal single-phase, two-component model.
+ */
+template <class TypeTag, int PVOffset = 0>
+struct OnePTwoCIndices
+{
+
+    //! Set the default phase used by the fluid system to the first one
+    static const int phaseIdx = GET_PROP_VALUE(TypeTag, PhaseIdx);
+
+    //! Component indices
+    static const int phaseCompIdx = phaseIdx;//!< The index of the main component of the considered phase
+    //! The index of the transported (minor) component; ASSUMES phase indices of 0 and 1
+    static const int transportCompIdx = (unsigned int)(1-phaseIdx);
+
+    // Equation indices
+   static const int conti0EqIdx = PVOffset + 0; //!< continuity equation index
+   static const int transportEqIdx = PVOffset + 1; //!< transport equation index
+
+    // primary variable indices
+    static const int pressureIdx = PVOffset + 0; //!< pressure
+    static const int massOrMoleFracIdx = PVOffset + 1; //!< mole fraction of the second component
+};
+
+// \}
+}
+
+#endif
diff --git a/dumux/porousmediumflow/1p2c/implicit/localresidual.hh b/dumux/porousmediumflow/1p2c/implicit/localresidual.hh
new file mode 100644
index 0000000000..e6640cd2f5
--- /dev/null
+++ b/dumux/porousmediumflow/1p2c/implicit/localresidual.hh
@@ -0,0 +1,265 @@
+// -*- 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/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ *
+ * \brief Element-wise calculation the local Jacobian for the single-phase,
+ *        two-component model in the fully implicit scheme.
+ */
+
+#ifndef DUMUX_ONEP_TWOC_LOCAL_RESIDUAL_HH
+#define DUMUX_ONEP_TWOC_LOCAL_RESIDUAL_HH
+
+#include "properties.hh"
+
+namespace Dumux
+{
+/*!
+ *
+ * \ingroup OnePTwoCModel
+ * \ingroup ImplicitLocalResidual
+ * \brief Calculate the local Jacobian for the single-phase,
+ *        two-component model in the fully implicit scheme.
+ *
+ *  This class is used to fill the gaps in BoxLocalResidual for the 1p2c flow and transport.
+ */
+template<class TypeTag>
+class OnePTwoCLocalResidual : public GET_PROP_TYPE(TypeTag, BaseLocalResidual)
+{
+protected:
+    typedef typename GET_PROP_TYPE(TypeTag, LocalResidual) Implementation;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
+
+    enum { dim = GridView::dimension };
+    enum { dimWorld = GridView::dimensionworld };
+    typedef Dune::FieldVector<Scalar, dim> DimVector;
+    typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition;
+
+    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+
+    enum {
+        //phase index
+        phaseIdx = Indices::phaseIdx,
+        transportCompIdx = Indices::transportCompIdx
+    };
+    // indices of the equations
+    enum {
+        conti0EqIdx = Indices::conti0EqIdx,
+        transportEqIdx = Indices::transportEqIdx
+    };
+
+    //! property that defines whether mole or mass fractions are used
+    static const bool useMoles = GET_PROP_VALUE(TypeTag, UseMoles);
+
+
+
+public:
+    /*!
+     * \brief Constructor. Sets the upwind weight.
+     */
+    OnePTwoCLocalResidual()
+    {
+        // retrieve the upwind weight for the mass conservation equations. Use the value
+        // specified via the property system as default, and overwrite
+        // it by the run-time parameter from the Dune::ParameterTree
+        upwindWeight_ = GET_PARAM_FROM_GROUP(TypeTag, Scalar, Implicit, MassUpwindWeight);
+    };
+
+    /*!
+     * \brief Evaluate the amount of all conservation quantities
+     *        (e.g. phase mass) within a finite volume.
+     *
+     *        \param storage The mass of the component within the sub-control volume
+     *        \param scvIdx The index of the considered face of the sub-control volume
+     *        \param usePrevSol Evaluate function with solution of current or previous time step
+     */
+    void computeStorage(PrimaryVariables &storage, const int scvIdx, const bool usePrevSol) const
+    {
+        // 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 &elemVolVars = usePrevSol ? this->prevVolVars_() : this->curVolVars_();
+        const VolumeVariables &volVars = elemVolVars[scvIdx];
+
+        storage = 0;
+        if(useMoles) // mole-fraction formulation
+        {
+            // storage term of continuity equation- molefractions
+            //careful: molarDensity changes with moleFrac!
+            storage[conti0EqIdx] += volVars.molarDensity()*volVars.porosity();
+            // storage term of the transport equation - molefractions
+            storage[transportEqIdx] +=
+                volVars.molarDensity()*volVars.moleFraction(transportCompIdx) *
+                volVars.porosity();
+        }
+        else // mass-fraction formulation
+        {
+            // storage term of continuity equation - massfractions
+            storage[conti0EqIdx] +=
+                volVars.density()*volVars.porosity();
+            //storage term of the transport equation - massfractions
+            storage[transportEqIdx] +=
+                volVars.density() * volVars.massFraction(transportCompIdx) * volVars.porosity();
+        }
+    }
+
+    /*!
+     * \brief Evaluate the mass flux over a face of a sub-control
+     *        volume.
+     *
+     *        \param flux The flux over the SCV (sub-control-volume) face for each component
+     *        \param fIdx The index of the considered face of the sub control volume
+     *        \param onBoundary A boolean variable to specify whether the flux variables
+     *               are calculated for interior SCV faces or boundary faces, default=false
+     */
+    void computeFlux(PrimaryVariables &flux, const int fIdx, const bool onBoundary=false) const
+    {
+        flux = 0;
+        FluxVariables fluxVars(this->problem_(),
+                               this->element_(),
+                               this->fvGeometry_(),
+                               fIdx,
+                               this->curVolVars_(),
+                               onBoundary);
+
+        asImp_()->computeAdvectiveFlux(flux, fluxVars);
+        asImp_()->computeDiffusiveFlux(flux, fluxVars);
+    }
+
+    /*!
+     * \brief Evaluate the advective mass flux of all components over
+     *        a face of a sub-control volume.
+     *
+     * \param flux The advective flux over the sub-control-volume face for each component
+     * \param fluxVars The flux variables at the current SCV
+     */
+    void computeAdvectiveFlux(PrimaryVariables &flux, const FluxVariables &fluxVars) const
+    {
+        ////////
+        // advective fluxes of all components in all phases
+        ////////
+
+        // data attached to upstream and the downstream vertices
+        // of the current phase
+        const VolumeVariables &up =
+            this->curVolVars_(fluxVars.upstreamIdx());
+        const VolumeVariables &dn =
+            this->curVolVars_(fluxVars.downstreamIdx());
+
+        if(!useMoles) //mass-fraction formulation
+        {
+            // total mass flux - massfraction
+            //KmvpNormal is the Darcy velocity multiplied with the normal vector, calculated in 1p2cfluxvariables.hh
+            flux[conti0EqIdx] +=
+                fluxVars.KmvpNormal() *
+                ((     upwindWeight_)*up.density()/up.viscosity()
+                 +
+                 ((1 - upwindWeight_)*dn.density()/dn.viscosity()));
+
+            // advective flux of the second component - massfraction
+            flux[transportEqIdx] +=
+                fluxVars.KmvpNormal() *
+                ((    upwindWeight_)*up.density() * up.massFraction(transportCompIdx)/up.viscosity()
+                 +
+                 (1 - upwindWeight_)*dn.density()*dn.massFraction(transportCompIdx)/dn.viscosity());
+        }
+        else //mole-fraction formulation
+        {
+            // total mass flux - molefraction
+            //KmvpNormal is the Darcy velocity multiplied with the normal vector, calculated in 1p2cfluxvariables.hh
+            flux[conti0EqIdx] +=
+                fluxVars.KmvpNormal() *
+                ((     upwindWeight_)*up.molarDensity()/up.viscosity()
+                 +
+                 ((1 - upwindWeight_)*dn.molarDensity()/dn.viscosity()));
+
+            // advective flux of the second component -molefraction
+            flux[transportEqIdx] +=
+                fluxVars.KmvpNormal() *
+                ((    upwindWeight_)*up.molarDensity() * up.moleFraction(transportCompIdx)/up.viscosity()
+                 +
+                 (1 - upwindWeight_)*dn.molarDensity() * dn.moleFraction(transportCompIdx)/dn.viscosity());
+        }
+
+    }
+
+    /*!
+     * \brief Adds the diffusive mass flux of all components over
+     *        a face of a sub-control volume.
+     *
+     * \param flux The diffusive flux over the sub-control-volume face for each component
+     * \param fluxVars The flux variables at the current SCV
+     */
+    void computeDiffusiveFlux(PrimaryVariables &flux, const FluxVariables &fluxVars) const
+    {
+        Scalar tmp(0);
+
+        // diffusive flux of second component
+        if(useMoles) // mole-fraction formulation
+        {
+            // diffusive flux of the second component - molefraction
+            tmp = -(fluxVars.moleFractionGrad(transportCompIdx)*fluxVars.face().normal);
+            tmp *= fluxVars.porousDiffCoeff() * fluxVars.molarDensity();
+
+            // dispersive flux of second component - molefraction
+                        GlobalPosition normalDisp;
+                        fluxVars.dispersionTensor().mv(fluxVars.face().normal, normalDisp);
+                        tmp -= fluxVars.molarDensity()*
+                            (normalDisp * fluxVars.moleFractionGrad(transportCompIdx));
+
+            flux[transportEqIdx] += tmp;
+        }
+        else // mass-fraction formulation
+        {
+            // diffusive flux of the second component - massfraction
+            tmp = -(fluxVars.moleFractionGrad(transportCompIdx)*fluxVars.face().normal);
+            tmp *= fluxVars.porousDiffCoeff() * fluxVars.molarDensity();
+
+            // dispersive flux of second component - massfraction
+                       GlobalPosition normalDisp;
+                       fluxVars.dispersionTensor().mv(fluxVars.face().normal, normalDisp);
+                       tmp -= fluxVars.molarDensity()*
+                       (normalDisp * fluxVars.moleFractionGrad(transportCompIdx));
+
+            // convert it to a mass flux and add it
+            flux[transportEqIdx] += tmp * FluidSystem::molarMass(transportCompIdx);
+        }
+    }
+
+    Implementation *asImp_()
+    { return static_cast<Implementation *> (this); }
+    const Implementation *asImp_() const
+    { return static_cast<const Implementation *> (this); }
+
+private:
+    Scalar upwindWeight_;
+};
+
+}
+
+#endif
diff --git a/dumux/porousmediumflow/1p2c/implicit/model.hh b/dumux/porousmediumflow/1p2c/implicit/model.hh
new file mode 100644
index 0000000000..f8d8a9fad7
--- /dev/null
+++ b/dumux/porousmediumflow/1p2c/implicit/model.hh
@@ -0,0 +1,194 @@
+// -*- 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/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ *
+ * \brief Base class for all models which use the single-phase,
+ *        two-component fully implicit model.
+ *        Adaption of the fully implicit scheme to the one-phase two-component flow model.
+ */
+
+#ifndef DUMUX_ONEP_TWOC_MODEL_HH
+#define DUMUX_ONEP_TWOC_MODEL_HH
+
+#include <dumux/porousmediumflow/implicit/velocityoutput.hh>
+#include "properties.hh"
+
+namespace Dumux
+{
+
+/*!
+ * \ingroup OnePTwoCModel
+ * \brief Adaption of the fully implicit scheme to the one-phase two-component flow model.
+ *
+ * This model implements a one-phase flow of a compressible fluid, that consists of two components,
+ * using a standard Darcy
+ * approach as the equation for the conservation of momentum:
+ \f[
+ v = - \frac{\textbf K}{\mu}
+ \left(\textbf{grad}\, p - \varrho {\textbf g} \right)
+ \f]
+ *
+ * Gravity can be enabled or disabled via the property system.
+ * By inserting this into the continuity equation, one gets
+ \f[
+ \phi\frac{\partial \varrho}{\partial t} - \text{div} \left\{
+   \varrho \frac{\textbf K}{\mu}  \left(\textbf{grad}\, p - \varrho {\textbf g} \right)
+ \right\} = q \;,
+ \f]
+ *
+ * The transport of the components \f$\kappa \in \{ w, a \}\f$ is described by the following equation:
+ \f[
+ \phi \frac{ \partial \varrho X^\kappa}{\partial t}
+ - \text{div} \left\lbrace \varrho X^\kappa \frac{{\textbf K}}{\mu} \left( \textbf{grad}\, p -
+ \varrho {\textbf g} \right)
+ + \varrho D^\kappa_\text{pm} \frac{M^\kappa}{M_\alpha} \textbf{grad} x^\kappa \right\rbrace = q.
+ \f]
+ *
+ * All equations are discretized using a vertex-centered finite volume (box)
+ * or cell-centered finite volume scheme as spatial
+ * and the implicit Euler method as time discretization.
+ * The model is able to use either mole or mass fractions. The property useMoles can be set to either true or false in the
+ * problem file. Make sure that the according units are used in the problem setup. useMoles is set to true by default.
+ *
+ * The primary variables are the pressure \f$p\f$ and the mole or mass fraction of dissolved component \f$x\f$.
+ */
+
+template<class TypeTag >
+class OnePTwoCModel : public GET_PROP_TYPE(TypeTag, BaseModel)
+{
+    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector;
+
+    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
+    enum { dim = GridView::dimension };
+    enum { dimWorld = GridView::dimensionworld };
+
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+    enum { phaseIdx = Indices::phaseIdx };
+
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+
+    enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) };
+    enum { dofCodim = isBox ? dim : 0 };
+
+public:
+    /*!
+     * \brief \copybrief ImplicitModel::addOutputVtkFields
+     *
+     * Specialization for the OnePTwoCModel, adding pressure,
+     * mass and mole fractions, and the process rank to the VTK writer.
+     */
+    template<class MultiWriter>
+    void addOutputVtkFields(const SolutionVector &sol,
+                            MultiWriter &writer)
+    {
+        typedef Dune::BlockVector<Dune::FieldVector<double, 1> > ScalarField;
+        typedef Dune::BlockVector<Dune::FieldVector<double, dimWorld> > VectorField;
+
+        // create the required scalar fields
+        unsigned numDofs = this->numDofs();
+        ScalarField &pressure = *writer.allocateManagedBuffer(numDofs);
+        ScalarField &delp = *writer.allocateManagedBuffer(numDofs);
+        ScalarField &moleFraction0 = *writer.allocateManagedBuffer(numDofs);
+        ScalarField &moleFraction1 = *writer.allocateManagedBuffer(numDofs);
+        ScalarField &massFraction0 = *writer.allocateManagedBuffer(numDofs);
+        ScalarField &massFraction1 = *writer.allocateManagedBuffer(numDofs);
+        ScalarField &rho = *writer.allocateManagedBuffer(numDofs);
+        ScalarField &mu = *writer.allocateManagedBuffer(numDofs);
+        VectorField *velocity = writer.template allocateManagedBuffer<double, dimWorld>(numDofs);
+        ImplicitVelocityOutput<TypeTag> velocityOutput(this->problem_());
+
+        if (velocityOutput.enableOutput())
+        {
+            // initialize velocity field
+            for (unsigned int i = 0; i < numDofs; ++i)
+            {
+                (*velocity)[i] = Scalar(0);
+            }
+        }
+
+        unsigned numElements = this->gridView_().size(0);
+        ScalarField &rank = *writer.allocateManagedBuffer(numElements);
+
+        for (const auto& element : Dune::elements(this->gridView_()))
+        {
+            if(element.partitionType() == Dune::InteriorEntity)
+            {
+                int eIdx = this->problem_().model().elementMapper().index(element);
+
+                rank[eIdx] = this->gridView_().comm().rank();
+
+                FVElementGeometry fvGeometry;
+                fvGeometry.update(this->gridView_(), element);
+
+                ElementVolumeVariables elemVolVars;
+                elemVolVars.update(this->problem_(),
+                                   element,
+                                   fvGeometry,
+                                   false /* oldSol? */);
+
+                for (int scvIdx = 0; scvIdx < fvGeometry.numScv; ++scvIdx)
+                {
+                    int dofIdxGlobal = this->dofMapper().subIndex(element, scvIdx, dofCodim);
+
+                    pressure[dofIdxGlobal] = elemVolVars[scvIdx].pressure();
+                    delp[dofIdxGlobal] = elemVolVars[scvIdx].pressure() - 1e5;
+                    moleFraction0[dofIdxGlobal] = elemVolVars[scvIdx].moleFraction(0);
+                    moleFraction1[dofIdxGlobal] = elemVolVars[scvIdx].moleFraction(1);
+                    massFraction0[dofIdxGlobal] = elemVolVars[scvIdx].massFraction(0);
+                    massFraction1[dofIdxGlobal] = elemVolVars[scvIdx].massFraction(1);
+                    rho[dofIdxGlobal] = elemVolVars[scvIdx].density();
+                    mu[dofIdxGlobal] = elemVolVars[scvIdx].viscosity();
+                }
+
+                // velocity output
+                velocityOutput.calculateVelocity(*velocity, elemVolVars, fvGeometry, element, phaseIdx);
+            }
+        }
+
+        writer.attachDofData(pressure, "P", isBox);
+        writer.attachDofData(delp, "delp", isBox);
+        if (velocityOutput.enableOutput())
+        {
+            writer.attachDofData(*velocity,  "velocity", isBox, dim);
+        }
+        char nameMoleFraction0[42], nameMoleFraction1[42];
+        snprintf(nameMoleFraction0, 42, "x_%s", FluidSystem::componentName(0));
+        snprintf(nameMoleFraction1, 42, "x_%s", FluidSystem::componentName(1));
+        writer.attachDofData(moleFraction0, nameMoleFraction0, isBox);
+        writer.attachDofData(moleFraction1, nameMoleFraction1, isBox);
+
+        char nameMassFraction0[42], nameMassFraction1[42];
+        snprintf(nameMassFraction0, 42, "X_%s", FluidSystem::componentName(0));
+        snprintf(nameMassFraction1, 42, "X_%s", FluidSystem::componentName(1));
+        writer.attachDofData(massFraction0, nameMassFraction0, isBox);
+        writer.attachDofData(massFraction1, nameMassFraction1, isBox);
+        writer.attachDofData(rho, "rho", isBox);
+        writer.attachDofData(mu, "mu", isBox);
+        writer.attachCellData(rank, "process rank");
+    }
+};
+}
+
+#include "propertydefaults.hh"
+
+#endif
diff --git a/dumux/porousmediumflow/1p2c/implicit/properties.hh b/dumux/porousmediumflow/1p2c/implicit/properties.hh
new file mode 100644
index 0000000000..7736c97a54
--- /dev/null
+++ b/dumux/porousmediumflow/1p2c/implicit/properties.hh
@@ -0,0 +1,81 @@
+// -*- 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/>.   *
+ *****************************************************************************/
+/*!
+ * \ingroup Properties
+ * \ingroup ImplicitProperties
+ * \ingroup OnePTwoCModel
+ * \file
+ *
+ * \brief Defines the properties required for the single-phase,
+ *        two-component fully implicit model.
+ */
+
+#ifndef DUMUX_1P2C_PROPERTIES_HH
+#define DUMUX_1P2C_PROPERTIES_HH
+
+
+#include <dumux/implicit/box/properties.hh>
+#include <dumux/implicit/cellcentered/properties.hh>
+#include <dumux/porousmediumflow/nonisothermal/implicit/properties.hh>
+
+namespace Dumux
+{
+// \{
+namespace Properties
+{
+
+//////////////////////////////////////////////////////////////////
+// Type tags
+//////////////////////////////////////////////////////////////////
+
+//! The type tags for the implicit isothermal one-phase two-component problems
+NEW_TYPE_TAG(OnePTwoC);
+NEW_TYPE_TAG(BoxOnePTwoC, INHERITS_FROM(BoxModel, OnePTwoC));
+NEW_TYPE_TAG(CCOnePTwoC, INHERITS_FROM(CCModel, OnePTwoC));
+
+//! The type tags for the corresponding non-isothermal problems
+NEW_TYPE_TAG(OnePTwoCNI, INHERITS_FROM(OnePTwoC, NonIsothermal));
+NEW_TYPE_TAG(BoxOnePTwoCNI, INHERITS_FROM(BoxModel, OnePTwoCNI));
+NEW_TYPE_TAG(CCOnePTwoCNI, INHERITS_FROM(CCModel, OnePTwoCNI));
+
+//////////////////////////////////////////////////////////////////
+// Property tags
+//////////////////////////////////////////////////////////////////
+
+NEW_PROP_TAG(NumPhases);   //!< Number of fluid phases in the system
+NEW_PROP_TAG(PhaseIdx); //!< A phase index in to allow that a two-phase fluidsystem is used
+NEW_PROP_TAG(NumComponents);   //!< Number of fluid components in the system
+NEW_PROP_TAG(Indices); //!< Enumerations for the model
+NEW_PROP_TAG(SpatialParams); //!< The type of the spatial parameters
+NEW_PROP_TAG(EffectiveDiffusivityModel); //!< The employed model for the computation of the effective diffusivity
+NEW_PROP_TAG(FluidSystem); //!< Type of the multi-component relations
+NEW_PROP_TAG(FluidState); //!< Type of the fluid state to be used
+NEW_PROP_TAG(ImplicitMassUpwindWeight);   //!< The default value of the upwind weight
+NEW_PROP_TAG(ImplicitMobilityUpwindWeight); //!< Weight for the upwind mobility in the velocity calculation
+NEW_PROP_TAG(ProblemEnableGravity); //!< Returns whether gravity is considered in the problem
+NEW_PROP_TAG(UseMoles); //!< Defines whether mole (true) or mass (false) fractions are used
+NEW_PROP_TAG(Scaling); //!< Defines Scaling of the model
+NEW_PROP_TAG(SpatialParamsForchCoeff); //!< Property for the forchheimer coefficient
+NEW_PROP_TAG(VtkAddVelocity); //!< Returns whether velocity vectors are written into the vtk output
+
+}
+// \}
+}
+
+#endif
diff --git a/dumux/porousmediumflow/1p2c/implicit/propertydefaults.hh b/dumux/porousmediumflow/1p2c/implicit/propertydefaults.hh
new file mode 100644
index 0000000000..cd9de92b12
--- /dev/null
+++ b/dumux/porousmediumflow/1p2c/implicit/propertydefaults.hh
@@ -0,0 +1,158 @@
+// -*- 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/>.   *
+ *****************************************************************************/
+/*!
+ * \ingroup Properties
+ * \ingroup ImplicitProperties
+ * \ingroup OnePTwoCModel
+ * \file
+ *
+ * \brief Defines some default values for the properties of the the
+ *        single-phase, two-component fully implicit model.
+ */
+
+#ifndef DUMUX_1P2C_PROPERTY_DEFAULTS_HH
+#define DUMUX_1P2C_PROPERTY_DEFAULTS_HH
+
+#include "properties.hh"
+#include "model.hh"
+#include "localresidual.hh"
+#include "volumevariables.hh"
+#include "fluxvariables.hh"
+#include "indices.hh"
+
+#include <dumux/porousmediumflow/nonisothermal/implicit/propertydefaults.hh>
+#include <dumux/material/spatialparams/implicitspatialparams1p.hh>
+#include <dumux/material/fluidmatrixinteractions/diffusivitymillingtonquirk.hh>
+#include <dumux/material/fluidmatrixinteractions/1p/thermalconductivityaverage.hh>
+#include <dumux/material/fluidstates/compositionalfluidstate.hh>
+
+namespace Dumux
+{
+// \{
+namespace Properties
+{
+//////////////////////////////////////////////////////////////////
+// Property values
+//////////////////////////////////////////////////////////////////
+
+
+SET_INT_PROP(OnePTwoC, NumEq, 2); //!< set the number of equations to 2
+SET_INT_PROP(OnePTwoC, NumPhases, 1); //!< The number of phases in the 1p2c model is 1
+SET_INT_PROP(OnePTwoC, NumComponents, 2); //!< The number of components in the 1p2c model is 2
+SET_SCALAR_PROP(OnePTwoC, Scaling, 1); //!< Scaling of the model is set to 1 by default
+SET_BOOL_PROP(OnePTwoC, UseMoles, true); //!< Define that mole fractions are used in the balance equations
+
+//! Use the 1p2c local residual function for the 1p2c model
+SET_TYPE_PROP(OnePTwoC, LocalResidual, OnePTwoCLocalResidual<TypeTag>);
+
+//! define the model
+SET_TYPE_PROP(OnePTwoC, Model, OnePTwoCModel<TypeTag>);
+
+//! define the VolumeVariables
+SET_TYPE_PROP(OnePTwoC, VolumeVariables, OnePTwoCVolumeVariables<TypeTag>);
+
+//! define the FluxVariables
+SET_TYPE_PROP(OnePTwoC, FluxVariables, OnePTwoCFluxVariables<TypeTag>);
+
+/*!
+ * \brief The fluid state which is used by the volume variables to
+ *        store the thermodynamic state. This should be chosen
+ *        appropriately for the model ((non-)isothermal, equilibrium, ...).
+ *        This can be done in the problem.
+ */
+SET_PROP(OnePTwoC, FluidState){
+    private:
+        typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+        typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+    public:
+        typedef Dumux::CompositionalFluidState<Scalar, FluidSystem> type;
+};
+
+//! set default upwind weight to 1.0, i.e. fully upwind
+SET_SCALAR_PROP(OnePTwoC, ImplicitMassUpwindWeight, 1.0);
+
+//! weight for the upwind mobility in the velocity calculation
+SET_SCALAR_PROP(OnePTwoC, ImplicitMobilityUpwindWeight, 1.0);
+
+//! Set the indices used by the 1p2c model
+SET_TYPE_PROP(OnePTwoC, Indices, OnePTwoCIndices<TypeTag>);
+//! The spatial parameters to be employed.
+//! Use ImplicitSpatialParamsOneP by default.
+SET_TYPE_PROP(OnePTwoC, SpatialParams, ImplicitSpatialParamsOneP<TypeTag>);
+
+//! The model after Millington (1961) is used for the effective diffusivity
+SET_PROP(OnePTwoC, EffectiveDiffusivityModel)
+{ private :
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+ public:
+    typedef DiffusivityMillingtonQuirk<Scalar> type;
+};
+
+//! Set the phaseIndex per default to zero (important for two-phase fluidsystems).
+SET_INT_PROP(OnePTwoC, PhaseIdx, 0);
+
+// disable velocity output by default
+SET_BOOL_PROP(OnePTwoC, VtkAddVelocity, false);
+
+// enable gravity by default
+SET_BOOL_PROP(OnePTwoC, ProblemEnableGravity, true);
+
+//! default value for the forchheimer coefficient
+// Source: Ward, J.C. 1964 Turbulent flow in porous media. ASCE J. Hydraul. Div 90.
+//        Actually the Forchheimer coefficient is also a function of the dimensions of the
+//        porous medium. Taking it as a constant is only a first approximation
+//        (Nield, Bejan, Convection in porous media, 2006, p. 10)
+SET_SCALAR_PROP(OnePTwoC, SpatialParamsForchCoeff, 0.55);
+
+//! average is used as default model to compute the effective thermal heat conductivity
+SET_PROP(OnePTwoCNI, ThermalConductivityModel)
+{ private :
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+  public:
+    typedef ThermalConductivityAverage<Scalar> type;
+};
+
+//////////////////////////////////////////////////////////////////
+// Property values for isothermal model required for the general non-isothermal model
+//////////////////////////////////////////////////////////////////
+
+// set isothermal Model
+SET_TYPE_PROP(OnePTwoCNI, IsothermalModel, OnePTwoCModel<TypeTag>);
+
+// set isothermal FluxVariables
+SET_TYPE_PROP(OnePTwoCNI, IsothermalFluxVariables, OnePTwoCFluxVariables<TypeTag>);
+
+//set isothermal VolumeVariables
+SET_TYPE_PROP(OnePTwoCNI, IsothermalVolumeVariables, OnePTwoCVolumeVariables<TypeTag>);
+
+//set isothermal LocalResidual
+SET_TYPE_PROP(OnePTwoCNI, IsothermalLocalResidual, OnePTwoCLocalResidual<TypeTag>);
+
+//set isothermal Indices
+SET_TYPE_PROP(OnePTwoCNI, IsothermalIndices, OnePTwoCIndices<TypeTag>);
+
+//set isothermal NumEq
+SET_INT_PROP(OnePTwoCNI, IsothermalNumEq, 2);
+
+
+}
+// \}
+}
+
+#endif
diff --git a/dumux/porousmediumflow/1p2c/implicit/volumevariables.hh b/dumux/porousmediumflow/1p2c/implicit/volumevariables.hh
new file mode 100644
index 0000000000..1e73c90a42
--- /dev/null
+++ b/dumux/porousmediumflow/1p2c/implicit/volumevariables.hh
@@ -0,0 +1,287 @@
+// -*- 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/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ * \brief Quantities required by the single-phase, two-component box
+ *        model defined on a vertex.
+ */
+#ifndef DUMUX_1P2C_VOLUME_VARIABLES_HH
+#define DUMUX_1P2C_VOLUME_VARIABLES_HH
+
+#include <dumux/implicit/volumevariables.hh>
+
+#include "properties.hh"
+
+namespace Dumux
+{
+
+/*!
+ * \ingroup OnePTwoCModel
+ * \ingroup ImplicitVolumeVariables
+ * \brief Contains the quantities which are constant within a
+ *        finite volume in the single-phase, two-component model.
+ */
+template <class TypeTag>
+class OnePTwoCVolumeVariables : public ImplicitVolumeVariables<TypeTag>
+{
+    typedef ImplicitVolumeVariables<TypeTag> ParentType;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
+    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) Implementation;
+    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
+    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+    static const bool useMoles = GET_PROP_VALUE(TypeTag, UseMoles);
+
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+    enum {
+        phaseIdx = Indices::phaseIdx,
+        phaseCompIdx = Indices::phaseCompIdx,
+        transportCompIdx = Indices::transportCompIdx
+    };
+    //indices of primary variables
+    enum{
+        pressureIdx = Indices::pressureIdx,
+        massOrMoleFracIdx = Indices::massOrMoleFracIdx
+    };
+
+    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
+    typedef typename GridView::template Codim<0>::Entity Element;
+    enum { dim = GridView::dimension };
+    enum { dimWorld = GridView::dimensionworld };
+
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef Dune::FieldVector<Scalar,dim> DimVector;
+    typedef Dune::FieldVector<Scalar,dimWorld> GlobalPosition;
+
+public:
+
+    typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState;
+
+    /*!
+     * \copydoc ImplicitVolumeVariables::update
+     */
+    void update(const PrimaryVariables &priVars,
+                const Problem &problem,
+                const Element &element,
+                const FVElementGeometry &fvGeometry,
+                const int scvIdx,
+                const bool isOldSol)
+    {
+        ParentType::update(priVars, problem, element, fvGeometry, scvIdx, isOldSol);
+
+        //calculate all secondary variables from the primary variables and store results in fluidstate
+        completeFluidState(priVars, problem, element, fvGeometry, scvIdx, fluidState_);
+
+        porosity_ = problem.spatialParams().porosity(element, fvGeometry, scvIdx);
+
+        dispersivity_ = problem.spatialParams().dispersivity(element, fvGeometry, scvIdx);
+
+        // Second instance of a parameter cache.
+        // Could be avoided if diffusion coefficients also
+        // became part of the fluid state.
+        typename FluidSystem::ParameterCache paramCache;
+        paramCache.updatePhase(fluidState_, phaseIdx);
+
+        diffCoeff_ = FluidSystem::binaryDiffusionCoefficient(fluidState_,
+                                                             paramCache,
+                                                             phaseIdx,
+                                                             phaseCompIdx,
+                                                             transportCompIdx);
+
+        Valgrind::CheckDefined(porosity_);
+        Valgrind::CheckDefined(dispersivity_);
+        Valgrind::CheckDefined(diffCoeff_);
+
+        // energy related quantities not contained in the fluid state
+        asImp_().updateEnergy_(priVars, problem, element, fvGeometry, scvIdx, isOldSol);
+    }
+
+    /*!
+     * \copydoc ImplicitModel::completeFluidState
+     */
+    static void completeFluidState(const PrimaryVariables& priVars,
+                                   const Problem& problem,
+                                   const Element& element,
+                                   const FVElementGeometry& fvGeometry,
+                                   const int scvIdx,
+                                   FluidState& fluidState)
+    {
+        Scalar t = Implementation::temperature_(priVars, problem, element,
+                                                fvGeometry, scvIdx);
+        fluidState.setTemperature(t);
+        fluidState.setSaturation(phaseIdx, 1.);
+
+        fluidState.setPressure(phaseIdx, priVars[pressureIdx]);
+
+        if(useMoles)
+        {
+            fluidState.setMoleFraction(phaseIdx, phaseCompIdx, 1 - priVars[massOrMoleFracIdx]);
+            fluidState.setMoleFraction(phaseIdx, transportCompIdx, priVars[massOrMoleFracIdx]);
+        }
+        else
+        {
+            // setMassFraction() has only to be called 1-numComponents times
+            fluidState.setMassFraction(phaseIdx, transportCompIdx, priVars[massOrMoleFracIdx]);
+        }
+
+        typename FluidSystem::ParameterCache paramCache;
+        paramCache.updatePhase(fluidState, phaseIdx);
+
+        Scalar value;
+        value = FluidSystem::density(fluidState, paramCache, phaseIdx);
+        fluidState.setDensity(phaseIdx, value);
+        value = FluidSystem::viscosity(fluidState, paramCache, phaseIdx);
+        fluidState.setViscosity(phaseIdx, value);
+
+        // compute and set the enthalpy
+        Scalar h = Implementation::enthalpy_(fluidState, paramCache, phaseIdx);
+        fluidState.setEnthalpy(phaseIdx, h);
+    }
+
+    /*!
+     * \brief Return the fluid configuration at the given primary
+     *        variables
+     */
+    const FluidState &fluidState() const
+    { return fluidState_; }
+
+    /*!
+     * \brief Return density \f$\mathrm{[kg/m^3]}\f$ the of the fluid phase.
+     */
+    Scalar density() const
+    { return fluidState_.density(phaseIdx); }
+
+    /*!
+     * \brief Return molar density \f$\mathrm{[mol/m^3]}\f$ the of the fluid phase.
+     */
+    Scalar molarDensity() const
+    { return fluidState_.molarDensity(phaseIdx);}
+
+    /*!
+     * \brief Return mole fraction \f$\mathrm{[mol/mol]}\f$ of a component in the phase.
+     *
+     * \param compIdx The index of the component
+     */
+    Scalar moleFraction(int compIdx) const
+    { return fluidState_.moleFraction(phaseIdx, (compIdx==0)?phaseCompIdx:transportCompIdx); }
+
+    /*!
+     * \brief Return mass fraction \f$\mathrm{[kg/kg]}\f$ of a component in the phase.
+     *
+     * \param compIdx The index of the component
+     */
+    Scalar massFraction(int compIdx) const
+    { return fluidState_.massFraction(phaseIdx, (compIdx==0)?phaseCompIdx:transportCompIdx); }
+
+    /*!
+     * \brief Return concentration \f$\mathrm{[mol/m^3]}\f$  of a component in the phase.
+     *
+     * \param compIdx The index of the component
+     */
+    Scalar molarity(int compIdx) const
+    { return fluidState_.molarity(phaseIdx, (compIdx==0)?phaseCompIdx:transportCompIdx); }
+
+    /*!
+     * \brief Return the effective pressure \f$\mathrm{[Pa]}\f$ of a given phase within
+     *        the control volume.
+     */
+    Scalar pressure() const
+    { return fluidState_.pressure(phaseIdx); }
+
+    /*!
+     * \brief Return the binary diffusion coefficient \f$\mathrm{[m^2/s]}\f$ in the fluid.
+     */
+    Scalar diffCoeff() const
+    { return diffCoeff_; }
+
+    /*!
+     * \brief Returns the dispersivity of the fluid's streamlines.
+     */
+    const GlobalPosition &dispersivity() const
+    { return dispersivity_; }
+
+    /*!
+     * \brief Return temperature \f$\mathrm{[K]}\f$ inside the sub-control volume.
+     *
+     * Note that we assume thermodynamic equilibrium, i.e. the
+     * temperature of the rock matrix and of all fluid phases are
+     * identical.
+     */
+    Scalar temperature() const
+    { return fluidState_.temperature(phaseIdx); }
+
+    /*!
+     * \brief Return the dynamic viscosity \f$\mathrm{[Pa*s]}\f$ of a given phase
+     *        within the control volume.
+     */
+    Scalar viscosity() const
+    { return fluidState_.viscosity(phaseIdx); }
+
+    /*!
+     * \brief Return the average porosity \f$\mathrm{[-]}\f$ within the control volume.
+     */
+    Scalar porosity() const
+    { return porosity_; }
+
+protected:
+    static Scalar temperature_(const PrimaryVariables &priVars,
+                               const Problem& problem,
+                               const Element &element,
+                               const FVElementGeometry &fvGeometry,
+                               const int scvIdx)
+    {
+        return problem.temperatureAtPos(fvGeometry.subContVol[scvIdx].global);
+    }
+
+    template<class ParameterCache>
+    static Scalar enthalpy_(const FluidState& fluidState,
+                            const ParameterCache& paramCache,
+                            const int phaseIdx)
+    {
+        return 0;
+    }
+
+    /*!
+     * \brief Called by update() to compute the energy related quantities.
+     */
+    void updateEnergy_(const PrimaryVariables &priVars,
+                       const Problem &problem,
+                       const Element &element,
+                       const FVElementGeometry &fvGeometry,
+                       const int scvIdx,
+                       const bool isOldSol)
+    { }
+
+    Scalar porosity_;    //!< Effective porosity within the control volume
+    GlobalPosition dispersivity_;
+    Scalar diffCoeff_;
+    FluidState fluidState_;
+
+private:
+    Implementation &asImp_()
+    { return *static_cast<Implementation*>(this); }
+
+    const Implementation &asImp_() const
+    { return *static_cast<const Implementation*>(this); }
+};
+
+}// end namespace
+
+#endif
diff --git a/dumux/porousmediumflow/2p2c/implicit/fluxvariables.hh b/dumux/porousmediumflow/2p2c/implicit/fluxvariables.hh
new file mode 100644
index 0000000000..73224c6306
--- /dev/null
+++ b/dumux/porousmediumflow/2p2c/implicit/fluxvariables.hh
@@ -0,0 +1,255 @@
+// -*- 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/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ * \brief Contains the data which is required to calculate
+ *        all fluxes of components over a face of a finite volume for
+ *        the two-phase two-component model fully implicit model.
+ */
+#ifndef DUMUX_2P2C_FLUX_VARIABLES_HH
+#define DUMUX_2P2C_FLUX_VARIABLES_HH
+
+#include <dumux/common/math.hh>
+#include <dumux/common/spline.hh>
+
+#include "properties.hh"
+
+namespace Dumux
+{
+
+/*!
+ * \ingroup TwoPTwoCModel
+ * \ingroup ImplicitFluxVariables
+ * \brief Contains the data which is required to calculate
+ *        all fluxes of components over a face of a finite volume for
+ *        the two-phase two-component model fully implicit model.
+ *
+ * This means pressure and concentration gradients, phase densities at
+ * the integration point, etc.
+ */
+template <class TypeTag>
+class TwoPTwoCFluxVariables : public GET_PROP_TYPE(TypeTag, BaseFluxVariables)
+{
+    typedef typename GET_PROP_TYPE(TypeTag, BaseFluxVariables) BaseFluxVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
+    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, EffectiveDiffusivityModel) EffectiveDiffusivityModel;
+    enum { numPhases = GET_PROP_VALUE(TypeTag, NumPhases) };
+
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+    enum {
+        wPhaseIdx = Indices::wPhaseIdx,
+        nPhaseIdx = Indices::nPhaseIdx,
+        wCompIdx = Indices::wCompIdx,
+        nCompIdx = Indices::nCompIdx
+    };
+
+    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
+    typedef typename GridView::template Codim<0>::Entity Element;
+    enum { dim = GridView::dimension };
+    enum { dimWorld = GridView::dimensionworld} ;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef Dune::FieldVector<Scalar, dim> DimVector;
+    typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition;
+
+    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
+
+ public:
+    /*!
+     * \brief The constructor
+     *
+     * \param problem The problem
+     * \param element The finite element
+     * \param fvGeometry The finite-volume geometry in the fully implicit scheme
+     * \param fIdx The local index of the sub-control-volume face
+     * \param elemVolVars The volume variables of the current element
+     * \param onBoundary Evaluate flux at inner sub-control-volume face or on a boundary face
+     */
+    TwoPTwoCFluxVariables(const Problem &problem,
+                          const Element &element,
+                          const FVElementGeometry &fvGeometry,
+                          const int fIdx,
+                          const ElementVolumeVariables &elemVolVars,
+                          const bool onBoundary = false)
+        : BaseFluxVariables(problem, element, fvGeometry, fIdx, elemVolVars, onBoundary)
+    {
+        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
+            density_[phaseIdx] = Scalar(0);
+            molarDensity_[phaseIdx] = Scalar(0);
+            moleFractionGrad_[phaseIdx] = Scalar(0);
+        }
+
+        calculateValues_(problem, element, elemVolVars);
+    }
+
+ protected:
+    void calculateValues_(const Problem &problem,
+                          const Element &element,
+                          const ElementVolumeVariables &elemVolVars)
+    {
+        // calculate densities at the integration points of the face
+        GlobalPosition tmp(0.0);
+        for (unsigned int idx = 0;
+             idx < this->face().numFap;
+             idx++) // loop over adjacent vertices
+        {
+            // index for the element volume variables
+            int volVarsIdx = this->face().fapIndices[idx];
+
+            for (int phaseIdx = 0; phaseIdx < numPhases; phaseIdx++)
+            {
+                density_[phaseIdx] += elemVolVars[volVarsIdx].density(phaseIdx)*
+                    this->face().shapeValue[idx];
+                molarDensity_[phaseIdx] += elemVolVars[volVarsIdx].molarDensity(phaseIdx)*
+                    this->face().shapeValue[idx];
+            }
+        }
+
+        calculateGradients_(problem, element, elemVolVars);
+        calculatePorousDiffCoeff_(problem, element, elemVolVars);
+    }
+
+    void calculateGradients_(const Problem &problem,
+                             const Element &element,
+                             const ElementVolumeVariables &elemVolVars)
+    {
+        // calculate gradients
+        GlobalPosition tmp(0.0);
+        for (unsigned int idx = 0;
+             idx < this->face().numFap;
+             idx++) // loop over adjacent vertices
+        {
+            // FE gradient at vertex idx
+            const GlobalPosition &feGrad = this->face().grad[idx];
+
+            // index for the element volume variables
+            int volVarsIdx = this->face().fapIndices[idx];
+
+            // the mole fraction gradient of the wetting phase
+            tmp = feGrad;
+            tmp *= elemVolVars[volVarsIdx].moleFraction(wPhaseIdx, nCompIdx);
+            moleFractionGrad_[wPhaseIdx] += tmp;
+
+            // the mole fraction gradient of the non-wetting phase
+            tmp = feGrad;
+            tmp *= elemVolVars[volVarsIdx].moleFraction(nPhaseIdx, wCompIdx);
+            moleFractionGrad_[nPhaseIdx] += tmp;
+        }
+    }
+
+    Scalar rhoFactor_(int phaseIdx, int scvIdx, const ElementVolumeVariables &vDat)
+    {
+        static const Scalar eps = 1e-2;
+        const Scalar sat = vDat[scvIdx].density(phaseIdx);
+        if (sat > eps)
+            return 0.5;
+        if (sat <= 0)
+            return 0;
+
+        static const Dumux::Spline<Scalar> sp(0, eps, // x0, x1
+                                              0, 0.5, // y0, y1
+                                              0, 0); // m0, m1
+        return sp.eval(sat);
+    }
+
+    void calculatePorousDiffCoeff_(const Problem &problem,
+                                   const Element &element,
+                                   const ElementVolumeVariables &elemVolVars)
+    {
+        const VolumeVariables &volVarsI = elemVolVars[this->face().i];
+        const VolumeVariables &volVarsJ = elemVolVars[this->face().j];
+
+        // the effective diffusion coefficients at vertex i and j
+        Scalar diffCoeffI;
+        Scalar diffCoeffJ;
+
+        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
+        {
+            // make sure to only calculate diffusion coefficients
+            // for phases which exist in both finite volumes
+            if (volVarsI.saturation(phaseIdx) <= 0 || volVarsJ.saturation(phaseIdx) <= 0)
+            {
+                porousDiffCoeff_[phaseIdx] = 0.0;
+                continue;
+            }
+
+            diffCoeffI = EffectiveDiffusivityModel::effectiveDiffusivity(volVarsI.porosity(),
+                                                                         volVarsI.saturation(phaseIdx),
+                                                                         volVarsI.diffCoeff(phaseIdx));
+
+            diffCoeffJ = EffectiveDiffusivityModel::effectiveDiffusivity(volVarsJ.porosity(),
+                                                                         volVarsJ.saturation(phaseIdx),
+                                                                         volVarsJ.diffCoeff(phaseIdx));
+
+            // -> harmonic mean
+            porousDiffCoeff_[phaseIdx] = harmonicMean(diffCoeffI, diffCoeffJ);
+        }
+    }
+
+ public:
+    /*!
+     * \brief Returns the effective diffusion coefficient \f$\mathrm{[m^2/s]}\f$
+     *        for each fluid phase in the porous medium.
+     *
+     * \param phaseIdx The phase index
+     */
+    Scalar porousDiffCoeff(int phaseIdx) const
+    { return porousDiffCoeff_[phaseIdx]; };
+
+    /*!
+     * \brief Returns the density \f$\mathrm{[kg/m^3]}\f$ of a phase.
+     *
+     * \param phaseIdx The phase index
+     */
+    Scalar density(int phaseIdx) const
+    { return density_[phaseIdx]; }
+
+    /*!
+     * \brief Returns the molar density \f$\mathrm{[mol/m^3]}\f$ of a phase.
+     *
+     * \param phaseIdx The phase index
+     */
+    Scalar molarDensity(int phaseIdx) const
+    { return molarDensity_[phaseIdx]; }
+
+    /*!
+     * \brief Returns the mole fraction gradient \f$\mathrm{[1/m]}\f$
+     *        of the dissolved component in a phase.
+     *
+     * \param phaseIdx The phase index
+     */
+    const GlobalPosition &moleFractionGrad(int phaseIdx) const
+    { return moleFractionGrad_[phaseIdx]; };
+
+ protected:
+    // mole fraction gradients
+    GlobalPosition moleFractionGrad_[numPhases];
+
+    // density of each face at the integration point
+    Scalar density_[numPhases], molarDensity_[numPhases];
+
+    // the diffusion coefficient for the porous medium
+    Scalar porousDiffCoeff_[numPhases];
+};
+
+} // end namespace
+
+#endif
diff --git a/dumux/porousmediumflow/2p2c/implicit/indices.hh b/dumux/porousmediumflow/2p2c/implicit/indices.hh
new file mode 100644
index 0000000000..a3518b278f
--- /dev/null
+++ b/dumux/porousmediumflow/2p2c/implicit/indices.hh
@@ -0,0 +1,145 @@
+// -*- 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/>.   *
+ *****************************************************************************/
+
+/*!
+ * \file
+ * \brief Defines the indices required for the two-phase two-component
+ *        fully implicit model.
+ */
+#ifndef DUMUX_2P2C_INDICES_HH
+#define DUMUX_2P2C_INDICES_HH
+
+#include "properties.hh"
+
+namespace Dumux
+{
+// \{
+
+/*!
+ * \ingroup TwoPTwoCModel
+ * \ingroup ImplicitIndices
+ * \brief Enumerates the formulations which the two-phase two-component model accepts.
+ */
+struct TwoPTwoCFormulation
+{
+    static const int pwsn = 0; //!< pw and sn as primary variables
+    static const int pnsw = 1; //!< pn and sw as primary variables
+};
+
+/*!
+ * \ingroup TwoPTwoCModel
+ * \ingroup ImplicitIndices
+ * \brief The indices for the isothermal two-phase two-component model.
+ *
+ * \tparam formulation The formulation, either pwsn or pnsw.
+ * \tparam PVOffset The first index in a primary variable vector.
+ */
+template <class TypeTag,
+          int formulation = TwoPTwoCFormulation::pwsn,
+          int PVOffset = 0>
+class TwoPTwoCIndices
+{
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+
+public:
+    // Phase indices
+    static const int wPhaseIdx = FluidSystem::wPhaseIdx; //!< Index of the wetting phase
+    static const int nPhaseIdx = FluidSystem::nPhaseIdx; //!< Index of the non-wetting phase
+
+    // Component indices
+    static const int wCompIdx = FluidSystem::wCompIdx; //!< Index of the primary component of the wetting phase
+    static const int nCompIdx = FluidSystem::nCompIdx; //!< Index of the primary component of the non-wetting phase
+
+    // present phases (-> 'pseudo' primary variable)
+    static const int wPhaseOnly = 1; //!< Only the wetting phase is present
+    static const int nPhaseOnly = 0; //!< Only the non-wetting phase is present
+    static const int bothPhases = 2; //!< Both phases are present
+
+    // Primary variable indices
+    //! Index for wetting/non-wetting phase pressure (depending on the formulation) in a solution vector
+    static const int pressureIdx = PVOffset + 0;
+    //! Index of either the saturation or the mass fraction of the non-wetting/wetting phase
+    static const int switchIdx = PVOffset + 1;
+
+    //! Index for wetting phase pressure in a solution vector
+    static const int pwIdx = pressureIdx;
+    //! Index of either the saturation of the non-wetting phase or the mass fraction secondary component in the only phase
+    static const int snOrXIdx = switchIdx;
+
+    // equation indices
+    //! Index of the mass conservation equation for the first component
+    static const int conti0EqIdx = PVOffset;
+    //! Index of the mass conservation equation for the primary component of the wetting phase
+    static const int contiWEqIdx = conti0EqIdx + wCompIdx;
+    //! Index of the mass conservation equation for the primary component of the non-wetting phase
+    static const int contiNEqIdx = conti0EqIdx + nCompIdx;
+};
+
+/*!
+ * \ingroup TwoPTwoCModel
+ * \ingroup ImplicitIndices
+ * \brief The indices for the isothermal two-phase two-component model in the pn-sw
+ *        formulation.
+ *
+ * \tparam PVOffset The first index in a primary variable vector.
+ */
+template <class TypeTag, int PVOffset>
+class TwoPTwoCIndices<TypeTag, TwoPTwoCFormulation::pnsw, PVOffset>
+{
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+
+public:
+    // Phase indices
+    static const int wPhaseIdx = FluidSystem::wPhaseIdx; //!< Index of the wetting phase
+    static const int nPhaseIdx = FluidSystem::nPhaseIdx; //!< Index of the non-wetting phase
+
+    // Component indices
+    static const int wCompIdx = FluidSystem::wCompIdx; //!< Index of the primary component of the wetting phase
+    static const int nCompIdx = FluidSystem::nCompIdx; //!< Index of the primary component of the non-wetting phase
+
+    // present phases (-> 'pseudo' primary variable)
+    static const int wPhaseOnly = 1; //!< Only the wetting phase is present
+    static const int nPhaseOnly = 2; //!< Only the non-wetting phase is present
+    static const int bothPhases = 3; //!< Both phases are present
+
+    // Primary variable indices
+    //! Index for wetting/non-wetting phase pressure (depending on the formulation) in a solution vector
+    static const int pressureIdx = PVOffset + 0;
+    //! Index of either the saturation or the mass fraction of the non-wetting/wetting phase
+    static const int switchIdx = PVOffset + 1;
+
+    //! Index for non-wetting phase pressure in a solution vector
+    static const int pnIdx = pressureIdx;
+    //! Index of either the saturation of the liquid phase or the mass fraction of the secondary component in the only phase
+    static const int swOrXIdx = switchIdx;
+
+    // Equation indices
+    //! Index of the mass conservation equation for the first component
+    static const int conti0EqIdx = PVOffset;
+    //! Index of the mass conservation equation for the primary component of the wetting phase
+    static const int contiWEqIdx = conti0EqIdx + wCompIdx;
+    //! Index of the mass conservation equation for the primary component of the non-wetting phase
+    static const int contiNEqIdx = conti0EqIdx + nCompIdx;
+};
+
+// \}
+
+}
+
+#endif
diff --git a/dumux/porousmediumflow/2p2c/implicit/localresidual.hh b/dumux/porousmediumflow/2p2c/implicit/localresidual.hh
new file mode 100644
index 0000000000..bd059ad725
--- /dev/null
+++ b/dumux/porousmediumflow/2p2c/implicit/localresidual.hh
@@ -0,0 +1,507 @@
+// -*- 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/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ *
+ * \brief Element-wise calculation of the Jacobian matrix for problems
+ *        using the two-phase two-component fully implicit model.
+ */
+
+#ifndef DUMUX_2P2C_LOCAL_RESIDUAL_BASE_HH
+#define DUMUX_2P2C_LOCAL_RESIDUAL_BASE_HH
+
+#include "properties.hh"
+
+namespace Dumux
+{
+/*!
+ * \ingroup TwoPTwoCModel
+ * \ingroup ImplicitLocalResidual
+ * \brief Element-wise calculation of the Jacobian matrix for problems
+ *        using the two-phase two-component fully implicit model.
+ *
+ * This class is used to fill the gaps in ImplicitLocalResidual for the
+ * two-phase two-component flow.
+ */
+template<class TypeTag>
+class TwoPTwoCLocalResidual: public GET_PROP_TYPE(TypeTag, BaseLocalResidual)
+{
+ protected:
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, LocalResidual) Implementation;
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
+    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, ElementBoundaryTypes) ElementBoundaryTypes;
+    typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables;
+    enum
+    {
+        numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
+        numComponents = GET_PROP_VALUE(TypeTag, NumComponents)
+    };
+
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+    enum
+    {
+        contiWEqIdx = Indices::contiWEqIdx,
+        contiNEqIdx = Indices::contiNEqIdx,
+        wPhaseIdx = Indices::wPhaseIdx,
+        nPhaseIdx = Indices::nPhaseIdx,
+        wCompIdx = Indices::wCompIdx,
+        nCompIdx = Indices::nCompIdx
+    };
+
+    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
+    typedef typename GridView::template Codim<0>::Entity Element;
+
+    static constexpr unsigned int replaceCompEqIdx =
+        GET_PROP_VALUE(TypeTag, ReplaceCompEqIdx);
+
+    //! Property that defines whether mole or mass fractions are used
+    static const bool useMoles = GET_PROP_VALUE(TypeTag, UseMoles);
+
+ public:
+    /*!
+     * \brief Constructor
+     *
+     * Sets the mass upwind weight.
+     */
+    TwoPTwoCLocalResidual()
+    {
+        // retrieve the upwind weight for the mass conservation equations. Use the value
+        // specified via the property system as default, and overwrite
+        // it by the run-time parameter from the Dune::ParameterTree
+        massUpwindWeight_ = GET_PARAM_FROM_GROUP(TypeTag, Scalar, Implicit, MassUpwindWeight);
+    }
+
+    /*!
+     * \brief Evaluate the storage term of the current solution in a
+     *        single phase.
+     *
+     * \param element The element
+     * \param phaseIdx The index of the fluid phase
+     */
+    void evalPhaseStorage(const Element &element, const int phaseIdx)
+    {
+        FVElementGeometry fvGeometry;
+        fvGeometry.update(this->gridView_(), element);
+        ElementBoundaryTypes bcTypes;
+        bcTypes.update(this->problem_(), element, fvGeometry);
+        ElementVolumeVariables elemVolVars;
+        elemVolVars.update(this->problem_(), element, fvGeometry, false);
+
+        this->storageTerm_.resize(fvGeometry.numScv);
+        this->storageTerm_ = 0;
+
+        this->elemPtr_ = &element;
+        this->fvElemGeomPtr_ = &fvGeometry;
+        this->bcTypesPtr_ = &bcTypes;
+        this->prevVolVarsPtr_ = 0;
+        this->curVolVarsPtr_ = &elemVolVars;
+        evalPhaseStorage_(phaseIdx);
+    }
+
+    /*!
+     * \brief Evaluate the amount of all conservation quantities
+     *        (e.g. phase mass) within a sub-control volume.
+     *
+     *  \param storage The mass of the component within the sub-control volume
+     *  \param scvIdx The sub-control-volume index
+     *  \param usePrevSol Based on usePrevSol solution of current or previous time step is used
+     *
+     * The result should be averaged over the volume (e.g. phase mass
+     * inside a sub-control volume divided by the volume)
+     */
+    void computeStorage(PrimaryVariables &storage, const int scvIdx, bool usePrevSol) const
+    {
+        // 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 &elemVolVars = usePrevSol ? this->prevVolVars_()
+            : this->curVolVars_();
+        const VolumeVariables &volVars = elemVolVars[scvIdx];
+
+        // compute storage term of all components within all phases
+        storage = 0;
+        if(useMoles) // mole-fraction formulation
+        {
+            for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
+            {
+                for (unsigned int compIdx = contiCompIdx1_(); compIdx <= contiCompIdx2_(); ++compIdx)
+                {
+                    unsigned int eqIdx = (compIdx == wCompIdx) ? contiWEqIdx : contiNEqIdx;
+                    storage[eqIdx] += volVars.molarDensity(phaseIdx)
+                        * volVars.saturation(phaseIdx)
+                        * volVars.moleFraction(phaseIdx, compIdx);
+                 }
+                 // this is only processed if one component mass balance equation
+                 // is replaced by the total mass balance equation
+                 if (replaceCompEqIdx < numComponents)
+                     storage[replaceCompEqIdx] +=
+                         volVars.molarDensity(phaseIdx)
+                         * volVars.saturation(phaseIdx);
+            }
+            storage *= volVars.porosity();
+        }
+        else // mass-fraction formulation
+        {
+            for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
+            {
+                for (unsigned int compIdx = contiCompIdx1_(); compIdx <= contiCompIdx2_(); ++compIdx)
+                {
+                    unsigned int eqIdx = (compIdx == wCompIdx) ? contiWEqIdx : contiNEqIdx;
+                    storage[eqIdx] += volVars.density(phaseIdx)
+                        * volVars.saturation(phaseIdx)
+                        * volVars.massFraction(phaseIdx, compIdx);
+                }
+                // this is only processed if one component mass balance equation
+                // is replaced by the total mass balance equation
+                if (replaceCompEqIdx < numComponents)
+                    storage[replaceCompEqIdx] +=
+                        volVars.density(phaseIdx)
+                        * volVars.saturation(phaseIdx);
+            }
+            storage *= volVars.porosity();
+        }
+    }
+
+    /*!
+     * \brief Evaluates the total flux of all conservation quantities
+     *        over a face of a sub-control volume.
+     *
+     * \param flux The flux over the sub-control-volume face for each component
+     * \param fIdx The index of the sub-control-volume face
+     * \param onBoundary Evaluate flux at inner sub-control-volume face or on a boundary face
+     */
+    void computeFlux(PrimaryVariables &flux, const int fIdx, bool onBoundary=false) const
+    {
+        FluxVariables fluxVars(this->problem_(),
+                               this->element_(),
+                               this->fvGeometry_(),
+                               fIdx,
+                               this->curVolVars_(),
+                               onBoundary);
+
+        flux = 0;
+        asImp_()->computeAdvectiveFlux(flux, fluxVars);
+        Valgrind::CheckDefined(flux);
+        asImp_()->computeDiffusiveFlux(flux, fluxVars);
+        Valgrind::CheckDefined(flux);
+    }
+
+    /*!
+     * \brief Evaluates the advective mass flux of all components over
+     *        a face of a sub-control volume.
+     *
+     * \param flux The flux over the sub-control-volume face for each component
+     * \param fluxVars The flux variables at the current sub-control-volume face
+     */
+    void computeAdvectiveFlux(PrimaryVariables &flux, const FluxVariables &fluxVars) const
+    {
+        ////////
+        // advective fluxes of all components in all phases
+        ////////
+
+        if(useMoles) // mole-fraction formulation
+        {
+            for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
+            {
+                // data attached to upstream and the downstream vertices
+                // of the current phase
+                const VolumeVariables &up =
+                    this->curVolVars_(fluxVars.upstreamIdx(phaseIdx));
+                const VolumeVariables &dn =
+                    this->curVolVars_(fluxVars.downstreamIdx(phaseIdx));
+
+                for (unsigned int compIdx = contiCompIdx1_(); compIdx <= contiCompIdx2_(); ++compIdx)
+                {
+                    unsigned int eqIdx = (compIdx == wCompIdx) ? contiWEqIdx : contiNEqIdx;
+                    // add advective flux of current component in current
+                    // phase
+                    if (massUpwindWeight_ > 0.0)
+                        // upstream vertex
+                        flux[eqIdx] +=
+                            fluxVars.volumeFlux(phaseIdx)
+                            * massUpwindWeight_
+                            * up.molarDensity(phaseIdx)
+                            * up.moleFraction(phaseIdx, compIdx);
+                    if (massUpwindWeight_ < 1.0)
+                        // downstream vertex
+                        flux[eqIdx] +=
+                            fluxVars.volumeFlux(phaseIdx)
+                            * (1 - massUpwindWeight_)
+                            * dn.molarDensity(phaseIdx)
+                            * dn.moleFraction(phaseIdx, compIdx);
+
+                    Valgrind::CheckDefined(fluxVars.volumeFlux(phaseIdx));
+                    Valgrind::CheckDefined(up.molarDensity(phaseIdx));
+                    Valgrind::CheckDefined(up.moleFraction(phaseIdx, compIdx));
+                    Valgrind::CheckDefined(dn.molarDensity(phaseIdx));
+                    Valgrind::CheckDefined(dn.moleFraction(phaseIdx, compIdx));
+                }
+                // flux of the total mass balance;
+                // this is only processed if one component mass balance equation
+                // is replaced by a total mass balance equation
+                if (replaceCompEqIdx < numComponents)
+                {
+                    // upstream vertex
+                    if (massUpwindWeight_ > 0.0)
+                        flux[replaceCompEqIdx] +=
+                            fluxVars.volumeFlux(phaseIdx)
+                            * massUpwindWeight_
+                            * up.molarDensity(phaseIdx);
+                    // downstream vertex
+                    if (massUpwindWeight_ < 1.0)
+                        flux[replaceCompEqIdx] +=
+                            fluxVars.volumeFlux(phaseIdx)
+                            * (1 - massUpwindWeight_)
+                            * dn.molarDensity(phaseIdx);
+                    Valgrind::CheckDefined(fluxVars.volumeFlux(phaseIdx));
+                    Valgrind::CheckDefined(up.molarDensity(phaseIdx));
+                    Valgrind::CheckDefined(dn.molarDensity(phaseIdx));
+
+                }
+
+            }
+        }
+        else // mass-fraction formulation
+        {
+            for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
+            {
+                // data attached to upstream and downstream vertices
+                // of the current phase
+                const VolumeVariables &up =
+                    this->curVolVars_(fluxVars.upstreamIdx(phaseIdx));
+                const VolumeVariables &dn =
+                    this->curVolVars_(fluxVars.downstreamIdx(phaseIdx));
+
+                for (unsigned int compIdx = contiCompIdx1_(); compIdx <= contiCompIdx2_(); ++compIdx)
+                {
+                    unsigned int eqIdx = (compIdx == wCompIdx) ? contiWEqIdx : contiNEqIdx;
+                    // add advective flux of current component in current
+                    // phase
+                    if (massUpwindWeight_ > 0.0)
+                        // upstream vertex
+                        flux[eqIdx] +=
+                            fluxVars.volumeFlux(phaseIdx)
+                            * massUpwindWeight_
+                            * up.density(phaseIdx)
+                            * up.massFraction(phaseIdx, compIdx);
+                    if (massUpwindWeight_ < 1.0)
+                        // downstream vertex
+                        flux[eqIdx] +=
+                            fluxVars.volumeFlux(phaseIdx)
+                            * (1 - massUpwindWeight_)
+                            * dn.density(phaseIdx)
+                            * dn.massFraction(phaseIdx, compIdx);
+
+                    Valgrind::CheckDefined(fluxVars.volumeFlux(phaseIdx));
+                    Valgrind::CheckDefined(up.density(phaseIdx));
+                    Valgrind::CheckDefined(up.massFraction(phaseIdx, compIdx));
+                    Valgrind::CheckDefined(dn.density(phaseIdx));
+                    Valgrind::CheckDefined(dn.massFraction(phaseIdx, compIdx));
+                }
+                // flux of the total mass balance;
+                // this is only processed if one component mass balance equation
+                // is replaced by a total mass balance equation
+                if (replaceCompEqIdx < numComponents)
+                {
+                    // upstream vertex
+                    if (massUpwindWeight_ > 0.0)
+                        flux[replaceCompEqIdx] +=
+                            fluxVars.volumeFlux(phaseIdx)
+                            * massUpwindWeight_
+                            * up.density(phaseIdx);
+                    // downstream vertex
+                    if (massUpwindWeight_ < 1.0)
+                        flux[replaceCompEqIdx] +=
+                            fluxVars.volumeFlux(phaseIdx)
+                            * (1 - massUpwindWeight_)
+                            * dn.density(phaseIdx);
+                    Valgrind::CheckDefined(fluxVars.volumeFlux(phaseIdx));
+                    Valgrind::CheckDefined(up.density(phaseIdx));
+                    Valgrind::CheckDefined(dn.density(phaseIdx));
+
+                }
+
+            }
+        }
+    }
+
+    /*!
+     * \brief Evaluates the diffusive mass flux of all components over
+     *        a face of a sub-control volume.
+     *
+     * \param flux The flux over the sub-control-volume face for each component
+     * \param fluxVars The flux variables at the current sub-control-volume face
+     */
+    void computeDiffusiveFlux(PrimaryVariables &flux, const FluxVariables &fluxVars) const
+
+    {
+        if(useMoles) // mole-fraction formulation
+        {
+            // add diffusive flux of gas component in liquid phase
+            Scalar tmp = - (fluxVars.moleFractionGrad(wPhaseIdx)*fluxVars.face().normal);
+            tmp *=
+                fluxVars.porousDiffCoeff(wPhaseIdx) *
+                fluxVars.molarDensity(wPhaseIdx);
+            // add the diffusive fluxes only to the component mass balance
+            if (replaceCompEqIdx != contiNEqIdx)
+                flux[contiNEqIdx] += tmp;
+            if (replaceCompEqIdx != contiWEqIdx)
+                flux[contiWEqIdx] -= tmp;
+
+            // add diffusive flux of liquid component in non-wetting phase
+            tmp = -(fluxVars.moleFractionGrad(nPhaseIdx)*fluxVars.face().normal);
+            tmp *=
+                fluxVars.porousDiffCoeff(nPhaseIdx) *
+                fluxVars.molarDensity(nPhaseIdx);
+            // add the diffusive fluxes only to the component mass balance
+            if (replaceCompEqIdx != contiWEqIdx)
+                flux[contiWEqIdx] += tmp;
+            if (replaceCompEqIdx != contiNEqIdx)
+                flux[contiNEqIdx] -= tmp;
+        }
+        else // mass-fraction formulation
+        {
+            // add diffusive flux of gas component in liquid phase
+            Scalar tmp = - (fluxVars.moleFractionGrad(wPhaseIdx)*fluxVars.face().normal);
+            tmp *=
+                fluxVars.porousDiffCoeff(wPhaseIdx) *
+                fluxVars.molarDensity(wPhaseIdx);
+            // add the diffusive fluxes only to the component mass balance
+            if (replaceCompEqIdx != contiNEqIdx)
+                flux[contiNEqIdx] += tmp * FluidSystem::molarMass(nCompIdx);
+            if (replaceCompEqIdx != contiWEqIdx)
+                flux[contiWEqIdx] -= tmp * FluidSystem::molarMass(wCompIdx);
+
+            // add diffusive flux of liquid component in non-wetting phase
+            tmp = -(fluxVars.moleFractionGrad(nPhaseIdx)*fluxVars.face().normal);
+            tmp *=
+                fluxVars.porousDiffCoeff(nPhaseIdx) *
+                fluxVars.molarDensity(nPhaseIdx);
+            // add the diffusive fluxes only to the component mass balance
+            if (replaceCompEqIdx != contiWEqIdx)
+                flux[contiWEqIdx] += tmp * FluidSystem::molarMass(wCompIdx);
+            if (replaceCompEqIdx != contiNEqIdx)
+                flux[contiNEqIdx] -= tmp * FluidSystem::molarMass(nCompIdx);
+        }
+    }
+
+ protected:
+    void evalPhaseStorage_(const int phaseIdx)
+    {
+        if(useMoles) // mole-fraction formulation
+        {
+            // evaluate the storage terms of a single phase
+            for (int i=0; i < this->fvGeometry_().numScv; i++) {
+                PrimaryVariables &storage = this->storageTerm_[i];
+                const ElementVolumeVariables &elemVolVars = this->curVolVars_();
+                const VolumeVariables &volVars = elemVolVars[i];
+
+                // compute storage term of all components within all phases
+                storage = 0;
+                for (int compIdx = 0; compIdx < numComponents; ++compIdx)
+                {
+                    int eqIdx = (compIdx == wCompIdx) ? contiWEqIdx : contiNEqIdx;
+                    storage[eqIdx] += volVars.molarDensity(phaseIdx)
+                        * volVars.saturation(phaseIdx)
+                        * volVars.moleFraction(phaseIdx, compIdx);
+                }
+
+                storage *= volVars.porosity();
+                storage *= this->fvGeometry_().subContVol[i].volume;
+            }
+        }
+        else // mass-fraction formulation
+        {
+            // evaluate the storage terms of a single phase
+            for (int i=0; i < this->fvGeometry_().numScv; i++) {
+                PrimaryVariables &storage = this->storageTerm_[i];
+                const ElementVolumeVariables &elemVolVars = this->curVolVars_();
+                const VolumeVariables &volVars = elemVolVars[i];
+
+                // compute storage term of all components within all phases
+                storage = 0;
+                for (int compIdx = 0; compIdx < numComponents; ++compIdx)
+                {
+                    int eqIdx = (compIdx == wCompIdx) ? contiWEqIdx : contiNEqIdx;
+                    storage[eqIdx] += volVars.density(phaseIdx)
+                        * volVars.saturation(phaseIdx)
+                        * volVars.massFraction(phaseIdx, compIdx);
+                }
+
+                storage *= volVars.porosity();
+                storage *= this->fvGeometry_().subContVol[i].volume;
+            }
+        }
+    }
+
+    /*!
+     * \brief Returns the equation index of the first mass-balance equation
+     *        of the component (used for loops)
+     *
+     * Returns the equation index of the first mass-balance equation
+     * of the component (used for loops) if one component mass balance
+     * is replaced by the total mass balance, this is the index
+     * of the remaining component mass-balance equation.
+     */
+    unsigned int contiCompIdx1_() const {
+        switch (replaceCompEqIdx)
+        {
+        case contiWEqIdx: return contiNEqIdx;
+        case contiNEqIdx: return contiWEqIdx;
+        default:          return 0;
+        }
+    }
+
+    /*!
+     * \brief Returns the equation index of the second mass balance
+     *        of the component (used for loops)
+     *
+     * Returns the equation index of the second mass balance
+     * of the component (used for loops)
+     * if one component mass balance is replaced by the total mass balance
+     * (replaceCompEqIdx < 2), this index is the same as contiCompIdx1().
+     */
+    unsigned int contiCompIdx2_() const {
+        switch (replaceCompEqIdx)
+        {
+        case contiWEqIdx: return contiNEqIdx;
+        case contiNEqIdx: return contiWEqIdx;
+        default:          return numComponents-1;
+        }
+    }
+
+    Implementation *asImp_()
+    { return static_cast<Implementation *> (this); }
+    const Implementation *asImp_() const
+    { return static_cast<const Implementation *> (this); }
+
+ private:
+    Scalar massUpwindWeight_;
+};
+
+} // end namespace
+
+#endif
diff --git a/dumux/porousmediumflow/2p2c/implicit/model.hh b/dumux/porousmediumflow/2p2c/implicit/model.hh
new file mode 100644
index 0000000000..d298e467b3
--- /dev/null
+++ b/dumux/porousmediumflow/2p2c/implicit/model.hh
@@ -0,0 +1,725 @@
+// -*- 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/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ *
+ * \brief Adaption of the fully implicit scheme to the
+ *        two-phase two-component fully implicit model.
+ */
+#ifndef DUMUX_2P2C_MODEL_HH
+#define DUMUX_2P2C_MODEL_HH
+
+#include "properties.hh"
+#include "indices.hh"
+#include <dumux/porousmediumflow/implicit/velocityoutput.hh>
+
+namespace Dumux
+{
+/*!
+ * \ingroup TwoPTwoCModel
+ * \brief Adaption of the fully implicit scheme to the
+ *        two-phase two-component fully implicit model.
+ *
+ * This model implements two-phase two-component flow of two compressible and
+ * partially miscible fluids \f$\alpha \in \{ w, n \}\f$ composed of the two components
+ * \f$\kappa \in \{ w, a \}\f$. The standard multiphase Darcy
+ * approach is used as the equation for the conservation of momentum:
+ * \f[
+ v_\alpha = - \frac{k_{r\alpha}}{\mu_\alpha} \mathbf{K}
+ \left(\textbf{grad}\, p_\alpha - \varrho_{\alpha} \mbox{\bf g} \right)
+ * \f]
+ *
+ * By inserting this into the equations for the conservation of the
+ * components, one gets one transport equation for each component
+ * \f{eqnarray*}
+ && \phi \frac{\partial (\sum_\alpha \varrho_\alpha \frac{M^\kappa}{M_\alpha} x_\alpha^\kappa S_\alpha )}
+ {\partial t}
+ - \sum_\alpha  \text{div} \left\{ \varrho_\alpha \frac{M^\kappa}{M_\alpha} x_\alpha^\kappa
+ \frac{k_{r\alpha}}{\mu_\alpha} \mathbf{K}
+ (\textbf{grad}\, p_\alpha - \varrho_{\alpha}  \mbox{\bf g}) \right\}
+ \nonumber \\ \nonumber \\
+ &-& \sum_\alpha \text{div} \left\{ D_{\alpha,\text{pm}}^\kappa \varrho_{\alpha} \frac{M^\kappa}{M_\alpha}
+ \textbf{grad} x^\kappa_{\alpha} \right\}
+ - \sum_\alpha q_\alpha^\kappa = 0 \qquad \kappa \in \{w, a\} \, ,
+ \alpha \in \{w, g\}
+ \f}
+ *
+ * All equations are discretized using a vertex-centered finite volume (box)
+ * or cell-centered finite volume scheme as spatial
+ * and the implicit Euler method as time discretization.
+ *
+ * By using constitutive relations for the capillary pressure \f$p_c =
+ * p_n - p_w\f$ and relative permeability \f$k_{r\alpha}\f$ and taking
+ * advantage of the fact that \f$S_w + S_n = 1\f$ and \f$x^\kappa_w + x^\kappa_n = 1\f$, the number of
+ * unknowns can be reduced to two.
+ * The used primary variables are, like in the two-phase model, either \f$p_w\f$ and \f$S_n\f$
+ * or \f$p_n\f$ and \f$S_w\f$. The formulation which ought to be used can be
+ * specified by setting the <tt>Formulation</tt> property to either
+ * TwoPTwoCIndices::pWsN or TwoPTwoCIndices::pNsW. By
+ * default, the model uses \f$p_w\f$ and \f$S_n\f$.
+ * Moreover, the second primary variable depends on the phase state, since a
+ * primary variable switch is included. The phase state is stored for all nodes
+ * of the system.
+ * The model is able to use either mole or mass fractions. The property useMoles can be set to either true or false in the
+ * problem file. Make sure that the according units are used in the problem setup. useMoles is set to true by default.
+ * Following cases can be distinguished:
+ * <ul>
+ *  <li> Both phases are present: The saturation is used (either \f$S_n\f$ or \f$S_w\f$, dependent on the chosen <tt>Formulation</tt>),
+ *      as long as \f$ 0 < S_\alpha < 1\f$</li>.
+ *  <li> Only wetting phase is present: The mole fraction of, e.g., air in the wetting phase \f$x^a_w\f$ is used,
+ *      as long as the maximum mole fraction is not exceeded \f$(x^a_w<x^a_{w,max})\f$</li>
+ *  <li> Only non-wetting phase is present: The mole fraction of, e.g., water in the non-wetting phase, \f$x^w_n\f$, is used,
+ *      as long as the maximum mole fraction is not exceeded \f$(x^w_n<x^w_{n,max})\f$</li>
+ * </ul>
+ */
+
+template<class TypeTag>
+class TwoPTwoCModel: public GET_PROP_TYPE(TypeTag, BaseModel)
+{
+    typedef typename GET_PROP_TYPE(TypeTag, BaseModel) ParentType;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
+    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector;
+    enum {
+        numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
+        numComponents = GET_PROP_VALUE(TypeTag, NumComponents)
+    };
+
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+    enum {
+        switchIdx = Indices::switchIdx,
+
+        wPhaseIdx = Indices::wPhaseIdx,
+        nPhaseIdx = Indices::nPhaseIdx,
+        wCompIdx = Indices::wCompIdx,
+        nCompIdx = Indices::nCompIdx,
+
+        wPhaseOnly = Indices::wPhaseOnly,
+        nPhaseOnly = Indices::nPhaseOnly,
+        bothPhases = Indices::bothPhases,
+
+        pwsn = TwoPTwoCFormulation::pwsn,
+        pnsw = TwoPTwoCFormulation::pnsw,
+        formulation = GET_PROP_VALUE(TypeTag, Formulation)
+    };
+
+    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
+    enum {
+        dim = GridView::dimension,
+        dimWorld = GridView::dimensionworld
+    };
+
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition;
+    static const bool useMoles = GET_PROP_VALUE(TypeTag, UseMoles);
+
+    enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) };
+    enum { dofCodim = isBox ? dim : 0 };
+
+public:
+    /*!
+     * \brief Initialize the static data with the initial solution.
+     *
+     * \param problem The problem to be solved
+     */
+    void init(Problem &problem)
+    {
+        ParentType::init(problem);
+
+        unsigned numDofs = this->numDofs();
+
+        staticDat_.resize(numDofs);
+
+        setSwitched_(false);
+
+        // check, if velocity output can be used (works only for cubes so far)
+        for (const auto& element : Dune::elements(this->gridView_()))
+        {
+            if (!isBox) // i.e. cell-centered discretization
+            {
+                int eIdxGlobal = this->dofMapper().index(element);
+                const GlobalPosition &globalPos = element.geometry().center();
+
+                // initialize phase presence
+                staticDat_[eIdxGlobal].phasePresence
+                    = this->problem_().initialPhasePresence(*(this->gridView_().template begin<dim>()),
+                                                            eIdxGlobal, globalPos);
+                staticDat_[eIdxGlobal].wasSwitched = false;
+
+                staticDat_[eIdxGlobal].oldPhasePresence
+                    = staticDat_[eIdxGlobal].phasePresence;
+            }
+        }
+
+        if (isBox) // i.e. vertex-centered discretization
+        {
+            for (const auto& vertex : Dune::vertices(this->gridView_()))
+            {
+                int vIdxGlobal = this->dofMapper().index(vertex);
+                const GlobalPosition &globalPos = vertex.geometry().corner(0);
+
+                // initialize phase presence
+                staticDat_[vIdxGlobal].phasePresence
+                    = this->problem_().initialPhasePresence(vertex, vIdxGlobal,
+                                                            globalPos);
+                staticDat_[vIdxGlobal].wasSwitched = false;
+
+                staticDat_[vIdxGlobal].oldPhasePresence
+                    = staticDat_[vIdxGlobal].phasePresence;
+            }
+        }
+    }
+
+    /*!
+     * \brief Compute the total storage of all conservation quantities in one phase
+     *
+     * \param storage Contains the storage of each component in one phase
+     * \param phaseIdx The phase index
+     */
+    void globalPhaseStorage(PrimaryVariables &storage, const int phaseIdx)
+    {
+        storage = 0;
+
+        for (const auto& element : Dune::elements(this->gridView_())) {
+            if(element.partitionType() == Dune::InteriorEntity)
+            {
+
+
+                this->localResidual().evalPhaseStorage(element, phaseIdx);
+
+                for (unsigned int i = 0; i < this->localResidual().storageTerm().size(); ++i)
+                    storage += this->localResidual().storageTerm()[i];
+            }
+        }
+        if (this->gridView_().comm().size() > 1)
+            storage = this->gridView_().comm().sum(storage);
+    }
+
+    /*!
+     * \brief Called by the update() method if applying the Newton
+     *        method was unsuccessful.
+     */
+    void updateFailed()
+    {
+        ParentType::updateFailed();
+
+        setSwitched_(false);
+        resetPhasePresence_();
+    }
+
+    /*!
+     * \brief Called by the problem if a time integration was
+     *        successful, post processing of the solution is done and the
+     *        result has been written to disk.
+     *
+     * This should prepare the model for the next time integration.
+     */
+    void advanceTimeLevel()
+    {
+        ParentType::advanceTimeLevel();
+
+        // update the phase state
+        updateOldPhasePresence_();
+        setSwitched_(false);
+    }
+
+    /*!
+     * \brief Returns true if the primary variables were switched for
+     *        at least one vertex after the last timestep.
+     */
+    bool switched() const
+    {
+        return switchFlag_;
+    }
+
+    /*!
+     * \brief Returns the phase presence of the current or the old solution of a degree of freedom.
+     *
+     * \param dofIdxGlobal The global index of the degree of freedom
+     * \param oldSol Based on oldSol current or previous time step is used
+     */
+    int phasePresence(int dofIdxGlobal, bool oldSol) const
+    {
+        return oldSol ? staticDat_[dofIdxGlobal].oldPhasePresence
+            : staticDat_[dofIdxGlobal].phasePresence;
+    }
+
+    /*!
+     * \brief Append all quantities of interest which can be derived
+     *        from the solution of the current time step to the VTK
+     *        writer.
+     *
+     * \param sol The solution vector
+     * \param writer The writer for multi-file VTK datasets
+     */
+    template<class MultiWriter>
+    void addOutputVtkFields(const SolutionVector &sol,
+                                MultiWriter &writer)
+    {
+        typedef Dune::BlockVector<Dune::FieldVector<double, 1> > ScalarField;
+        typedef Dune::BlockVector<Dune::FieldVector<double, dimWorld> > VectorField;
+
+        // get the number of degrees of freedom
+        unsigned numDofs = this->numDofs();
+
+        // create the required scalar fields
+        ScalarField *sN    = writer.allocateManagedBuffer(numDofs);
+        ScalarField *sW    = writer.allocateManagedBuffer(numDofs);
+        ScalarField *pn    = writer.allocateManagedBuffer(numDofs);
+        ScalarField *pw    = writer.allocateManagedBuffer(numDofs);
+        ScalarField *pc    = writer.allocateManagedBuffer(numDofs);
+        ScalarField *rhoW  = writer.allocateManagedBuffer(numDofs);
+        ScalarField *rhoN  = writer.allocateManagedBuffer(numDofs);
+        ScalarField *mobW  = writer.allocateManagedBuffer(numDofs);
+        ScalarField *mobN = writer.allocateManagedBuffer(numDofs);
+        ScalarField *phasePresence = writer.allocateManagedBuffer(numDofs);
+        ScalarField *massFrac[numPhases][numComponents];
+        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
+            for (int compIdx = 0; compIdx < numComponents; ++compIdx)
+                massFrac[phaseIdx][compIdx] = writer.allocateManagedBuffer(numDofs);
+        ScalarField *moleFrac[numPhases][numComponents];
+        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
+                    for (int compIdx = 0; compIdx < numComponents; ++compIdx)
+                        moleFrac[phaseIdx][compIdx] = writer.allocateManagedBuffer(numDofs);
+        ScalarField *temperature = writer.allocateManagedBuffer(numDofs);
+        ScalarField *poro = writer.allocateManagedBuffer(numDofs);
+        VectorField *velocityN = writer.template allocateManagedBuffer<double, dimWorld>(numDofs);
+        VectorField *velocityW = writer.template allocateManagedBuffer<double, dimWorld>(numDofs);
+        ImplicitVelocityOutput<TypeTag> velocityOutput(this->problem_());
+
+        if (velocityOutput.enableOutput()) // check if velocity output is demanded
+        {
+            // initialize velocity fields
+            for (unsigned int i = 0; i < numDofs; ++i)
+            {
+                (*velocityN)[i] = Scalar(0);
+                (*velocityW)[i] = Scalar(0);
+            }
+        }
+
+        unsigned numElements = this->gridView_().size(0);
+        ScalarField *rank = writer.allocateManagedBuffer(numElements);
+
+        for (const auto& element : Dune::elements(this->gridView_()))
+        {
+            if(element.partitionType() == Dune::InteriorEntity)
+            {
+                int eIdx = this->elementMapper().index(element);
+                (*rank)[eIdx] = this->gridView_().comm().rank();
+
+                FVElementGeometry fvGeometry;
+                fvGeometry.update(this->gridView_(), element);
+
+                ElementVolumeVariables elemVolVars;
+                elemVolVars.update(this->problem_(),
+                                   element,
+                                   fvGeometry,
+                                   false /* oldSol? */);
+
+                for (int scvIdx = 0; scvIdx < fvGeometry.numScv; ++scvIdx)
+                {
+                    int dofIdxGlobal = this->dofMapper().subIndex(element, scvIdx, dofCodim);
+
+                    (*sN)[dofIdxGlobal]    = elemVolVars[scvIdx].saturation(nPhaseIdx);
+                    (*sW)[dofIdxGlobal]    = elemVolVars[scvIdx].saturation(wPhaseIdx);
+                    (*pn)[dofIdxGlobal]    = elemVolVars[scvIdx].pressure(nPhaseIdx);
+                    (*pw)[dofIdxGlobal]    = elemVolVars[scvIdx].pressure(wPhaseIdx);
+                    (*pc)[dofIdxGlobal]    = elemVolVars[scvIdx].capillaryPressure();
+                    (*rhoW)[dofIdxGlobal]  = elemVolVars[scvIdx].density(wPhaseIdx);
+                    (*rhoN)[dofIdxGlobal]  = elemVolVars[scvIdx].density(nPhaseIdx);
+                    (*mobW)[dofIdxGlobal]  = elemVolVars[scvIdx].mobility(wPhaseIdx);
+                    (*mobN)[dofIdxGlobal]  = elemVolVars[scvIdx].mobility(nPhaseIdx);
+                    for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
+                        for (int compIdx = 0; compIdx < numComponents; ++compIdx)
+                        {
+                            (*massFrac[phaseIdx][compIdx])[dofIdxGlobal]
+                                = elemVolVars[scvIdx].massFraction(phaseIdx, compIdx);
+
+                            Valgrind::CheckDefined((*massFrac[phaseIdx][compIdx])[dofIdxGlobal][0]);
+                        }
+                    for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
+                        for (int compIdx = 0; compIdx < numComponents; ++compIdx)
+                        {
+                            (*moleFrac[phaseIdx][compIdx])[dofIdxGlobal]
+                                = elemVolVars[scvIdx].moleFraction(phaseIdx, compIdx);
+
+                            Valgrind::CheckDefined((*moleFrac[phaseIdx][compIdx])[dofIdxGlobal][0]);
+                        }
+                    (*poro)[dofIdxGlobal]  = elemVolVars[scvIdx].porosity();
+                    (*temperature)[dofIdxGlobal] = elemVolVars[scvIdx].temperature();
+                    (*phasePresence)[dofIdxGlobal]
+                        = staticDat_[dofIdxGlobal].phasePresence;
+                }
+
+                // velocity output
+                velocityOutput.calculateVelocity(*velocityW, elemVolVars, fvGeometry, element, wPhaseIdx);
+                velocityOutput.calculateVelocity(*velocityN, elemVolVars, fvGeometry, element, nPhaseIdx);
+            }
+
+        } // loop over elements
+
+        writer.attachDofData(*sN,     "Sn", isBox);
+        writer.attachDofData(*sW,     "Sw", isBox);
+        writer.attachDofData(*pn,     "pn", isBox);
+        writer.attachDofData(*pw,     "pw", isBox);
+        writer.attachDofData(*pc,     "pc", isBox);
+        writer.attachDofData(*rhoW,   "rhoW", isBox);
+        writer.attachDofData(*rhoN,   "rhoN", isBox);
+        writer.attachDofData(*mobW,   "mobW", isBox);
+        writer.attachDofData(*mobN,   "mobN", isBox);
+        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
+        {
+            for (int compIdx = 0; compIdx < numComponents; ++compIdx)
+            {
+                std::ostringstream oss;
+                oss << "X_" << FluidSystem::phaseName(phaseIdx) << "^" << FluidSystem::componentName(compIdx);
+                writer.attachDofData(*massFrac[phaseIdx][compIdx], oss.str(), isBox);
+            }
+        }
+        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
+        {
+            for (int compIdx = 0; compIdx < numComponents; ++compIdx)
+            {
+                std::ostringstream oss;
+                oss << "x_" << FluidSystem::phaseName(phaseIdx) << "^" << FluidSystem::componentName(compIdx);
+                writer.attachDofData(*moleFrac[phaseIdx][compIdx], oss.str(), isBox);
+            }
+        }
+        writer.attachDofData(*poro, "porosity", isBox);
+        writer.attachDofData(*temperature,    "temperature", isBox);
+        writer.attachDofData(*phasePresence,  "phase presence", isBox);
+
+        if (velocityOutput.enableOutput()) // check if velocity output is demanded
+        {
+            writer.attachDofData(*velocityW,  "velocityW", isBox, dim);
+            writer.attachDofData(*velocityN,  "velocityN", isBox, dim);
+        }
+
+        writer.attachCellData(*rank, "process rank");
+    }
+
+    /*!
+     * \brief Write the current solution to a restart file.
+     *
+     * \param outStream The output stream of one vertex for the restart file
+     * \param entity The entity, either a vertex or an element
+     */
+    template<class Entity>
+    void serializeEntity(std::ostream &outStream, const Entity &entity)
+    {
+        // write primary variables
+        ParentType::serializeEntity(outStream, entity);
+
+        int dofIdxGlobal = this->dofMapper().index(entity);
+
+        if (!outStream.good())
+            DUNE_THROW(Dune::IOError, "Could not serialize entity " << dofIdxGlobal);
+
+        outStream << staticDat_[dofIdxGlobal].phasePresence << " ";
+    }
+
+    /*!
+     * \brief Reads the current solution from a restart file.
+     *
+     * \param inStream The input stream of one vertex from the restart file
+     * \param entity The entity, either a vertex or an element
+     */
+    template<class Entity>
+    void deserializeEntity(std::istream &inStream, const Entity &entity)
+    {
+        // read primary variables
+        ParentType::deserializeEntity(inStream, entity);
+
+        // read phase presence
+        int dofIdxGlobal = this->dofMapper().index(entity);
+
+        if (!inStream.good())
+            DUNE_THROW(Dune::IOError,
+                       "Could not deserialize entity " << dofIdxGlobal);
+
+        inStream >> staticDat_[dofIdxGlobal].phasePresence;
+        staticDat_[dofIdxGlobal].oldPhasePresence
+            = staticDat_[dofIdxGlobal].phasePresence;
+
+    }
+
+    /*!
+     * \brief Update the static data of all vertices in the grid.
+     *
+     * \param curGlobalSol The current global solution
+     * \param oldGlobalSol The previous global solution
+     */
+    void updateStaticData(SolutionVector &curGlobalSol,
+                          const SolutionVector &oldGlobalSol)
+    {
+        bool wasSwitched = false;
+        int succeeded;
+        try {
+            for (unsigned i = 0; i < staticDat_.size(); ++i)
+                staticDat_[i].visited = false;
+
+            FVElementGeometry fvGeometry;
+            static VolumeVariables volVars;
+            for (const auto& element : Dune::elements(this->gridView_()))
+            {
+                fvGeometry.update(this->gridView_(), element);
+                for (int scvIdx = 0; scvIdx < fvGeometry.numScv; ++scvIdx)
+                {
+                    int dofIdxGlobal = this->dofMapper().subIndex(element, scvIdx, dofCodim);
+
+                    if (staticDat_[dofIdxGlobal].visited)
+                        continue;
+
+                    staticDat_[dofIdxGlobal].visited = true;
+                    volVars.update(curGlobalSol[dofIdxGlobal],
+                            this->problem_(),
+                            element,
+                            fvGeometry,
+                            scvIdx,
+                            false);
+                    const GlobalPosition &globalPos = fvGeometry.subContVol[scvIdx].global;
+                    if (primaryVarSwitch_(curGlobalSol,
+                            volVars,
+                            dofIdxGlobal,
+                            globalPos))
+                    {
+                        this->jacobianAssembler().markDofRed(dofIdxGlobal);
+                        wasSwitched = true;
+                    }
+                }
+            }
+            succeeded = 1;
+        }
+        catch (Dumux::NumericalProblem &e)
+        {
+            std::cout << "\n"
+                      << "Rank " << this->problem_().gridView().comm().rank()
+                      << " caught an exception while updating the static data." << e.what()
+                      << "\n";
+            succeeded = 0;
+        }
+        //make sure that all processes succeeded. If not throw a NumericalProblem to decrease the time step size.
+        if (this->gridView_().comm().size() > 1)
+            succeeded = this->gridView_().comm().min(succeeded);
+
+        if (!succeeded) {
+                DUNE_THROW(NumericalProblem,
+                        "A process did not succeed in updating the static data.");
+            return;
+        }
+
+        // make sure that if there was a variable switch in an
+        // other partition we will also set the switch flag
+        // for our partition.
+        if (this->gridView_().comm().size() > 1)
+            wasSwitched = this->gridView_().comm().max(wasSwitched);
+
+        setSwitched_(wasSwitched);
+    }
+
+ protected:
+    /*!
+     * \brief Data which is attached to each vertex and is not only
+     *        stored locally.
+     */
+    struct StaticVars
+    {
+        int phasePresence;
+        bool wasSwitched;
+
+        int oldPhasePresence;
+        bool visited;
+    };
+
+    /*!
+     * \brief Resets the current phase presence of all vertices to the old one.
+     *
+     * This is done after an update failed.
+     */
+    void resetPhasePresence_()
+    {
+        for (unsigned int idx = 0; idx < staticDat_.size(); ++idx)
+        {
+            staticDat_[idx].phasePresence
+                = staticDat_[idx].oldPhasePresence;
+            staticDat_[idx].wasSwitched = false;
+        }
+    }
+
+    /*!
+     * \brief Sets the phase presence of all vertices state to the current one.
+     */
+    void updateOldPhasePresence_()
+    {
+        for (unsigned int idx = 0; idx < staticDat_.size(); ++idx)
+        {
+            staticDat_[idx].oldPhasePresence
+                = staticDat_[idx].phasePresence;
+            staticDat_[idx].wasSwitched = false;
+        }
+    }
+
+    /*!
+     * \brief Sets whether there was a primary variable switch after
+     *        the last timestep.
+     */
+    void setSwitched_(bool yesno)
+    {
+        switchFlag_ = yesno;
+    }
+
+    /*!
+     * \brief Performs variable switch at a vertex, returns true if a
+     *        variable switch was performed.
+     */
+    bool primaryVarSwitch_(SolutionVector &globalSol,
+                           const VolumeVariables &volVars,
+                           int dofIdxGlobal,
+                           const GlobalPosition &globalPos)
+    {
+        // evaluate primary variable switch
+        bool wouldSwitch = false;
+        int phasePresence = staticDat_[dofIdxGlobal].phasePresence;
+        int newPhasePresence = phasePresence;
+
+        // check if a primary var switch is necessary
+        if (phasePresence == nPhaseOnly)
+        {
+            // calculate mole fraction in the hypothetic wetting phase
+            Scalar xww = volVars.moleFraction(wPhaseIdx, wCompIdx);
+            Scalar xwn = volVars.moleFraction(wPhaseIdx, nCompIdx);
+
+            Scalar xwMax = 1.0;
+            if (xww + xwn > xwMax)
+                wouldSwitch = true;
+            if (staticDat_[dofIdxGlobal].wasSwitched)
+                xwMax *= 1.02;
+
+            // if the sum of the mole fractions is larger than
+            // 100%, wetting phase appears
+            if (xww + xwn > xwMax)
+            {
+                // wetting phase appears
+                std::cout << "wetting phase appears at vertex " << dofIdxGlobal
+                          << ", coordinates: " << globalPos << ", xww + xwn: "
+                          << xww + xwn << std::endl;
+                newPhasePresence = bothPhases;
+                if (formulation == pnsw)
+                    globalSol[dofIdxGlobal][switchIdx] = 0.0;
+                else if (formulation == pwsn)
+                    globalSol[dofIdxGlobal][switchIdx] = 1.0;
+            }
+        }
+        else if (phasePresence == wPhaseOnly)
+        {
+            // calculate fractions of the partial pressures in the
+            // hypothetic nonwetting phase
+            Scalar xnw = volVars.moleFraction(nPhaseIdx, wCompIdx);
+            Scalar xnn = volVars.moleFraction(nPhaseIdx, nCompIdx);
+
+            Scalar xgMax = 1.0;
+            if (xnw + xnn > xgMax)
+                wouldSwitch = true;
+            if (staticDat_[dofIdxGlobal].wasSwitched)
+                xgMax *= 1.02;
+
+            // if the sum of the mole fractions is larger than
+            // 100%, nonwetting phase appears
+            if (xnw + xnn > xgMax)
+            {
+                // nonwetting phase appears
+                std::cout << "nonwetting phase appears at vertex " << dofIdxGlobal
+                          << ", coordinates: " << globalPos << ", xnw + xnn: "
+                          << xnw + xnn << std::endl;
+                newPhasePresence = bothPhases;
+                if (formulation == pnsw)
+                    globalSol[dofIdxGlobal][switchIdx] = 0.999;
+                else if (formulation == pwsn)
+                    globalSol[dofIdxGlobal][switchIdx] = 0.001;
+            }
+        }
+        else if (phasePresence == bothPhases)
+        {
+            Scalar Smin = 0.0;
+            if (staticDat_[dofIdxGlobal].wasSwitched)
+                Smin = -0.01;
+
+            if (volVars.saturation(nPhaseIdx) <= Smin)
+            {
+                wouldSwitch = true;
+                // nonwetting phase disappears
+                std::cout << "Nonwetting phase disappears at vertex " << dofIdxGlobal
+                          << ", coordinates: " << globalPos << ", sn: "
+                          << volVars.saturation(nPhaseIdx) << std::endl;
+                newPhasePresence = wPhaseOnly;
+
+                if(useMoles) // mole-fraction formulation
+                {
+                    globalSol[dofIdxGlobal][switchIdx]
+                        = volVars.moleFraction(wPhaseIdx, nCompIdx);
+                }
+                else // mass-fraction formulation
+                {
+                    globalSol[dofIdxGlobal][switchIdx]
+                        = volVars.massFraction(wPhaseIdx, nCompIdx);
+                }
+            }
+            else if (volVars.saturation(wPhaseIdx) <= Smin)
+            {
+                wouldSwitch = true;
+                // wetting phase disappears
+                std::cout << "Wetting phase disappears at vertex " << dofIdxGlobal
+                          << ", coordinates: " << globalPos << ", sw: "
+                          << volVars.saturation(wPhaseIdx) << std::endl;
+                newPhasePresence = nPhaseOnly;
+
+                if(useMoles) // mole-fraction formulation
+                {
+                    globalSol[dofIdxGlobal][switchIdx]
+                        = volVars.moleFraction(nPhaseIdx, wCompIdx);
+                }
+                else // mass-fraction formulation
+                {
+                    globalSol[dofIdxGlobal][switchIdx]
+                        = volVars.massFraction(nPhaseIdx, wCompIdx);
+                }
+            }
+        }
+
+        staticDat_[dofIdxGlobal].phasePresence = newPhasePresence;
+        staticDat_[dofIdxGlobal].wasSwitched = wouldSwitch;
+        return phasePresence != newPhasePresence;
+    }
+
+protected:
+    // parameters given in constructor
+    std::vector<StaticVars> staticDat_;
+    bool switchFlag_;
+};
+
+}
+
+#include "propertydefaults.hh"
+
+#endif
diff --git a/dumux/porousmediumflow/2p2c/implicit/newtoncontroller.hh b/dumux/porousmediumflow/2p2c/implicit/newtoncontroller.hh
new file mode 100644
index 0000000000..db9579b3c2
--- /dev/null
+++ b/dumux/porousmediumflow/2p2c/implicit/newtoncontroller.hh
@@ -0,0 +1,104 @@
+// -*- 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/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ * \brief A two-phase two-component specific controller for the Newton solver.
+ */
+#ifndef DUMUX_2P2C_NEWTON_CONTROLLER_HH
+#define DUMUX_2P2C_NEWTON_CONTROLLER_HH
+
+#include "properties.hh"
+
+#include <dumux/nonlinear/newtoncontroller.hh>
+
+namespace Dumux {
+
+/*!
+ * \ingroup Newton
+ * \ingroup TwoPTwoCModel
+ * \brief A two-phase two-component specific controller for the Newton solver.
+ *
+ * This controller 'knows' what a 'physically meaningful' solution is
+ * which allows the Newton method to abort earlier if the solution is
+ * way out of bounds.
+ */
+template <class TypeTag>
+class TwoPTwoCNewtonController : public NewtonController<TypeTag>
+{
+    typedef NewtonController<TypeTag> ParentType;
+    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
+    typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector;
+
+public:
+    TwoPTwoCNewtonController(const Problem &problem)
+        : ParentType(problem)
+    {}
+
+    /*!
+     * \brief Suggest a new time step size based either on the number of Newton
+     *        iterations required or on the variable switch
+     *
+     * \param uCurrentIter The current global solution vector
+     * \param uLastIter The previous global solution vector
+     *
+     */
+    void newtonEndStep(SolutionVector &uCurrentIter,
+                       const SolutionVector &uLastIter)
+    {
+        int succeeded;
+        try {
+            // call the method of the base class
+            this->method().model().updateStaticData(uCurrentIter, uLastIter);
+            ParentType::newtonEndStep(uCurrentIter, uLastIter);
+
+            succeeded = 1;
+            if (this->gridView_().comm().size() > 1)
+                succeeded = this->gridView_().comm().min(succeeded);
+        }
+        catch (Dumux::NumericalProblem &e)
+        {
+            std::cout << "rank " << this->problem_().gridView().comm().rank()
+                      << " caught an exception while updating:" << e.what()
+                      << "\n";
+            succeeded = 0;
+            if (this->gridView_().comm().size() > 1)
+                succeeded = this->gridView_().comm().min(succeeded);
+        }
+
+        if (!succeeded) {
+            DUNE_THROW(NumericalProblem,
+                       "A process did not succeed in linearizing the system");
+        }
+    }
+
+    /*!
+     * \brief Returns true if the current solution can be considered to
+     *        be accurate enough
+     */
+    bool newtonConverged()
+    {
+        if (this->method().model().switched())
+            return false;
+
+        return ParentType::newtonConverged();
+    }
+};
+}
+
+#endif
diff --git a/dumux/porousmediumflow/2p2c/implicit/properties.hh b/dumux/porousmediumflow/2p2c/implicit/properties.hh
new file mode 100644
index 0000000000..3f8da55d76
--- /dev/null
+++ b/dumux/porousmediumflow/2p2c/implicit/properties.hh
@@ -0,0 +1,85 @@
+// -*- 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/>.   *
+ *****************************************************************************/
+/*!
+ * \ingroup Properties
+ * \ingroup ImplicitProperties
+ * \ingroup TwoPTwoCModel
+ *
+ * \file
+ *
+ * \brief Defines the properties required for the two-phase two-component
+ *        fully implicit model.
+ */
+#ifndef DUMUX_2P2C_PROPERTIES_HH
+#define DUMUX_2P2C_PROPERTIES_HH
+
+#include <dumux/implicit/box/properties.hh>
+#include <dumux/implicit/cellcentered/properties.hh>
+#include <dumux/porousmediumflow/nonisothermal/implicit/properties.hh>
+
+namespace Dumux
+{
+
+namespace Properties
+{
+//////////////////////////////////////////////////////////////////
+// Type tags
+//////////////////////////////////////////////////////////////////
+
+//! The type tags for the implicit isothermal two-phase two-component problems
+NEW_TYPE_TAG(TwoPTwoC);
+NEW_TYPE_TAG(BoxTwoPTwoC, INHERITS_FROM(BoxModel, TwoPTwoC));
+NEW_TYPE_TAG(CCTwoPTwoC, INHERITS_FROM(CCModel, TwoPTwoC));
+
+//! The type tags for the corresponding non-isothermal problems
+NEW_TYPE_TAG(TwoPTwoCNI, INHERITS_FROM(TwoPTwoC, NonIsothermal));
+NEW_TYPE_TAG(BoxTwoPTwoCNI, INHERITS_FROM(BoxModel, TwoPTwoCNI));
+NEW_TYPE_TAG(CCTwoPTwoCNI, INHERITS_FROM(CCModel, TwoPTwoCNI));
+
+//////////////////////////////////////////////////////////////////
+// Property tags
+//////////////////////////////////////////////////////////////////
+
+NEW_PROP_TAG(NumPhases); //!< Number of fluid phases in the system
+NEW_PROP_TAG(NumComponents); //!< Number of fluid components in the system
+NEW_PROP_TAG(Indices); //!< Enumerations for the model
+NEW_PROP_TAG(Formulation); //!< The formulation of the model
+NEW_PROP_TAG(SpatialParams); //!< The type of the spatial parameters
+NEW_PROP_TAG(FluidSystem); //!< The type of the multi-component relations
+NEW_PROP_TAG(FluidState); //!< The type of the 2p2c fluid state
+
+NEW_PROP_TAG(MaterialLaw); //!< The material law which ought to be used (extracted from the spatial parameters)
+NEW_PROP_TAG(MaterialLawParams); //!< The parameters of the material law (extracted from the spatial parameters)
+NEW_PROP_TAG(EffectiveDiffusivityModel); //!< The employed model for the computation of the effective diffusivity
+
+NEW_PROP_TAG(ProblemEnableGravity); //!< Returns whether gravity is considered in the problem
+NEW_PROP_TAG(UseMoles); //!< Defines whether mole (true) or mass (false) fractions are used
+NEW_PROP_TAG(UseConstraintSolver); //!< Determines whether the constraint solver should be used
+
+NEW_PROP_TAG(ImplicitMassUpwindWeight); //!< The value of the upwind weight for the mass conservation equations
+NEW_PROP_TAG(ImplicitMobilityUpwindWeight); //!< Weight for the upwind mobility in the velocity calculation
+NEW_PROP_TAG(ReplaceCompEqIdx); //!< The index of the total mass balance equation,
+                                //!< if one component balance is replaced (ReplaceCompEqIdx < NumComponents)
+NEW_PROP_TAG(VtkAddVelocity); //!< Returns whether velocity vectors are written into the VTK output
+NEW_PROP_TAG(BaseFluxVariables); //!< The base flux variables
+NEW_PROP_TAG(SpatialParamsForchCoeff); //!< Property for the forchheimer coefficient
+}
+}
+
+#endif
diff --git a/dumux/porousmediumflow/2p2c/implicit/propertydefaults.hh b/dumux/porousmediumflow/2p2c/implicit/propertydefaults.hh
new file mode 100644
index 0000000000..04d0b6203a
--- /dev/null
+++ b/dumux/porousmediumflow/2p2c/implicit/propertydefaults.hh
@@ -0,0 +1,232 @@
+// -*- 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/>.   *
+ *****************************************************************************/
+/*!
+ * \ingroup Properties
+ * \ingroup ImplicitProperties
+ * \ingroup TwoPTwoCModel
+ * \file
+ *
+ * \brief Defines default values for most properties required by the
+ *        two-phase two-component fully implicit model.
+ */
+#ifndef DUMUX_2P2C_PROPERTY_DEFAULTS_HH
+#define DUMUX_2P2C_PROPERTY_DEFAULTS_HH
+
+#include "properties.hh"
+#include "model.hh"
+#include "indices.hh"
+#include "fluxvariables.hh"
+#include "volumevariables.hh"
+#include "localresidual.hh"
+#include "newtoncontroller.hh"
+
+#include <dumux/porousmediumflow/nonisothermal/implicit/propertydefaults.hh>
+#include <dumux/material/fluidmatrixinteractions/diffusivitymillingtonquirk.hh>
+#include <dumux/porousmediumflow/implicit/darcyfluxvariables.hh>
+#include <dumux/material/spatialparams/implicitspatialparams.hh>
+#include <dumux/material/fluidmatrixinteractions/2p/thermalconductivitysomerton.hh>
+
+namespace Dumux
+{
+
+namespace Properties {
+//////////////////////////////////////////////////////////////////
+// Property values
+//////////////////////////////////////////////////////////////////
+
+/*!
+ * \brief Set the property for the number of components.
+ *
+ * We just forward the number from the fluid system and use a static
+ * assert to make sure it is 2.
+ */
+SET_PROP(TwoPTwoC, NumComponents)
+{
+ private:
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+
+ public:
+    static const int value = FluidSystem::numComponents;
+
+    static_assert(value == 2,
+                  "Only fluid systems with 2 components are supported by the 2p-2c model!");
+};
+
+/*!
+ * \brief Set the property for the number of fluid phases.
+ *
+ * We just forward the number from the fluid system and use a static
+ * assert to make sure it is 2.
+ */
+SET_PROP(TwoPTwoC, NumPhases)
+{
+ private:
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+
+ public:
+    static const int value = FluidSystem::numPhases;
+    static_assert(value == 2,
+                  "Only fluid systems with 2 phases are supported by the 2p-2c model!");
+};
+
+/*!
+ * \brief The fluid state which is used by the volume variables to
+ *        store the thermodynamic state. This should be chosen
+ *        appropriately for the model ((non-)isothermal, equilibrium, ...).
+ *        This can be done in the problem.
+ */
+SET_PROP(TwoPTwoC, FluidState){
+    private:
+        typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+        typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+    public:
+        typedef Dumux::CompositionalFluidState<Scalar, FluidSystem> type;
+};
+
+//! Set the number of equations to 2
+SET_INT_PROP(TwoPTwoC, NumEq, 2);
+
+//! Set the default formulation to pw-sn
+SET_INT_PROP(TwoPTwoC,
+             Formulation,
+             TwoPTwoCFormulation::pwsn);
+
+//! Set as default that no component mass balance is replaced by the total mass balance
+SET_INT_PROP(TwoPTwoC, ReplaceCompEqIdx, 2);
+
+//! Set the property for the material parameters by extracting it from the material law.
+SET_PROP(TwoPTwoC, MaterialLawParams)
+{
+ private:
+    typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw;
+
+ public:
+    typedef typename MaterialLaw::Params type;
+};
+
+//! Use the 2p2c local residual operator
+SET_TYPE_PROP(TwoPTwoC,
+              LocalResidual,
+              TwoPTwoCLocalResidual<TypeTag>);
+
+//! Use the 2p2c Newton controller
+SET_TYPE_PROP(TwoPTwoC, NewtonController, TwoPTwoCNewtonController<TypeTag>);
+
+//! Use the 2p2c model
+SET_TYPE_PROP(TwoPTwoC, Model, TwoPTwoCModel<TypeTag>);
+
+//! Use the 2p2c VolumeVariables
+SET_TYPE_PROP(TwoPTwoC, VolumeVariables, TwoPTwoCVolumeVariables<TypeTag>);
+
+//! Use the 2p2c FluxVariables
+SET_TYPE_PROP(TwoPTwoC, FluxVariables, TwoPTwoCFluxVariables<TypeTag>);
+
+//! Set the BaseFluxVariables to realize Darcy flow
+SET_TYPE_PROP(TwoPTwoC, BaseFluxVariables, ImplicitDarcyFluxVariables<TypeTag>);
+
+//! Set the upwind weight for the mass conservation equations
+SET_SCALAR_PROP(TwoPTwoC, ImplicitMassUpwindWeight, 1.0);
+
+//! Set default mobility upwind weight to 1.0, i.e. fully upwind
+SET_SCALAR_PROP(TwoPTwoC, ImplicitMobilityUpwindWeight, 1.0);
+
+//! Set the indices required by the isothermal 2p2c
+SET_PROP(TwoPTwoC, Indices)
+{ private:
+    enum { Formulation = GET_PROP_VALUE(TypeTag, Formulation) };
+ public:
+    typedef TwoPTwoCIndices<TypeTag, Formulation, 0> type;
+};
+
+//! Use the ImplicitSpatialParams by default
+SET_TYPE_PROP(TwoPTwoC, SpatialParams, ImplicitSpatialParams<TypeTag>);
+
+//! Use the model after Millington (1961) for the effective diffusivity
+SET_PROP(TwoPTwoC, EffectiveDiffusivityModel)
+{ private :
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+ public:
+    typedef DiffusivityMillingtonQuirk<Scalar> type;
+};
+
+//! Disable velocity output by default
+SET_BOOL_PROP(TwoPTwoC, VtkAddVelocity, false);
+
+//! Enable gravity by default
+SET_BOOL_PROP(TwoPTwoC, ProblemEnableGravity, true);
+
+//! Use mole fractions in the balance equations by default
+SET_BOOL_PROP(TwoPTwoC, UseMoles, true);
+
+//! Determines whether the constraint solver is used
+SET_BOOL_PROP(TwoPTwoC, UseConstraintSolver, true);
+
+//! Set default value for the Forchheimer coefficient
+// Source: Ward, J.C. 1964 Turbulent flow in porous media. ASCE J. Hydraul. Div 90.
+//        Actually the Forchheimer coefficient is also a function of the dimensions of the
+//        porous medium. Taking it as a constant is only a first approximation
+//        (Nield, Bejan, Convection in porous media, 2006, p. 10)
+SET_SCALAR_PROP(TwoPTwoC, SpatialParamsForchCoeff, 0.55);
+
+//! Somerton is used as default model to compute the effective thermal heat conductivity
+SET_PROP(TwoPTwoCNI, ThermalConductivityModel)
+{
+private:
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+public:
+    typedef ThermalConductivitySomerton<Scalar, Indices> type;
+};
+
+//! temperature is already written by the isothermal model
+SET_BOOL_PROP(TwoPTwoCNI, NiOutputLevel, 0);
+
+//////////////////////////////////////////////////////////////////
+// Property values for isothermal model required for the general non-isothermal model
+//////////////////////////////////////////////////////////////////
+
+// set isothermal Model
+SET_TYPE_PROP(TwoPTwoCNI, IsothermalModel, TwoPTwoCModel<TypeTag>);
+
+// set isothermal FluxVariables
+SET_TYPE_PROP(TwoPTwoCNI, IsothermalFluxVariables, TwoPTwoCFluxVariables<TypeTag>);
+
+//set isothermal VolumeVariables
+SET_TYPE_PROP(TwoPTwoCNI, IsothermalVolumeVariables, TwoPTwoCVolumeVariables<TypeTag>);
+
+//set isothermal LocalResidual
+SET_TYPE_PROP(TwoPTwoCNI, IsothermalLocalResidual, TwoPTwoCLocalResidual<TypeTag>);
+
+//set isothermal Indices
+SET_PROP(TwoPTwoCNI, IsothermalIndices)
+{
+private:
+    enum { Formulation = GET_PROP_VALUE(TypeTag, Formulation) };
+public:
+    typedef TwoPTwoCIndices<TypeTag, Formulation, 0> type;
+};
+
+//set isothermal NumEq
+SET_INT_PROP(TwoPTwoCNI, IsothermalNumEq, 2);
+
+}
+
+}
+
+#endif
diff --git a/dumux/porousmediumflow/2p2c/implicit/volumevariables.hh b/dumux/porousmediumflow/2p2c/implicit/volumevariables.hh
new file mode 100644
index 0000000000..88b20bb907
--- /dev/null
+++ b/dumux/porousmediumflow/2p2c/implicit/volumevariables.hh
@@ -0,0 +1,621 @@
+// -*- 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/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ *
+ * \brief Contains the quantities which are constant within a
+ *        finite volume in the two-phase two-component model.
+ */
+#ifndef DUMUX_2P2C_VOLUME_VARIABLES_HH
+#define DUMUX_2P2C_VOLUME_VARIABLES_HH
+
+#include <dumux/implicit/model.hh>
+#include <dumux/material/fluidstates/compositionalfluidstate.hh>
+#include <dumux/material/constraintsolvers/computefromreferencephase.hh>
+#include <dumux/material/constraintsolvers/misciblemultiphasecomposition.hh>
+#include "properties.hh"
+#include "indices.hh"
+
+namespace Dumux
+{
+
+/*!
+ * \ingroup TwoPTwoCModel
+ * \ingroup ImplicitVolumeVariables
+ * \brief Contains the quantities which are constant within a
+ *        finite volume in the two-phase two-component model.
+ */
+template <class TypeTag>
+class TwoPTwoCVolumeVariables : public ImplicitVolumeVariables<TypeTag>
+{
+    typedef ImplicitVolumeVariables<TypeTag> ParentType;
+
+    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) Implementation;
+    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
+    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
+    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw;
+    typedef typename GET_PROP_TYPE(TypeTag, MaterialLawParams) MaterialLawParams;
+    enum {
+        numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
+        numComponents = GET_PROP_VALUE(TypeTag, NumComponents)
+    };
+
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+    enum {
+        wCompIdx = Indices::wCompIdx,
+        nCompIdx = Indices::nCompIdx,
+        wPhaseIdx = Indices::wPhaseIdx,
+        nPhaseIdx = Indices::nPhaseIdx
+    };
+
+    // present phases
+    enum {
+        wPhaseOnly = Indices::wPhaseOnly,
+        nPhaseOnly = Indices::nPhaseOnly,
+        bothPhases = Indices::bothPhases
+    };
+
+    // formulations
+    enum {
+        formulation = GET_PROP_VALUE(TypeTag, Formulation),
+        pwsn = TwoPTwoCFormulation::pwsn,
+        pnsw = TwoPTwoCFormulation::pnsw
+    };
+
+    // primary variable indices
+    enum {
+        switchIdx = Indices::switchIdx,
+        pressureIdx = Indices::pressureIdx
+    };
+
+    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
+    typedef typename GridView::template Codim<0>::Entity Element;
+    enum { dim = GridView::dimension};
+
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+    typedef Dumux::MiscibleMultiPhaseComposition<Scalar, FluidSystem> MiscibleMultiPhaseComposition;
+    static const bool useMoles = GET_PROP_VALUE(TypeTag, UseMoles);
+    static const bool useConstraintSolver = GET_PROP_VALUE(TypeTag, UseConstraintSolver);
+    static_assert(useMoles || (!useMoles && useConstraintSolver),
+                  "if UseMoles is set false, UseConstraintSolver has to be set to true");
+    typedef Dumux::ComputeFromReferencePhase<Scalar, FluidSystem> ComputeFromReferencePhase;
+
+    enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) };
+    enum { dofCodim = isBox ? dim : 0 };
+
+public:
+
+    typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState;
+
+    /*!
+     * \copydoc ImplicitVolumeVariables::update
+     */
+    void update(const PrimaryVariables &priVars,
+                const Problem &problem,
+                const Element &element,
+                const FVElementGeometry &fvGeometry,
+                const int scvIdx,
+                const bool isOldSol)
+    {
+        ParentType::update(priVars,
+                           problem,
+                           element,
+                           fvGeometry,
+                           scvIdx,
+                           isOldSol);
+
+        completeFluidState(priVars, problem, element, fvGeometry, scvIdx, fluidState_, isOldSol);
+
+        /////////////
+        // calculate the remaining quantities
+        /////////////
+        const MaterialLawParams &materialParams =
+        problem.spatialParams().materialLawParams(element, fvGeometry, scvIdx);
+
+        // Second instance of a parameter cache.
+        // Could be avoided if diffusion coefficients also
+        // became part of the fluid state.
+        typename FluidSystem::ParameterCache paramCache;
+        paramCache.updateAll(fluidState_);
+        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
+
+
+            // relative permeabilities
+            Scalar kr;
+            if (phaseIdx == wPhaseIdx)
+                kr = MaterialLaw::krw(materialParams, saturation(wPhaseIdx));
+            else // ATTENTION: krn requires the wetting phase saturation
+                // as parameter!
+                kr = MaterialLaw::krn(materialParams, saturation(wPhaseIdx));
+            relativePermeability_[phaseIdx] = kr;
+            Valgrind::CheckDefined(relativePermeability_[phaseIdx]);
+
+            // binary diffusion coefficients
+            diffCoeff_[phaseIdx] =
+            FluidSystem::binaryDiffusionCoefficient(fluidState_,
+                                                    paramCache,
+                                                    phaseIdx,
+                                                    wCompIdx,
+                                                    nCompIdx);
+            Valgrind::CheckDefined(diffCoeff_[phaseIdx]);
+        }
+
+        // porosity
+        porosity_ = problem.spatialParams().porosity(element,
+                                                     fvGeometry,
+                                                     scvIdx);
+        Valgrind::CheckDefined(porosity_);
+
+        // energy related quantities not contained in the fluid state
+        asImp_().updateEnergy_(priVars, problem, element, fvGeometry, scvIdx, isOldSol);
+    }
+
+    /*!
+     * \copydoc ImplicitModel::completeFluidState
+     * \param isOldSol Specifies whether this is the previous solution or the current one
+     */
+    static void completeFluidState(const PrimaryVariables& priVars,
+                                   const Problem& problem,
+                                   const Element& element,
+                                   const FVElementGeometry& fvGeometry,
+                                   int scvIdx,
+                                   FluidState& fluidState,
+                                   bool isOldSol = false)
+    {
+        Scalar t = Implementation::temperature_(priVars, problem, element,
+                                                fvGeometry, scvIdx);
+        fluidState.setTemperature(t);
+        int dofIdxGlobal = problem.model().dofMapper().subIndex(element, scvIdx, dofCodim);
+        int phasePresence = problem.model().phasePresence(dofIdxGlobal, isOldSol);
+
+        /////////////
+        // set the saturations
+        /////////////
+        Scalar sn;
+        if (phasePresence == nPhaseOnly)
+            sn = 1.0;
+        else if (phasePresence == wPhaseOnly) {
+            sn = 0.0;
+        }
+        else if (phasePresence == bothPhases) {
+            if (formulation == pwsn)
+                sn = priVars[switchIdx];
+            else if (formulation == pnsw)
+                sn = 1.0 - priVars[switchIdx];
+            else DUNE_THROW(Dune::InvalidStateException, "Formulation: " << formulation << " is invalid.");
+        }
+        else DUNE_THROW(Dune::InvalidStateException, "phasePresence: " << phasePresence << " is invalid.");
+        fluidState.setSaturation(wPhaseIdx, 1 - sn);
+        fluidState.setSaturation(nPhaseIdx, sn);
+
+        /////////////
+        // set the pressures of the fluid phases
+        /////////////
+
+        // calculate capillary pressure
+        const MaterialLawParams &materialParams =
+        problem.spatialParams().materialLawParams(element, fvGeometry, scvIdx);
+        Scalar pc = MaterialLaw::pc(materialParams, 1 - sn);
+
+        if (formulation == pwsn) {
+            fluidState.setPressure(wPhaseIdx, priVars[pressureIdx]);
+            fluidState.setPressure(nPhaseIdx, priVars[pressureIdx] + pc);
+        }
+        else if (formulation == pnsw) {
+            fluidState.setPressure(nPhaseIdx, priVars[pressureIdx]);
+            fluidState.setPressure(wPhaseIdx, priVars[pressureIdx] - pc);
+        }
+        else DUNE_THROW(Dune::InvalidStateException, "Formulation: " << formulation << " is invalid.");
+
+        /////////////
+        // calculate the phase compositions
+        /////////////
+        typename FluidSystem::ParameterCache paramCache;
+
+        //get the phase pressures and set the fugacity coefficients here if constraintsolver is not used
+        Scalar pn = 0;
+        Scalar pw = 0;
+
+        if(!useConstraintSolver) {
+            if (formulation == pwsn) {
+                pw = priVars[pressureIdx];
+                pn = pw + pc;
+            }
+            else {
+                pn = priVars[pressureIdx];
+                pw = pn - pc;
+            }
+
+            for (int phaseIdx = 0; phaseIdx < numPhases; ++ phaseIdx) {
+                assert(FluidSystem::isIdealMixture(phaseIdx));
+
+                for (int compIdx = 0; compIdx < numComponents; ++ compIdx) {
+                    Scalar phi = FluidSystem::fugacityCoefficient(fluidState, paramCache, phaseIdx, compIdx);
+                    fluidState.setFugacityCoefficient(phaseIdx, compIdx, phi);
+                }
+            }
+        }
+
+        // now comes the tricky part: calculate phase compositions
+        if (phasePresence == bothPhases) {
+            // both phases are present, phase compositions are a
+            // result of the the nonwetting <-> wetting equilibrium. This is
+            // the job of the "MiscibleMultiPhaseComposition"
+            // constraint solver
+            if(useConstraintSolver) {
+                MiscibleMultiPhaseComposition::solve(fluidState,
+                                                     paramCache,
+                                                     /*setViscosity=*/true,
+                                                     /*setInternalEnergy=*/false);
+            }
+            // ... or calculated explicitly this way ...
+            else {
+                //get the partial pressure of the main component of the the wetting phase ("H20") within the nonwetting (gas) phase == vapor pressure due to equilibrium
+                //note that in this case the fugacityCoefficient * pw is the vapor pressure (see implementation in respective fluidsystem)
+                Scalar partPressH2O = FluidSystem::fugacityCoefficient(fluidState,
+                                                                       wPhaseIdx,
+                                                                       wCompIdx) * pw;
+
+                // get the partial pressure of the main component of the the nonwetting (gas) phase ("Air")
+                Scalar partPressAir = pn - partPressH2O;
+
+                //calculate the mole fractions of the components within the nonwetting phase
+                Scalar xnn = partPressAir/pn;
+                Scalar xnw = partPressH2O/pn;
+
+                // calculate the mole fractions of the components within the wetting phase
+                //note that in this case the fugacityCoefficient * pw is the Henry Coefficient (see implementation in respective fluidsystem)
+                Scalar xwn = partPressAir
+                  / (FluidSystem::fugacityCoefficient(fluidState,
+                                                      wPhaseIdx,nCompIdx)
+                  * pw);
+
+                Scalar xww = 1.0 -xwn;
+
+                //set all mole fractions
+                fluidState.setMoleFraction(wPhaseIdx, wCompIdx, xww);
+                fluidState.setMoleFraction(wPhaseIdx, nCompIdx, xwn);
+                fluidState.setMoleFraction(nPhaseIdx, wCompIdx, xnw);
+                fluidState.setMoleFraction(nPhaseIdx, nCompIdx, xnn);
+
+                paramCache.updateComposition(fluidState, wPhaseIdx);
+                paramCache.updateComposition(fluidState, nPhaseIdx);
+
+                //set the phase densities
+                Scalar rhoW = FluidSystem::density(fluidState, paramCache, wPhaseIdx);
+                Scalar rhoN = FluidSystem::density(fluidState, paramCache, nPhaseIdx);
+
+                fluidState.setDensity(wPhaseIdx, rhoW);
+                fluidState.setDensity(nPhaseIdx, rhoN);
+            }
+        }
+        else if (phasePresence == nPhaseOnly) {
+            // only the nonwetting phase is present, i.e. nonwetting phase
+            // composition is stored explicitly.
+            if(useMoles)
+            {
+                fluidState.setMoleFraction(nPhaseIdx, nCompIdx, 1 - priVars[switchIdx]);
+                fluidState.setMoleFraction(nPhaseIdx, wCompIdx, priVars[switchIdx]);
+            }
+            else
+            {
+                // setMassFraction() has only to be called 1-numComponents times
+                fluidState.setMassFraction(nPhaseIdx, wCompIdx, priVars[switchIdx]);
+            }
+
+            // calculate the composition of the remaining phases (as
+            // well as the densities of all phases). This is the job
+            // of the "ComputeFromReferencePhase" constraint solver
+            if (useConstraintSolver) {
+                ComputeFromReferencePhase::solve(fluidState,
+                                                 paramCache,
+                                                 nPhaseIdx,
+                                                 /*setViscosity=*/true,
+                                                 /*setInternalEnergy=*/false);
+            }
+            // ... or calculated explicitly this way ...
+            else {
+                // note that the water phase is actually not existing!
+                // thus, this is used as phase switch criterion
+                Scalar xnw = priVars[switchIdx];
+                Scalar xnn = 1.0 -xnw;
+
+                //first, xww:
+                // xnw * pn = "actual" (hypothetical) vapor pressure
+                // fugacityCoefficient * pw = vapor pressure given by thermodynamic conditions
+                // Here, xww is not actually the mole fraction of water in the wetting phase
+                // xww is only the ratio of "actual" vapor pressure / "thermodynamic" vapor pressure
+                // If xww > 1 : gas is over-saturated with water vapor,
+                // condensation takes place (see switch criterion in model)
+                Scalar xww = xnw * pn
+                  / (FluidSystem::fugacityCoefficient(fluidState,
+                                                      wPhaseIdx,wCompIdx)
+                     * pw);
+
+                // now, xwn:
+                //partialPressure / xwn = Henry
+                //partialPressure = xnn * pn
+                //xwn = xnn * pn / Henry
+                // Henry = fugacityCoefficient * pw
+                Scalar xwn = xnn * pn / (FluidSystem::fugacityCoefficient(fluidState,
+                                                                          wPhaseIdx,nCompIdx)
+                                         * pw);
+
+                fluidState.setMoleFraction(wPhaseIdx, wCompIdx, xww);
+                fluidState.setMoleFraction(wPhaseIdx, nCompIdx, xwn);
+
+                paramCache.updateComposition(fluidState, wPhaseIdx);
+                paramCache.updateComposition(fluidState, nPhaseIdx);
+
+                Scalar rhoW = FluidSystem::density(fluidState, paramCache, wPhaseIdx);
+                Scalar rhoN = FluidSystem::density(fluidState, paramCache, nPhaseIdx);
+
+                fluidState.setDensity(wPhaseIdx, rhoW);
+                fluidState.setDensity(nPhaseIdx, rhoN);
+            }
+        }
+        else if (phasePresence == wPhaseOnly) {
+            // only the wetting phase is present, i.e. wetting phase
+            // composition is stored explicitly.
+            if(useMoles) // mole-fraction formulation
+            {
+                fluidState.setMoleFraction(wPhaseIdx, wCompIdx, 1-priVars[switchIdx]);
+                fluidState.setMoleFraction(wPhaseIdx, nCompIdx, priVars[switchIdx]);
+            }
+            else // mass-fraction formulation
+            {
+                // setMassFraction() has only to be called 1-numComponents times
+                fluidState.setMassFraction(wPhaseIdx, nCompIdx, priVars[switchIdx]);
+            }
+
+            // calculate the composition of the remaining phases (as
+            // well as the densities of all phases). This is the job
+            // of the "ComputeFromReferencePhase" constraint solver
+            if (useConstraintSolver) {
+                ComputeFromReferencePhase::solve(fluidState,
+                                                 paramCache,
+                                                 wPhaseIdx,
+                                                 /*setViscosity=*/true,
+                                                 /*setInternalEnergy=*/false);
+            }
+            // ... or calculated explicitly this way ...
+            else {
+                // note that the gas phase is actually not existing!
+                // thus, this is used as phase switch criterion
+                Scalar xwn = priVars[switchIdx];
+
+                //first, xnw:
+                //psteam = xnw * pn = partial pressure of water in gas phase
+                //psteam = fugacityCoefficient * pw
+                Scalar xnw = (FluidSystem::fugacityCoefficient(fluidState,
+                                                               wPhaseIdx,wCompIdx)
+                              * pw) / pn ;
+
+                //now, xnn:
+                // xwn = partialPressure / Henry
+                // partialPressure = pn * xnn
+                // xwn = pn * xnn / Henry
+                // xnn = xwn * Henry / pn
+                // Henry = fugacityCoefficient * pw
+                Scalar xnn = xwn * (FluidSystem::fugacityCoefficient(fluidState,
+                                                                     wPhaseIdx,nCompIdx)
+                                    * pw) / pn ;
+
+                fluidState.setMoleFraction(nPhaseIdx, nCompIdx, xnn);
+                fluidState.setMoleFraction(nPhaseIdx, wCompIdx, xnw);
+
+                paramCache.updateComposition(fluidState, wPhaseIdx);
+                paramCache.updateComposition(fluidState, nPhaseIdx);
+
+                Scalar rhoW = FluidSystem::density(fluidState, paramCache, wPhaseIdx);
+                Scalar rhoN = FluidSystem::density(fluidState, paramCache, nPhaseIdx);
+
+                fluidState.setDensity(wPhaseIdx, rhoW);
+                fluidState.setDensity(nPhaseIdx, rhoN);
+            }
+        }
+
+        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
+            //set the viscosity here if constraintsolver is not used
+            if(!useConstraintSolver) {
+                const Scalar mu =
+                FluidSystem::viscosity(fluidState,
+                                       paramCache,
+                                       phaseIdx);
+                fluidState.setViscosity(phaseIdx,mu);
+            }
+            // compute and set the enthalpy
+            Scalar h = Implementation::enthalpy_(fluidState, paramCache, phaseIdx);
+            fluidState.setEnthalpy(phaseIdx, h);
+        }
+   }
+
+
+    /*!
+     * \brief Returns the phase state within the control volume.
+     */
+    const FluidState &fluidState() const
+    { return fluidState_; }
+
+    /*!
+     * \brief Returns the saturation of a given phase within
+     *        the control volume in \f$[-]\f$.
+     *
+     * \param phaseIdx The phase index
+     */
+    Scalar saturation(const int phaseIdx) const
+    { return fluidState_.saturation(phaseIdx); }
+
+    /*!
+     * \brief Returns the mass fraction of a given component in a
+     *        given phase within the control volume in \f$[-]\f$.
+     *
+     * \param phaseIdx The phase index
+     * \param compIdx The component index
+     */
+    Scalar massFraction(const int phaseIdx, const int compIdx) const
+    { return fluidState_.massFraction(phaseIdx, compIdx); }
+
+    /*!
+     * \brief Returns the mole fraction of a given component in a
+     *        given phase within the control volume in \f$[-]\f$.
+     *
+     * \param phaseIdx The phase index
+     * \param compIdx The component index
+     */
+    Scalar moleFraction(const int phaseIdx, const int compIdx) const
+    { return fluidState_.moleFraction(phaseIdx, compIdx); }
+
+    /*!
+     * \brief Returns the mass density of a given phase within the
+     *        control volume in \f$[kg/m^3]\f$.
+     *
+     * \param phaseIdx The phase index
+     */
+    Scalar density(const int phaseIdx) const
+    { return fluidState_.density(phaseIdx); }
+
+    /*!
+     * \brief Returns the dynamic viscosity of the fluid within the
+     *        control volume in \f$\mathrm{[Pa s]}\f$.
+     *
+     * \param phaseIdx The phase index
+     */
+    Scalar viscosity(const int phaseIdx) const
+    { return fluidState_.viscosity(phaseIdx); }
+
+    /*!
+     * \brief Returns the mass density of a given phase within the
+     *        control volume in \f$[mol/m^3]\f$.
+     *
+     * \param phaseIdx The phase index
+     */
+    Scalar molarDensity(const int phaseIdx) const
+    { return fluidState_.density(phaseIdx) / fluidState_.averageMolarMass(phaseIdx); }
+
+    /*!
+     * \brief Returns the effective pressure of a given phase within
+     *        the control volume in \f$[kg/(m*s^2)=N/m^2=Pa]\f$.
+     *
+     * \param phaseIdx The phase index
+     */
+    Scalar pressure(const int phaseIdx) const
+    { return fluidState_.pressure(phaseIdx); }
+
+    /*!
+     * \brief Returns temperature within the control volume in \f$[K]\f$.
+     *
+     * Note that we assume thermodynamic equilibrium, i.e. the
+     * temperature of the rock matrix and of all fluid phases are
+     * identical.
+     */
+    Scalar temperature() const
+    { return fluidState_.temperature(/*phaseIdx=*/0); }
+
+    /*!
+     * \brief Returns the relative permeability of a given phase within
+     *        the control volume in \f$[-]\f$.
+     *
+     * \param phaseIdx The phase index
+     */
+    Scalar relativePermeability(const int phaseIdx) const
+    {
+        return relativePermeability_[phaseIdx];
+    }
+
+    /*!
+     * \brief Returns the effective mobility of a given phase within
+     *        the control volume in \f$[s*m/kg]\f$.
+     *
+     * \param phaseIdx The phase index
+     */
+    Scalar mobility(const int phaseIdx) const
+    {
+        return relativePermeability_[phaseIdx]/fluidState_.viscosity(phaseIdx);
+    }
+
+    /*!
+     * \brief Returns the effective capillary pressure within the control volume
+     *        in \f$[kg/(m*s^2)=N/m^2=Pa]\f$.
+     */
+    Scalar capillaryPressure() const
+    { return fluidState_.pressure(nPhaseIdx) - fluidState_.pressure(wPhaseIdx); }
+
+    /*!
+     * \brief Returns the average porosity within the control volume in \f$[-]\f$.
+     */
+    Scalar porosity() const
+    { return porosity_; }
+
+    /*!
+     * \brief Returns the binary diffusion coefficients for a phase in \f$[m^2/s]\f$.
+     */
+    Scalar diffCoeff(const int phaseIdx) const
+    { return diffCoeff_[phaseIdx]; }
+
+
+protected:
+    static Scalar temperature_(const PrimaryVariables &priVars,
+                               const Problem& problem,
+                               const Element &element,
+                               const FVElementGeometry &fvGeometry,
+                               int scvIdx)
+    {
+        return problem.temperatureAtPos(fvGeometry.subContVol[scvIdx].global);
+    }
+
+    template<class ParameterCache>
+    static Scalar enthalpy_(const FluidState& fluidState,
+                            const ParameterCache& paramCache,
+                            const int phaseIdx)
+    {
+        return 0;
+    }
+
+    /*!
+     * \brief Called by update() to compute the energy related quantities
+     */
+    void updateEnergy_(const PrimaryVariables &sol,
+                       const Problem &problem,
+                       const Element &element,
+                       const FVElementGeometry &fvGeometry,
+                       const int scvIdx,
+                       bool isOldSol)
+    { }
+
+    Scalar porosity_; //!< Effective porosity within the control volume
+    Scalar relativePermeability_[numPhases]; //!< Relative permeability within the control volume
+    Scalar diffCoeff_[numPhases]; //!< Binary diffusion coefficients for the phases
+    FluidState fluidState_;
+
+private:
+    Implementation &asImp_()
+    { return *static_cast<Implementation*>(this); }
+
+    const Implementation &asImp_() const
+    { return *static_cast<const Implementation*>(this); }
+
+
+};
+
+} // end namespace
+
+#endif
diff --git a/dumux/porousmediumflow/2pnc/implicit/fluxvariables.hh b/dumux/porousmediumflow/2pnc/implicit/fluxvariables.hh
new file mode 100644
index 0000000000..8f85e0d0ae
--- /dev/null
+++ b/dumux/porousmediumflow/2pnc/implicit/fluxvariables.hh
@@ -0,0 +1,415 @@
+// -*- 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/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ * \brief Contains the data which is required to calculate
+ *        all fluxes of components over a face of a finite volume for
+ *        the two-phase two-component model fully implicit model.
+ */
+#ifndef DUMUX_2PNC_FLUX_VARIABLES_HH
+#define DUMUX_2PNC_FLUX_VARIABLES_HH
+
+#include <dumux/common/math.hh>
+#include <dumux/common/spline.hh>
+
+#include "properties.hh"
+
+namespace Dumux
+{
+/*!
+ * \ingroup TwoPNCModel
+ * \ingroup ImplicitFluxVariables
+ * \brief Contains the data which is required to calculate
+ *        all fluxes of components over a face of a finite volume for
+ *        the two-phase n-component fully implicit model.
+ *
+ * This means pressure and concentration gradients, phase densities at
+ * the integration point, etc.
+ */
+
+template <class TypeTag>
+class TwoPNCFluxVariables : public GET_PROP_TYPE(TypeTag, BaseFluxVariables)
+{
+    typedef typename GET_PROP_TYPE(TypeTag, BaseFluxVariables) BaseFluxVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
+    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
+
+    typedef typename GridView::ctype CoordScalar;
+    typedef typename GridView::template Codim<0>::Entity Element;
+    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
+
+    enum {
+            dim = GridView::dimension,
+            dimWorld = GridView::dimensionworld,
+            numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
+            numComponents = GET_PROP_VALUE(TypeTag, NumComponents),
+          };
+
+    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
+    typedef typename GET_PROP_TYPE(TypeTag, SpatialParams) SpatialParams;
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+//     typedef typename FVElementGeometry::SubControlVolume SCV;
+    typedef typename FVElementGeometry::SubControlVolumeFace SCVFace;
+
+    typedef Dune::FieldVector<CoordScalar, dimWorld> DimVector;
+    typedef Dune::FieldMatrix<CoordScalar, dim, dim> DimMatrix;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+    enum {
+            wPhaseIdx = FluidSystem::wPhaseIdx,
+            nPhaseIdx = FluidSystem::nPhaseIdx,
+            wCompIdx  = FluidSystem::wCompIdx,
+         };
+
+public:
+    /*!
+     * \brief The constructor
+     *
+     * \param problem The problem
+     * \param element The finite element
+     * \param fvGeometry The finite-volume geometry in the fully implicit scheme
+     * \param fIdx The local index of the sub-control-volume face
+     * \param elemVolVars The volume variables of the current element
+     * \param onBoundary Evaluate flux at inner sub-control-volume face or on a boundary face
+     */
+    TwoPNCFluxVariables(const Problem &problem,
+                     const Element &element,
+                     const FVElementGeometry &fvGeometry,
+                     const int fIdx,
+                     const ElementVolumeVariables &elemVolVars,
+                     const bool onBoundary = false)
+    : BaseFluxVariables(problem, element, fvGeometry, fIdx, elemVolVars, onBoundary)
+    {
+        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
+            density_[phaseIdx] = Scalar(0);
+            molarDensity_[phaseIdx] = Scalar(0);
+            potentialGrad_[phaseIdx] = Scalar(0);
+            for (int compIdx = 0; compIdx < numComponents; ++compIdx)
+            {
+                massFractionGrad_[phaseIdx][compIdx] = Scalar(0);
+                moleFractionGrad_[phaseIdx][compIdx] = Scalar(0);
+            }
+        }
+        calculateGradients_(problem, element, elemVolVars);
+        calculateVelocities_(problem, element, elemVolVars);
+        calculateporousDiffCoeff_(problem, element, elemVolVars);
+    };
+
+protected:
+    void calculateGradients_(const Problem &problem,
+                             const Element &element,
+                             const ElementVolumeVariables &elemVolVars)
+    {
+        // calculate gradients
+        DimVector tmp(0.0);
+        for (int idx = 0;
+             idx < this->fvGeometry_.numScv;
+             idx++) // loop over adjacent vertices
+        {
+            // FE gradient at vertex idx
+            const DimVector &feGrad = face().grad[idx];
+
+            // compute sum of pressure gradients for each phase
+            for (int phaseIdx = 0; phaseIdx < numPhases; phaseIdx++)
+            {
+                // the pressure gradient
+                tmp = feGrad;
+                tmp *= elemVolVars[idx].pressure(phaseIdx); //FE grad times phase pressure
+                potentialGrad_[phaseIdx] += tmp;
+            }
+
+            // the concentration gradient of the non-wetting
+            // component in the wetting phase
+
+            for(int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
+            {
+                for(int compIdx = 0; compIdx < numComponents; ++compIdx)
+                {
+                    if(compIdx != phaseIdx) //No grad is needed for this case
+                    {
+                        tmp = feGrad;
+                        tmp *= elemVolVars[idx].massFraction(phaseIdx, compIdx);
+                        massFractionGrad_[phaseIdx][compIdx] += tmp;
+
+                        tmp = feGrad;
+                        tmp *= elemVolVars[idx].moleFraction(phaseIdx, compIdx);
+                        moleFractionGrad_[phaseIdx][compIdx] += tmp;
+                    }
+                }
+            }
+        }
+
+        // correct the pressure gradients by the hydrostatic
+        // pressure due to gravity
+        for (int phaseIdx=0; phaseIdx < numPhases; phaseIdx++)
+        {
+            int i = face().i;
+            int j = face().j;
+            Scalar fI = rhoFactor_(phaseIdx, i, elemVolVars);
+            Scalar fJ = rhoFactor_(phaseIdx, j, elemVolVars);
+            if (fI + fJ <= 0)
+                fI = fJ = 0.5; // doesn't matter because no phase is
+                               // present in both cells!
+            density_[phaseIdx] =
+                (fI*elemVolVars[i].density(phaseIdx) +
+                 fJ*elemVolVars[j].density(phaseIdx))
+                /
+                (fI + fJ);
+            // phase density
+            molarDensity_[phaseIdx]
+                =
+                (fI*elemVolVars[i].molarDensity(phaseIdx) +
+                 fJ*elemVolVars[j].molarDensity(phaseIdx))
+                /
+                (fI + fJ); //arithmetic averaging
+
+            tmp = problem.gravity();
+            tmp *= density_[phaseIdx];
+
+            potentialGrad_[phaseIdx] -= tmp;
+        }
+    }
+
+    Scalar rhoFactor_(int phaseIdx, int scvIdx, const ElementVolumeVariables &vDat)
+    {
+
+        static const Scalar eps = 1e-2;
+        const Scalar sat = vDat[scvIdx].density(phaseIdx);
+        if (sat > eps)
+            return 0.5;
+        if (sat <= 0)
+            return 0;
+
+        static const Dumux::Spline<Scalar> sp(0, eps, // x0, x1
+                                              0, 0.5, // y0, y1
+                                              0, 0); // m0, m1
+        return sp.eval(sat);
+    }
+
+    void calculateVelocities_(const Problem &problem,
+                              const Element &element,
+                              const ElementVolumeVariables &elemVolVars)
+    {
+        const SpatialParams &spatialParams = problem.spatialParams();
+        // multiply the pressure potential with the intrinsic
+        // permeability
+        DimMatrix K(0.0);
+
+        for (int phaseIdx=0; phaseIdx < numPhases; phaseIdx++)
+        {
+            auto K_i = spatialParams.intrinsicPermeability(element,this->fvGeometry_,face().i);
+            //K_i *= volVarsI.permFactor();
+
+            auto K_j = spatialParams.intrinsicPermeability(element,this->fvGeometry_,face().j);
+            //K_j *= volVarsJ.permFactor();
+
+            spatialParams.meanK(K,K_i,K_j);
+
+            K.mv(potentialGrad_[phaseIdx], Kmvp_[phaseIdx]);
+            KmvpNormal_[phaseIdx] = - (Kmvp_[phaseIdx] * face().normal);
+        }
+
+        // set the upstream and downstream vertices
+        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
+        {
+            upstreamIdx_[phaseIdx] = face().i;
+            downstreamIdx_[phaseIdx] = face().j;
+
+            if (KmvpNormal_[phaseIdx] < 0) {
+                std::swap(upstreamIdx_[phaseIdx],
+                          downstreamIdx_[phaseIdx]);
+            }
+        }
+    }
+
+    void calculateporousDiffCoeff_(const Problem &problem,
+                                   const Element &element,
+                                   const ElementVolumeVariables &elemVolVars)
+    {
+        const VolumeVariables &volVarsI = elemVolVars[face().i];
+        const VolumeVariables &volVarsJ = elemVolVars[face().j];
+
+        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
+        {
+            /* If there is no phase saturation on either side of the face
+                * no diffusion takes place */
+
+            if (volVarsI.saturation(phaseIdx) <= 0 ||
+                volVarsJ.saturation(phaseIdx) <= 0)
+                {
+                for (int compIdx = 0; compIdx < numComponents; ++compIdx)
+                    {
+                        porousDiffCoeff_[phaseIdx][compIdx] = 0.0;
+                    }
+                }
+
+            else
+            {
+            // calculate tortuosity at the nodes i and j needed
+            // for porous media diffusion coefficient
+            Scalar tauI =  1.0/(volVarsI.porosity() * volVarsI.porosity()) *
+                            pow(volVarsI.porosity() * volVarsI.saturation(phaseIdx), 7.0/3);
+
+            Scalar tauJ =   1.0/(volVarsJ.porosity() * volVarsJ.porosity()) *
+                            pow(volVarsJ.porosity() * volVarsJ.saturation(phaseIdx), 7.0/3);
+            // Diffusion coefficient in the porous medium
+
+            // -> harmonic mean
+            for (int compIdx = 0; compIdx < numComponents; ++compIdx)
+                {
+                    if(phaseIdx==compIdx)
+                        porousDiffCoeff_[phaseIdx][compIdx] = 0.0;
+                    else
+                    {
+                        porousDiffCoeff_[phaseIdx][compIdx] = harmonicMean(volVarsI.porosity() * volVarsI.saturation(phaseIdx) * tauI * volVarsI.diffCoeff(phaseIdx, compIdx),
+                                                                            volVarsJ.porosity() * volVarsJ.saturation(phaseIdx) * tauJ * volVarsJ.diffCoeff(phaseIdx, compIdx));
+                    }
+                }
+            }
+        }
+    }
+
+public:
+    /*!
+     * \brief Return the pressure potential multiplied with the
+     *        intrinsic permeability which goes from vertex i to
+     *        vertex j.
+     *
+     * Note that the length of the face's normal is the area of the
+     * face, so this is not the actual velocity by the integral of
+     * the velocity over the face's area. Also note that the phase
+     * mobility is not yet included here since this would require a
+     * decision on the upwinding approach (which is done in the
+     * model and/or local residual file).
+     *
+     *   \param phaseIdx The phase index
+     */
+    Scalar KmvpNormal(int phaseIdx) const
+    { return KmvpNormal_[phaseIdx]; }
+
+    /*!
+     * \brief Return the pressure potential multiplied with the
+     *        intrinsic permeability as vector (for velocity output)
+     *
+     *   \param phaseIdx The phase index
+     */
+    DimVector Kmvp(int phaseIdx) const
+    { return Kmvp_[phaseIdx]; }
+
+    /*!
+     * \brief Return the local index of the upstream control volume
+     *        for a given phase.
+     *
+     *   \param phaseIdx The phase index
+     */
+    int upstreamIdx(int phaseIdx) const
+    { return upstreamIdx_[phaseIdx]; }
+
+    /*!
+     * \brief Return the local index of the downstream control volume
+     *        for a given phase.
+     *
+     *   \param phaseIdx The phase index
+     */
+    int downstreamIdx(int phaseIdx) const
+    { return downstreamIdx_[phaseIdx]; }
+
+    /*!
+     * \brief The binary diffusion coefficient for each fluid phase.
+     *
+     *   \param phaseIdx The phase index
+     *   \param compIdx The component index
+     */
+    Scalar porousDiffCoeff(int phaseIdx, int compIdx) const
+    { return porousDiffCoeff_[phaseIdx][compIdx];}
+
+    /*!
+     * \brief Return density \f$\mathrm{[kg/m^3]}\f$ of a phase at the integration
+     *        point.
+     *
+     * \param phaseIdx The phase index
+     */
+    Scalar density(int phaseIdx) const
+    { return density_[phaseIdx]; }
+
+    /*!
+     * \brief Return molar density \f$\mathrm{[mol/m^3]}\f$ of a phase at the integration
+     *        point.
+     *
+     * \param phaseIdx The phase index
+     */
+    Scalar molarDensity(int phaseIdx) const
+    { return molarDensity_[phaseIdx]; }
+
+    /*!
+     * \brief The concentration gradient of a component in a phase.
+     *
+     * \param phaseIdx The phase index
+     * \param compIdx The component index
+     */
+    const DimVector &massFractionGrad(int phaseIdx, int compIdx) const
+    { return massFractionGrad_[phaseIdx][compIdx]; }
+
+    /*!
+     * \brief The molar concentration gradient of a component in a phase.
+     *
+     * \param phaseIdx The phase index
+     * \param compIdx The component index
+     */
+    const DimVector &moleFractionGrad(int phaseIdx, int compIdx) const
+    { return moleFractionGrad_[phaseIdx][compIdx]; }
+
+    const SCVFace &face() const
+    {
+    if (this->onBoundary_)
+        return this->fvGeometry_.boundaryFace[this->faceIdx_];
+    else
+        return this->fvGeometry_.subContVolFace[this->faceIdx_];
+    }
+
+protected:
+
+    // gradients
+    DimVector potentialGrad_[numPhases];
+    DimVector massFractionGrad_[numPhases][numComponents];
+    DimVector moleFractionGrad_[numPhases][numComponents];
+
+    // density of each face at the integration point
+    Scalar density_[numPhases], molarDensity_[numPhases];
+
+    // intrinsic permeability times pressure potential gradient
+    DimVector Kmvp_[numPhases];
+    // projected on the face normal
+    Scalar KmvpNormal_[numPhases];
+
+    // local index of the upwind vertex for each phase
+    int upstreamIdx_[numPhases];
+    // local index of the downwind vertex for each phase
+    int downstreamIdx_[numPhases];
+
+    // the diffusion coefficient for the porous medium
+    Dune::FieldMatrix<Scalar, numPhases, numComponents> porousDiffCoeff_;
+};
+
+} // end namespace
+
+#endif
diff --git a/dumux/porousmediumflow/2pnc/implicit/indices.hh b/dumux/porousmediumflow/2pnc/implicit/indices.hh
new file mode 100644
index 0000000000..a527345942
--- /dev/null
+++ b/dumux/porousmediumflow/2pnc/implicit/indices.hh
@@ -0,0 +1,80 @@
+// -*- 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/>.   *
+ *****************************************************************************/
+
+/*!
+ * \file
+ * \brief Defines the indices required for the two-phase n-component
+ *        fully implicit model.
+ */
+#ifndef DUMUX_2PNC_INDICES_HH
+#define DUMUX_2PNC_INDICES_HH
+#include "properties.hh"
+namespace Dumux
+{
+/*!
+ * \ingroup TwoPNCModel
+ * \ingroup ImplicitIndices
+ * \brief Enumerates the formulations which the two-phase n-component model accepts.
+ *
+ */
+struct TwoPNCFormulation//TODO: This might need to be change similar to 2p2c indices
+{
+    enum {
+            plSg,
+            pgSl,
+            pnSw = pgSl,
+            pwSn = plSg
+          };
+};
+
+/*!
+ * \ingroup TwoPNCModel
+ * \ingroup ImplicitIndices
+ * \brief The indices for the isothermal two-phase n-component model.
+ *
+ * \tparam PVOffset The first index in a primary variable vector.
+ */
+template <class TypeTag, int PVOffset = 0>
+class TwoPNCIndices
+{
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+
+public:
+    // Phase indices
+    static const int wPhaseIdx = FluidSystem::wPhaseIdx; //!< Index of the wetting phase
+    static const int nPhaseIdx = FluidSystem::nPhaseIdx; //!< Index of the non-wetting phase
+    // present phases (-> 'pseudo' primary variable)
+    static const int wPhaseOnly = 1; //!< Only the non-wetting phase is present
+    static const int nPhaseOnly = 2; //!< Only the wetting phase is present
+    static const int bothPhases = 3; //!< Both phases are present
+
+    // Primary variable indices
+    static const int pressureIdx = PVOffset + 0; //!< Index for wetting/non-wetting phase pressure (depending on formulation) in a solution vector
+    static const int switchIdx = PVOffset + 1; //!< Index of the either the saturation or the mass fraction of the non-wetting/wetting phase
+    // equation indices
+    static const int conti0EqIdx = PVOffset + 0; //!< Reference index for mass conservation equations.
+    static const int contiWEqIdx = conti0EqIdx + FluidSystem::wCompIdx; //!< Index of the mass conservation equation for the wetting phase major component
+    static const int contiNEqIdx = conti0EqIdx + FluidSystem::nCompIdx; //!< Index of the mass conservation equation for the non-wetting phase major component
+};
+
+// \}
+
+}
+
+#endif
diff --git a/dumux/porousmediumflow/2pnc/implicit/localresidual.hh b/dumux/porousmediumflow/2pnc/implicit/localresidual.hh
new file mode 100644
index 0000000000..bddf0fe962
--- /dev/null
+++ b/dumux/porousmediumflow/2pnc/implicit/localresidual.hh
@@ -0,0 +1,349 @@
+// -*- 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/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ *
+ * \brief Element-wise calculation of the Jacobian matrix for problems
+ *        using the two-phase n-component box model.
+ */
+
+#ifndef DUMUX_2PNC_LOCAL_RESIDUAL_BASE_HH
+#define DUMUX_2PNC_LOCAL_RESIDUAL_BASE_HH
+
+#include "properties.hh"
+#include "volumevariables.hh"
+#include <dumux/nonlinear/newtoncontroller.hh>
+
+#include <iostream>
+#include <vector>
+
+namespace Dumux
+{
+/*!
+ * \ingroup TwoPNCModel
+ * \ingroup ImplicitLocalResidual
+ * \brief Element-wise calculation of the Jacobian matrix for problems
+ *        using the two-phase n-component fully implicit box model.
+ *
+ * This class is used to fill the gaps in ImplicitLocalResidual for the two-phase n-component flow.
+ */
+template<class TypeTag>
+class TwoPNCLocalResidual: public GET_PROP_TYPE(TypeTag, BaseLocalResidual)
+{
+protected:
+    typedef TwoPNCLocalResidual<TypeTag> ThisType;
+    typedef typename GET_PROP_TYPE(TypeTag, LocalResidual) Implementation;
+    typedef BoxLocalResidual<TypeTag> ParentType;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
+    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+
+    typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector;
+    typedef typename GET_PROP_TYPE(TypeTag, ElementSolutionVector) ElementSolutionVector;
+    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes;
+
+    typedef CompositionalFluidState<Scalar, FluidSystem> FluidState;
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+
+    enum
+    {
+        dim = GridView::dimension,
+        dimWorld = GridView::dimensionworld,
+
+        numEq = GET_PROP_VALUE(TypeTag, NumEq),
+        numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
+        numComponents = GET_PROP_VALUE(TypeTag, NumComponents),
+
+        replaceCompEqIdx = GET_PROP_VALUE(TypeTag, ReplaceCompEqIdx),
+
+        pressureIdx = Indices::pressureIdx,
+        switchIdx = Indices::switchIdx,
+
+        wPhaseIdx = FluidSystem::wPhaseIdx,
+        nPhaseIdx = FluidSystem::nPhaseIdx,
+
+        wCompIdx = FluidSystem::wCompIdx,
+        nCompIdx = FluidSystem::nCompIdx,
+
+        conti0EqIdx = Indices::conti0EqIdx,
+
+        wPhaseOnly = Indices::wPhaseOnly,
+        nPhaseOnly = Indices::nPhaseOnly,
+        bothPhases = Indices::bothPhases,
+
+        plSg = TwoPNCFormulation::plSg,
+        pgSl = TwoPNCFormulation::pgSl,
+        formulation = GET_PROP_VALUE(TypeTag, Formulation)
+    };
+
+    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, ElementBoundaryTypes) ElementBoundaryTypes;
+    typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, SpatialParams) SpatialParams;
+    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
+
+
+    typedef typename GridView::template Codim<0>::Entity Element;
+    typedef typename GridView::ctype CoordScalar;
+
+
+public:
+    /*!
+     * \brief Constructor. Sets the upwind weight.
+     */
+    TwoPNCLocalResidual()
+    {
+        // retrieve the upwind weight for the mass conservation equations. Use the value
+        // specified via the property system as default, and overwrite
+        // it by the run-time parameter from the Dune::ParameterTree
+        massUpwindWeight_ = GET_PARAM_FROM_GROUP(TypeTag, Scalar, Implicit, MassUpwindWeight);
+    };
+
+    /*!
+     * \brief Evaluate the storage term of the current solution in a
+     *        single phase.
+     *
+     * \param element The element
+     * \param phaseIdx The index of the fluid phase
+     */
+    void evalPhaseStorage(const Element &element, int phaseIdx)
+    {
+        FVElementGeometry fvGeometry;
+        fvGeometry.update(this->gridView_(), element);
+        ElementBoundaryTypes bcTypes;
+        bcTypes.update(this->problem_(), element, fvGeometry);
+        ElementVolumeVariables volVars;
+        volVars.update(this->problem_(), element, fvGeometry, false);
+
+        this->residual_.resize(fvGeometry.numScv);
+        this->residual_ = 0;
+
+        this->elemPtr_ = &element;
+        this->fvElemGeomPtr_ = &fvGeometry;
+        this->bcTypesPtr_ = &bcTypes;
+        this->prevVolVarsPtr_ = 0;
+        this->curVolVarsPtr_ = &volVars;
+        evalPhaseStorage_(phaseIdx);
+    }
+
+    /*!
+     * \brief Evaluate the amount all conservation quantities
+     *        (e.g. phase mass) within a sub-control volume.
+     *
+     * The result should be averaged over the volume (e.g. phase mass
+     * inside a sub control volume divided by the volume)
+     *
+     *  \param storage the mass of the component within the sub-control volume
+     *  \param scvIdx The SCV (sub-control-volume) index
+     *  \param usePrevSol Evaluate function with solution of current or previous time step
+     */
+    void computeStorage(PrimaryVariables &storage, int scvIdx, bool usePrevSol) const
+    {
+        // 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 &elemVolVars = usePrevSol ? this->prevVolVars_()
+                : this->curVolVars_();
+        const VolumeVariables &volVars = elemVolVars[scvIdx];
+
+        // Compute storage term of all fluid components in the fluid phases
+        storage = 0;
+        for (unsigned int phaseIdx = 0; phaseIdx < numPhases /*+ numSPhases*/; ++phaseIdx)
+        {
+            //if(phaseIdx< numPhases)
+            //{
+                for (unsigned int compIdx = 0; compIdx < numComponents; ++compIdx) //H2O, Air, Salt
+                {
+                    int eqIdx = conti0EqIdx + compIdx;
+                    if (replaceCompEqIdx != eqIdx)
+                    {
+                        storage[eqIdx] += volVars.molarDensity(phaseIdx)
+                                        * volVars.saturation(phaseIdx)
+                                        * volVars.moleFraction(phaseIdx, compIdx)
+                                        * volVars.porosity();
+                    }
+                    else
+                    {
+                        storage[replaceCompEqIdx] += volVars.molarDensity(phaseIdx)
+                                                * volVars.saturation(phaseIdx)
+                                                * volVars.porosity();
+                    }
+                }
+        }
+         Valgrind::CheckDefined(storage);
+    }
+    /*!
+     * \brief Evaluates the total flux of all conservation quantities
+     *        over a face of a sub-control volume.
+     *
+     * \param flux The flux over the sub-control-volume face for each component
+     * \param fIdx The index of the sub-control-volume face
+     * \param onBoundary Evaluate flux at inner sub-control-volume face or on a boundary face
+     */
+    void computeFlux(PrimaryVariables &flux, const int fIdx, bool onBoundary = false) const
+    {
+        FluxVariables fluxVars(this->problem_(),
+                      this->element_(),
+                      this->fvGeometry_(),
+                      fIdx,
+                      this->curVolVars_(),
+                      onBoundary);
+
+        flux = 0;
+        asImp_()->computeAdvectiveFlux(flux, fluxVars);
+        asImp_()->computeDiffusiveFlux(flux, fluxVars);
+        Valgrind::CheckDefined(flux);
+    }
+    /*!
+     * \brief Evaluates the advective mass flux of all components over
+     *        a face of a subcontrol volume.
+     *
+     * \param flux The advective flux over the sub-control-volume face for each component
+     * \param fluxVars The flux variables at the current SCV
+     */
+    void computeAdvectiveFlux(PrimaryVariables &flux, const FluxVariables &fluxVars) const
+    {
+        ////////
+        // advective fluxes of all components in all phases
+        ////////
+        for (unsigned int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
+        {
+         // data attached to upstream and the downstream vertices
+         // of the current phase
+         const VolumeVariables &up = this->curVolVars_(fluxVars.upstreamIdx(phaseIdx));
+         const VolumeVariables &dn = this->curVolVars_(fluxVars.downstreamIdx(phaseIdx));
+
+         for (unsigned int compIdx = 0; compIdx < numComponents; ++compIdx)
+         {
+         // add advective flux of current component in current
+         // phase
+            unsigned int eqIdx = conti0EqIdx + compIdx;
+
+         if (eqIdx != replaceCompEqIdx)
+         {
+            // upstream vertex
+            flux[eqIdx] += fluxVars.KmvpNormal(phaseIdx)
+                        * (massUpwindWeight_
+                            * up.mobility(phaseIdx)
+                            * up.molarDensity(phaseIdx)
+                            * up.moleFraction(phaseIdx, compIdx)
+                        +
+                            (1.0 - massUpwindWeight_)
+                            * dn.mobility(phaseIdx)
+                            * dn.molarDensity(phaseIdx)
+                            * dn.moleFraction(phaseIdx, compIdx));
+
+            Valgrind::CheckDefined(fluxVars.KmvpNormal(phaseIdx));
+            Valgrind::CheckDefined(up.molarDensity(phaseIdx));
+            Valgrind::CheckDefined(dn.molarDensity(phaseIdx));
+         }
+         else
+         {
+         flux[replaceCompEqIdx] += fluxVars.KmvpNormal(phaseIdx)
+                                * (massUpwindWeight_
+                                    * up.molarDensity(phaseIdx)
+                                    * up.mobility(phaseIdx)
+                                    +
+                                    (1.0 - massUpwindWeight_)
+                                    * dn.molarDensity(phaseIdx)
+                                    * dn.mobility(phaseIdx));
+
+
+         Valgrind::CheckDefined(fluxVars.KmvpNormal(phaseIdx));
+         Valgrind::CheckDefined(up.molarDensity(phaseIdx));
+         Valgrind::CheckDefined(dn.molarDensity(phaseIdx));
+         }
+         }
+       }
+     }
+
+    /*!
+     * \brief Evaluates the diffusive mass flux of all components over
+     *        a face of a sub-control volume.
+     *
+     * \param flux The flux over the sub-control-volume face for each component
+     * \param fluxVars The flux variables at the current sub-control-volume face
+     */
+    void computeDiffusiveFlux(PrimaryVariables &flux, const FluxVariables &fluxVars) const
+    {
+        //Loop calculates the diffusive flux for every component in a phase. The amount of moles of a component
+        //(eg Air in liquid) in a phase
+        //which is not the main component (eg. H2O in the liquid phase) moved from i to j equals the amount of moles moved
+        //from the main component in a phase (eg. H2O in the liquid phase) from j to i. So two fluxes in each component loop
+        // are calculated in the same phase.
+
+        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
+            for (int compIdx = 0; compIdx < numComponents; ++compIdx)
+            {
+                //add diffusive fluxes only to the component balances
+                if (replaceCompEqIdx != (conti0EqIdx + compIdx))
+                {
+                    Scalar diffCont = - fluxVars.porousDiffCoeff(phaseIdx ,compIdx)
+                                        * fluxVars.molarDensity(phaseIdx)
+                                        * (fluxVars.moleFractionGrad(phaseIdx, compIdx)
+                                            * fluxVars.face().normal);
+                    flux[conti0EqIdx + compIdx] += diffCont;
+                    flux[conti0EqIdx + phaseIdx] -= diffCont;
+                }
+            }
+    }
+
+protected:
+
+    void evalPhaseStorage_(int phaseIdx)
+    {
+        // evaluate the storage terms of a single phase
+        for (int i=0; i < this->fvGeometry_().numScv; i++)
+        {
+            PrimaryVariables &result = this->residual_[i];
+            const ElementVolumeVariables &elemVolVars = this->curVolVars_();
+            const VolumeVariables &volVars = elemVolVars[i];
+
+            // compute storage term of all fluid components within all phases
+            result = 0;
+            for (int compIdx = 0; compIdx < numComponents; ++compIdx)
+            {
+                result[conti0EqIdx + compIdx] += volVars.density(phaseIdx)
+                                * volVars.saturation(phaseIdx)
+                                * volVars.massFraction(phaseIdx, compIdx)
+                                * volVars.porosity();
+            }
+            result *= this->fvGeometry_().subContVol[i].volume;
+        }
+    }
+
+    Implementation *asImp_()
+    { return static_cast<Implementation *> (this); }
+    const Implementation *asImp_() const
+    { return static_cast<const Implementation *> (this); }
+
+public:
+   Scalar massUpwindWeight_;
+};
+
+} // end namespace
+
+#endif
diff --git a/dumux/porousmediumflow/2pnc/implicit/model.hh b/dumux/porousmediumflow/2pnc/implicit/model.hh
new file mode 100644
index 0000000000..7daf35faac
--- /dev/null
+++ b/dumux/porousmediumflow/2pnc/implicit/model.hh
@@ -0,0 +1,741 @@
+// -*- 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/>.   *
+ *****************************************************************************/
+/*!
+* \file
+*
+* \brief Adaption of the fully implicit box scheme to the two-phase n-component flow model.
+*/
+
+#ifndef DUMUX_2PNC_MODEL_HH
+#define DUMUX_2PNC_MODEL_HH
+
+#include <dumux/porousmediumflow/implicit/velocityoutput.hh>
+
+#include "properties.hh"
+#include "indices.hh"
+#include "localresidual.hh"
+
+namespace Dumux
+{
+/*!
+ * \ingroup TwoPNCModel
+ * \brief Adaption of the fully implicit scheme to the
+ *        two-phase n-component fully implicit model.
+ *
+ * This model implements two-phase n-component flow of two compressible and
+ * partially miscible fluids \f$\alpha \in \{ w, n \}\f$ composed of the n components
+ * \f$\kappa \in \{ w, a,\cdots \}\f$. The standard multiphase Darcy
+ * approach is used as the equation for the conservation of momentum:
+ * \f[
+ v_\alpha = - \frac{k_{r\alpha}}{\mu_\alpha} \mbox{\bf K}
+ \left(\text{grad}\, p_\alpha - \varrho_{\alpha} \mbox{\bf g} \right)
+ * \f]
+ *
+ * By inserting this into the equations for the conservation of the
+ * components, one gets one transport equation for each component
+ * \f{eqnarray}
+ && \phi \frac{\partial (\sum_\alpha \varrho_\alpha X_\alpha^\kappa S_\alpha )}
+ {\partial t}
+ - \sum_\alpha  \text{div} \left\{ \varrho_\alpha X_\alpha^\kappa
+ \frac{k_{r\alpha}}{\mu_\alpha} \mbox{\bf K}
+ (\text{grad}\, p_\alpha - \varrho_{\alpha}  \mbox{\bf g}) \right\}
+ \nonumber \\ \nonumber \\
+    &-& \sum_\alpha \text{div} \left\{{\bf D_{\alpha, pm}^\kappa} \varrho_{\alpha} \text{grad}\, X^\kappa_{\alpha} \right\}
+ - \sum_\alpha q_\alpha^\kappa = 0 \qquad \kappa \in \{w, a,\cdots \} \, ,
+ \alpha \in \{w, g\}
+ \f}
+ *
+ * All equations are discretized using a vertex-centered finite volume (box)
+ * or cell-centered finite volume scheme (this is not done for 2pnc approach yet, however possible) as
+ * spatial and the implicit Euler method as time discretization.
+ *
+ * By using constitutive relations for the capillary pressure \f$p_c =
+ * p_n - p_w\f$ and relative permeability \f$k_{r\alpha}\f$ and taking
+ * advantage of the fact that \f$S_w + S_n = 1\f$ and \f$X^\kappa_w + X^\kappa_n = 1\f$, the number of
+ * unknowns can be reduced to number of components.
+ *
+ * The used primary variables are, like in the two-phase model, either \f$p_w\f$ and \f$S_n\f$
+ * or \f$p_n\f$ and \f$S_w\f$. The formulation which ought to be used can be
+ * specified by setting the <tt>Formulation</tt> property to either
+ * TwoPTwoCIndices::pWsN or TwoPTwoCIndices::pNsW. By
+ * default, the model uses \f$p_w\f$ and \f$S_n\f$.
+ *
+ * Moreover, the second primary variable depends on the phase state, since a
+ * primary variable switch is included. The phase state is stored for all nodes
+ * of the system. The model is uses mole fractions.
+ *Following cases can be distinguished:
+ * <ul>
+ *  <li> Both phases are present: The saturation is used (either \f$S_n\f$ or \f$S_w\f$, dependent on the chosen <tt>Formulation</tt>),
+ *      as long as \f$ 0 < S_\alpha < 1\f$</li>.
+ *  <li> Only wetting phase is present: The mass fraction of, e.g., air in the wetting phase \f$X^a_w\f$ is used,
+ *      as long as the maximum mass fraction is not exceeded (\f$X^a_w<X^a_{w,max}\f$)</li>
+ *  <li> Only non-wetting phase is present: The mass fraction of, e.g., water in the non-wetting phase, \f$X^w_n\f$, is used,
+ *      as long as the maximum mass fraction is not exceeded (\f$X^w_n<X^w_{n,max}\f$)</li>
+ * </ul>
+ */
+
+template<class TypeTag>
+class TwoPNCModel: public GET_PROP_TYPE(TypeTag, BaseModel)
+{
+    typedef typename GET_PROP_TYPE(TypeTag, BaseModel) ParentType;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
+
+    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
+    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector;
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+
+    enum { dim = GridView::dimension };
+    enum { dimWorld = GridView::dimensionworld };
+
+    enum { numEq = GET_PROP_VALUE(TypeTag, NumEq) };
+    enum { numPhases = GET_PROP_VALUE(TypeTag, NumPhases) };
+    enum {  numComponents = GET_PROP_VALUE(TypeTag, NumComponents) };
+    enum {  numMajorComponents = GET_PROP_VALUE(TypeTag, NumMajorComponents) };
+
+    enum {
+            pressureIdx = Indices::pressureIdx,
+            switchIdx = Indices::switchIdx
+    };
+    enum {
+            wPhaseIdx = Indices::wPhaseIdx,
+            nPhaseIdx = Indices::nPhaseIdx
+    };
+    enum {
+            wCompIdx = FluidSystem::wCompIdx,
+            nCompIdx = FluidSystem::nCompIdx
+    };
+    enum {
+            wPhaseOnly = Indices::wPhaseOnly,
+            nPhaseOnly = Indices::nPhaseOnly,
+            bothPhases = Indices::bothPhases
+    };
+    enum {
+            plSg = TwoPNCFormulation::plSg,
+            pgSl = TwoPNCFormulation::pgSl,
+            formulation = GET_PROP_VALUE(TypeTag, Formulation)
+    };
+
+    typedef CompositionalFluidState<Scalar, FluidSystem> FluidState;
+
+    typedef typename GridView::template Codim<dim>::Entity Vertex;
+    typedef typename GridView::template Codim<0>::Entity Element;
+
+    typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition;
+    typedef typename GridView::ctype CoordScalar;
+    typedef Dune::FieldMatrix<CoordScalar, dimWorld, dimWorld> Tensor;
+
+    enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) };
+    enum { dofCodim = isBox ? dim : 0 };
+
+public:
+    /*!
+     * \brief Initialize the static data with the initial solution.
+     *
+     * \param problem The problem to be solved
+     */
+    void init(Problem &problem)
+    {
+        ParentType::init(problem);
+
+        unsigned numDofs = this->numDofs();
+
+        staticDat_.resize(numDofs);
+
+        setSwitched_(false);
+
+        for (const auto& element : Dune::elements(this->gridView_()))
+        {
+            if (!isBox) // i.e. cell-centered discretization
+            {
+                int dofIdxGlobal = this->dofMapper().index(element);
+                const GlobalPosition &globalPos = element.geometry().center();
+
+                // initialize phase presence
+                staticDat_[dofIdxGlobal].phasePresence
+                    = this->problem_().initialPhasePresence(*(this->gridView_().template begin<dim>()),
+                                                            dofIdxGlobal, globalPos);
+                staticDat_[dofIdxGlobal].wasSwitched = false;
+
+                staticDat_[dofIdxGlobal].oldPhasePresence
+                    = staticDat_[dofIdxGlobal].phasePresence;
+            }
+        }
+
+        if (isBox) // i.e. vertex-centered discretization
+        {
+            for (const auto& vertex : Dune::vertices(this->gridView_()))
+            {
+                int dofIdxGlobal = this->dofMapper().index(vertex);
+                const GlobalPosition &globalPos = vertex.geometry().corner(0);
+
+                // initialize phase presence
+                staticDat_[dofIdxGlobal].phasePresence
+                    = this->problem_().initialPhasePresence(vertex, dofIdxGlobal,
+                                                            globalPos);
+                staticDat_[dofIdxGlobal].wasSwitched = false;
+
+                staticDat_[dofIdxGlobal].oldPhasePresence
+                    = staticDat_[dofIdxGlobal].phasePresence;
+            }
+        }
+    }
+
+    /*!
+     * \brief Compute the total storage of all conservation quantities in one phase
+     *
+     * \param storage Contains the storage of each component in one phase
+     * \param phaseIdx The phase index
+     */
+    void globalPhaseStorage(PrimaryVariables &storage, int phaseIdx)
+    {
+        storage = 0;
+
+        for (const auto& element : Dune::elements(this->gridView_()))
+        {
+            if(element.partitionType() == Dune::InteriorEntity)
+            {
+                this->localResidual().evalPhaseStorage(element, phaseIdx);
+
+                for (unsigned int i = 0; i < this->localResidual().storageTerm().size(); ++i)
+                    storage += this->localResidual().storageTerm()[i];
+            }
+        }
+
+        this->gridView_().comm().sum(storage);
+    }
+
+    /*!
+     * \brief Called by the update() method if applying the newton
+     *         method was unsuccessful.
+     */
+    void updateFailed()
+    {
+        ParentType::updateFailed();
+
+        setSwitched_(false);
+        resetPhasePresence_();
+    }
+
+    /*!
+     * \brief Called by the problem if a time integration was
+     *        successful, post processing of the solution is done and the
+     *        result has been written to disk.
+     *
+     * This should prepare the model for the next time integration.
+     */
+    void advanceTimeLevel()
+    {
+        ParentType::advanceTimeLevel();
+
+        // update the phase state
+        updateOldPhasePresence_();
+        setSwitched_(false);
+    }
+
+    /*!
+     * \brief Return true if the primary variables were switched for
+     *        at least one vertex after the last timestep.
+     */
+    bool switched() const
+    {
+        return switchFlag_;
+    }
+
+    /*!
+     * \brief Returns the phase presence of the current or the old solution of a vertex.
+     *
+     * \param globalVertexIdx The global vertex index
+     * \param oldSol Evaluate function with solution of current or previous time step
+     */
+    int phasePresence(int globalVertexIdx, bool oldSol) const
+    {
+        return oldSol ? staticDat_[globalVertexIdx].oldPhasePresence
+                : staticDat_[globalVertexIdx].phasePresence;
+    }
+
+    /*!
+     * \brief Append all quantities of interest which can be derived
+     *        from the solution of the current time step to the VTK
+     *        writer.
+     *
+     * \param sol The solution vector
+     * \param writer The writer for multi-file VTK datasets
+     */
+    template<class MultiWriter>
+    void addOutputVtkFields(const SolutionVector &sol,
+                            MultiWriter &writer)
+    {
+
+        typedef Dune::BlockVector<Dune::FieldVector<Scalar, 1> > ScalarField;
+        typedef Dune::BlockVector<Dune::FieldVector<Scalar, dim> > VectorField;
+
+        // get the number of degrees of freedom
+        unsigned numDofs = this->numDofs();
+
+        ScalarField *Sg            = writer.allocateManagedBuffer (numDofs);
+        ScalarField *Sl            = writer.allocateManagedBuffer (numDofs);
+        ScalarField *pg            = writer.allocateManagedBuffer (numDofs);
+        ScalarField *pl            = writer.allocateManagedBuffer (numDofs);
+        ScalarField *pc            = writer.allocateManagedBuffer (numDofs);
+        ScalarField *rhoL          = writer.allocateManagedBuffer (numDofs);
+        ScalarField *rhoG          = writer.allocateManagedBuffer (numDofs);
+        ScalarField *mobL          = writer.allocateManagedBuffer (numDofs);
+        ScalarField *mobG          = writer.allocateManagedBuffer (numDofs);
+        ScalarField *temperature   = writer.allocateManagedBuffer (numDofs);
+        ScalarField *poro          = writer.allocateManagedBuffer (numDofs);
+        ScalarField *boxVolume     = writer.allocateManagedBuffer (numDofs);
+        VectorField *velocityN = writer.template allocateManagedBuffer<double, dim>(numDofs);
+        VectorField *velocityW = writer.template allocateManagedBuffer<double, dim>(numDofs);
+        ImplicitVelocityOutput<TypeTag> velocityOutput(this->problem_());
+
+        if (velocityOutput.enableOutput()) // check if velocity output is demanded
+        {
+            // initialize velocity fields
+            for (unsigned int i = 0; i < numDofs; ++i)
+            {
+                (*velocityN)[i] = Scalar(0);
+                (*velocityW)[i] = Scalar(0);
+            }
+        }
+
+        ScalarField *moleFraction[numPhases][numComponents];
+        for (int i = 0; i < numPhases; ++i)
+            for (int j = 0; j < numComponents; ++j)
+                moleFraction[i][j] = writer.allocateManagedBuffer(numDofs);
+
+        ScalarField *molarity[numComponents];
+        for (int j = 0; j < numComponents ; ++j)
+            molarity[j] = writer.allocateManagedBuffer(numDofs);
+
+        ScalarField *Perm[dim];
+        for (int j = 0; j < dim; ++j) //Permeability only in main directions xx and yy
+            Perm[j] = writer.allocateManagedBuffer(numDofs);
+
+        *boxVolume = 0;
+
+        unsigned numElements = this->gridView_().size(0);
+        ScalarField *rank = writer.allocateManagedBuffer (numElements);
+
+        FVElementGeometry fvGeometry;
+        VolumeVariables volVars;
+        ElementVolumeVariables elemVolVars;
+
+        for (const auto& element : Dune::elements(this->gridView_()))
+        {
+            int eIdxGlobal = this->problem_().elementMapper().index(element);
+            (*rank)[eIdxGlobal] = this->gridView_().comm().rank();
+            fvGeometry.update(this->gridView_(), element);
+
+            elemVolVars.update(this->problem_(),
+                               element,
+                               fvGeometry,
+                               false /* oldSol? */);
+
+            for (int scvIdx = 0; scvIdx < fvGeometry.numScv; ++scvIdx)
+            {
+                int dofIdxGlobal = this->dofMapper().subIndex(element, scvIdx, dofCodim);
+
+                volVars.update(sol[dofIdxGlobal],
+                               this->problem_(),
+                               element,
+                               fvGeometry,
+                               scvIdx,
+                               false);
+
+                GlobalPosition globalPos = fvGeometry.subContVol[scvIdx].global;
+                (*Sg)[dofIdxGlobal]             = elemVolVars[scvIdx].saturation(nPhaseIdx);
+                (*Sl)[dofIdxGlobal]             = elemVolVars[scvIdx].saturation(wPhaseIdx);
+                (*pg)[dofIdxGlobal]             = elemVolVars[scvIdx].pressure(nPhaseIdx);
+                (*pl)[dofIdxGlobal]             = elemVolVars[scvIdx].pressure(wPhaseIdx);
+                (*pc)[dofIdxGlobal]             = elemVolVars[scvIdx].capillaryPressure();
+                (*rhoL)[dofIdxGlobal]           = elemVolVars[scvIdx].density(wPhaseIdx);
+                (*rhoG)[dofIdxGlobal]           = elemVolVars[scvIdx].density(nPhaseIdx);
+                (*mobL)[dofIdxGlobal]           = elemVolVars[scvIdx].mobility(wPhaseIdx);
+                (*mobG)[dofIdxGlobal]           = elemVolVars[scvIdx].mobility(nPhaseIdx);
+                (*boxVolume)[dofIdxGlobal]     += fvGeometry.subContVol[scvIdx].volume;
+                (*poro)[dofIdxGlobal]           = elemVolVars[scvIdx].porosity();
+                (*temperature)[dofIdxGlobal]    = elemVolVars[scvIdx].temperature();
+
+                for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
+                {
+                    for (int compIdx = 0; compIdx < numComponents; ++compIdx)
+                    {
+                        (*moleFraction[phaseIdx][compIdx])[dofIdxGlobal]= volVars.moleFraction(phaseIdx,compIdx);
+                        Valgrind::CheckDefined((*moleFraction[phaseIdx][compIdx])[dofIdxGlobal]);
+                    }
+                }
+                for (int compIdx = 0; compIdx < numComponents; ++compIdx)
+                    (*molarity[compIdx])[dofIdxGlobal] = (volVars.molarity(wPhaseIdx, compIdx));
+
+                Tensor K = perm_(this->problem_().spatialParams().intrinsicPermeability(element, fvGeometry, scvIdx));
+
+                for (int j = 0; j<dim; ++j)
+                    (*Perm[j])[dofIdxGlobal] = K[j][j] /* volVars.permFactor()*/;
+            };
+
+            // velocity output
+            if(velocityOutput.enableOutput()){
+                velocityOutput.calculateVelocity(*velocityW, elemVolVars, fvGeometry, element, wPhaseIdx);
+                velocityOutput.calculateVelocity(*velocityN, elemVolVars, fvGeometry, element, nPhaseIdx);
+            }
+
+        } // loop over element
+
+        writer.attachDofData(*Sg, "Sg", isBox);
+        writer.attachDofData(*Sl, "Sl", isBox);
+        writer.attachDofData(*pg, "pg", isBox);
+        writer.attachDofData(*pl, "pl", isBox);
+        writer.attachDofData(*pc, "pc", isBox);
+        writer.attachDofData(*rhoL, "rhoL", isBox);
+        writer.attachDofData(*rhoG, "rhoG", isBox);
+        writer.attachDofData(*mobL, "mobL", isBox);
+        writer.attachDofData(*mobG, "mobG", isBox);
+        writer.attachDofData(*poro, "porosity", isBox);
+        writer.attachDofData(*temperature, "temperature", isBox);
+        writer.attachDofData(*boxVolume, "boxVolume", isBox);
+        writer.attachDofData(*Perm[0], "Kxx", isBox);
+        if (dim >= 2)
+            writer.attachDofData(*Perm[1], "Kyy", isBox);
+        if (dim == 3)
+            writer.attachDofData(*Perm[2], "Kzz", isBox);
+
+        for (int i = 0; i < numPhases; ++i)
+        {
+            for (int j = 0; j < numComponents; ++j)
+            {
+                std::ostringstream oss;
+                oss << "x"
+                    << FluidSystem::componentName(j)
+                    << FluidSystem::phaseName(i);
+                writer.attachDofData(*moleFraction[i][j], oss.str().c_str(), isBox);
+            }
+        }
+
+        for (int j = 0; j < numComponents; ++j)
+        {
+            std::ostringstream oss;
+            oss << "m^w_"
+                << FluidSystem::componentName(j);
+            writer.attachDofData(*molarity[j], oss.str().c_str(), isBox);
+        }
+
+        if (velocityOutput.enableOutput()) // check if velocity output is demanded
+        {
+            writer.attachDofData(*velocityW,  "velocityW", isBox, dim);
+            writer.attachDofData(*velocityN,  "velocityN", isBox, dim);
+        }
+
+        writer.attachCellData(*rank, "process rank");
+    }
+
+    /*!
+     * \brief Write the current solution to a restart file.
+     *
+     * \param outStream The output stream of one vertex for the restart file
+     * \param entity The Entity
+     */
+    template<class Entity>
+    void serializeEntity(std::ostream &outStream, const Entity &entity)
+    {
+        // write primary variables
+        ParentType::serializeEntity(outStream, entity);
+        int dofIdxGlobal = this->dofMapper().index(entity);
+
+        if (!outStream.good())
+            DUNE_THROW(Dune::IOError, "Could not serialize vertex " << dofIdxGlobal);
+
+        outStream << staticDat_[dofIdxGlobal].phasePresence << " ";
+    }
+
+    /*!
+     * \brief Reads the current solution for a vertex from a restart
+     *        file.
+     *
+     * \param inStream The input stream of one vertex from the restart file
+     * \param entity The Entity
+     */
+    template<class Entity>
+    void deserializeEntity(std::istream &inStream, const Entity &entity)
+    {
+        // read primary variables
+        ParentType::deserializeEntity(inStream, entity);
+        int dofIdxGlobal = this->dofMapper().index(entity);
+
+        if (!inStream.good())
+            DUNE_THROW(Dune::IOError,
+                       "Could not deserialize vertex " << dofIdxGlobal);
+
+        inStream >> staticDat_[dofIdxGlobal].phasePresence;
+        staticDat_[dofIdxGlobal].oldPhasePresence
+                = staticDat_[dofIdxGlobal].phasePresence;
+
+    }
+
+    /*!
+     * \brief Update the static data of all vertices in the grid.
+     *
+     * \param curGlobalSol The current global solution
+     * \param oldGlobalSol The previous global solution
+     */
+    void updateStaticData(SolutionVector &curGlobalSol,
+                          const SolutionVector &oldGlobalSol)
+    {
+        bool wasSwitched = false;
+
+        for (unsigned i = 0; i < staticDat_.size(); ++i)
+            staticDat_[i].visited = false;
+
+        FVElementGeometry fvGeometry;
+        static VolumeVariables volVars;
+        for (const auto& element : Dune::elements(this->gridView_()))
+        {
+            fvGeometry.update(this->gridView_(), element);
+            for (int scvIdx = 0; scvIdx < fvGeometry.numScv; ++scvIdx)
+            {
+                int dofIdxGlobal = this->dofMapper().subIndex(element, scvIdx, dim);
+
+                if (staticDat_[dofIdxGlobal].visited)
+                    continue;
+
+                staticDat_[dofIdxGlobal].visited = true;
+                volVars.update(curGlobalSol[dofIdxGlobal],
+                               this->problem_(),
+                               element,
+                               fvGeometry,
+                               scvIdx,
+                               false);
+                const GlobalPosition &global = element.geometry().corner(scvIdx);
+                if (primaryVarSwitch_(curGlobalSol, volVars, dofIdxGlobal, global))
+                    wasSwitched = true;
+            }
+        }
+
+        // make sure that if there was a variable switch in an
+        // other partition we will also set the switch flag
+        // for our partition.
+        wasSwitched = this->gridView_().comm().max(wasSwitched);
+
+        setSwitched_(wasSwitched);
+    }
+
+protected:
+    /*!
+     * \brief Data which is attached to each vertex and is not only
+     *        stored locally.
+     */
+    struct StaticVars
+    {
+        int phasePresence;
+        bool wasSwitched;
+
+        int oldPhasePresence;
+        bool visited;
+    };
+
+    Tensor perm_(Scalar perm)
+    {
+        Tensor K(0.0);
+
+        for(int i=0; i<dim; i++)
+            K[i][i] = perm;
+
+       return K;
+    }
+
+    Tensor perm_(Tensor perm)
+    {
+       return perm;
+    }
+
+    /*!
+     * \brief Reset the current phase presence of all vertices to the old one.
+     *
+     * This is done after an update failed.
+     */
+    void resetPhasePresence_()
+    {
+        int numDofs = this->gridView_().size(dim);
+        for (int i = 0; i < numDofs; ++i)
+        {
+            staticDat_[i].phasePresence
+                    = staticDat_[i].oldPhasePresence;
+            staticDat_[i].wasSwitched = false;
+        }
+    }
+
+    /*!
+     * \brief Set the old phase of all verts state to the current one.
+     */
+    void updateOldPhasePresence_()
+    {
+        int numDofs = this->gridView_().size(dim);
+        for (int i = 0; i < numDofs; ++i)
+        {
+            staticDat_[i].oldPhasePresence
+                    = staticDat_[i].phasePresence;
+            staticDat_[i].wasSwitched = false;
+        }
+    }
+
+    /*!
+     * \brief Set whether there was a primary variable switch after in
+     *        the last timestep.
+     */
+    void setSwitched_(bool yesno)
+    {
+        switchFlag_ = yesno;
+    }
+
+    //  perform variable switch at a vertex; Returns true if a
+    //  variable switch was performed.
+    bool primaryVarSwitch_(SolutionVector &globalSol,
+                           const VolumeVariables &volVars, int dofIdxGlobal,
+                           const GlobalPosition &globalPos)
+    {
+
+            // evaluate primary variable switch
+            bool wouldSwitch = false;
+            int phasePresence = staticDat_[dofIdxGlobal].phasePresence;
+            int newPhasePresence = phasePresence;
+
+            //check if a primary variable switch is necessary
+            if (phasePresence == bothPhases)
+            {
+                Scalar Smin = 0; //saturation threshold
+                if (staticDat_[dofIdxGlobal].wasSwitched)
+                    Smin = -0.01;
+
+                //if saturation of liquid phase is smaller 0 switch
+                if (volVars.saturation(wPhaseIdx) <= Smin)
+                {
+                    wouldSwitch = true;
+                    //liquid phase has to disappear
+                    std::cout << "Liquid Phase disappears at vertex " << dofIdxGlobal
+                                << ", coordinated: " << globalPos << ", Sl: "
+                                << volVars.saturation(wPhaseIdx) << std::endl;
+                    newPhasePresence = nPhaseOnly;
+
+                    //switch not depending on formulation
+                    //switch "Sl" to "xgH20"
+                    globalSol[dofIdxGlobal][switchIdx]
+                            = volVars.moleFraction(nPhaseIdx, wCompIdx /*H2O*/);
+
+                    //switch all secondary components to mole fraction in gas phase
+                    for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx)
+                        globalSol[dofIdxGlobal][compIdx] = volVars.moleFraction(nPhaseIdx,compIdx);
+                }
+                //if saturation of gas phase is smaller than 0 switch
+                else if (volVars.saturation(nPhaseIdx) <= Smin)
+                {
+                    wouldSwitch = true;
+                    //gas phase has to disappear
+                    std::cout << "Gas Phase disappears at vertex " << dofIdxGlobal
+                                << ", coordinated: " << globalPos << ", Sg: "
+                                << volVars.saturation(nPhaseIdx) << std::endl;
+                    newPhasePresence = wPhaseOnly;
+
+                    //switch "Sl" to "xlN2"
+                    globalSol[dofIdxGlobal][switchIdx]
+                            = volVars.moleFraction(wPhaseIdx, nCompIdx /*N2*/);
+                }
+            }
+            else if (phasePresence == nPhaseOnly)
+            {
+                Scalar xlmax = 1;
+                Scalar sumxl = 0;
+                //Calculate sum of mole fractions in the hypothetical liquid phase
+                for (int compIdx = 0; compIdx < numComponents; compIdx++)
+                {
+                    sumxl += volVars.moleFraction(wPhaseIdx, compIdx);
+                }
+                if (sumxl > xlmax)
+                    wouldSwitch = true;
+                if (staticDat_[dofIdxGlobal].wasSwitched)
+                    xlmax *=1.02;
+                //liquid phase appears if sum is larger than one
+                if (sumxl/*sum of mole fractions*/ > xlmax/*1*/)
+                {
+                    std::cout << "Liquid Phase appears at vertex " << dofIdxGlobal
+                            << ", coordinated: " << globalPos << ", sumxl: "
+                            << sumxl << std::endl;
+                    newPhasePresence = bothPhases;
+
+                    //saturation of the liquid phase set to 0.0001 (if formulation pgSl and vice versa)
+                    if (formulation == pgSl)
+                        globalSol[dofIdxGlobal][switchIdx] = 0.0001;
+                    else if (formulation == plSg)
+                        globalSol[dofIdxGlobal][switchIdx] = 0.9999;
+
+                    //switch all secondary components back to liquid mole fraction
+                    for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx)
+                        globalSol[dofIdxGlobal][compIdx] = volVars.moleFraction(wPhaseIdx,compIdx);
+                }
+            }
+            else if (phasePresence == wPhaseOnly)
+            {
+                Scalar xgmax = 1;
+                Scalar sumxg = 0;
+                //Calculate sum of mole fractions in the hypothetical liquid phase
+                for (int compIdx = 0; compIdx < numComponents; compIdx++)
+                {
+                    sumxg += volVars.moleFraction(nPhaseIdx, compIdx);
+                }
+                if (sumxg > xgmax)
+                    wouldSwitch = true;
+                if (staticDat_[dofIdxGlobal].wasSwitched)
+                    xgmax *=1.02;
+                //liquid phase appears if sum is larger than one
+                if (sumxg > xgmax)
+                {
+                    std::cout << "Gas Phase appears at vertex " << dofIdxGlobal
+                            << ", coordinated: " << globalPos << ", sumxg: "
+                            << sumxg << std::endl;
+                    newPhasePresence = bothPhases;
+                    //saturation of the liquid phase set to 0.9999 (if formulation pgSl and vice versa)
+                    if (formulation == pgSl)
+                        globalSol[dofIdxGlobal][switchIdx] = 0.9999;
+                    else if (formulation == plSg)
+                        globalSol[dofIdxGlobal][switchIdx] = 0.0001;
+
+                }
+            }
+
+
+            staticDat_[dofIdxGlobal].phasePresence = newPhasePresence;
+            staticDat_[dofIdxGlobal].wasSwitched = wouldSwitch;
+            return phasePresence != newPhasePresence;
+        }
+
+    // parameters given in constructor
+    std::vector<StaticVars> staticDat_;
+    bool switchFlag_;
+};
+
+}
+
+#include "propertydefaults.hh"
+
+#endif
diff --git a/dumux/porousmediumflow/2pnc/implicit/newtoncontroller.hh b/dumux/porousmediumflow/2pnc/implicit/newtoncontroller.hh
new file mode 100644
index 0000000000..d5a41740fc
--- /dev/null
+++ b/dumux/porousmediumflow/2pnc/implicit/newtoncontroller.hh
@@ -0,0 +1,105 @@
+// -*- 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/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ * \brief A two-phase n-component specific controller for the newton solver.
+ */
+#ifndef DUMUX_2PNC_NEWTON_CONTROLLER_HH
+#define DUMUX_2PNC_NEWTON_CONTROLLER_HH
+
+#include "properties.hh"
+
+#include <dumux/nonlinear/newtoncontroller.hh>
+
+namespace Dumux {
+/*!
+ * \ingroup Newton
+ * \ingroup TwoPNCModel
+ * \brief A two-phase n-component specific controller for the newton solver.
+ *
+ * This controller 'knows' what a 'physically meaningful' solution is
+ * which allows the newton method to abort quicker if the solution is
+ * way out of bounds.
+ */
+template <class TypeTag>
+class TwoPNCNewtonController : public NewtonController<TypeTag>
+{
+    typedef NewtonController<TypeTag> ParentType;
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(Problem)) Problem;
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(SolutionVector)) SolutionVector;
+
+public:
+  TwoPNCNewtonController(Problem &problem)
+      : ParentType(problem)
+    {};
+
+
+    /*!
+     * \brief
+     * Suggest a new time step size based either on the number of newton
+     * iterations required or on the variable switch
+     *
+     * \param uCurrentIter The current global solution vector
+     * \param uLastIter The previous global solution vector
+     *
+     */
+    void newtonEndStep(SolutionVector &uCurrentIter,
+                       const SolutionVector &uLastIter)
+    {
+        int succeeded;
+        try {
+            // call the method of the base class
+            this->method().model().updateStaticData(uCurrentIter, uLastIter);
+            ParentType::newtonEndStep(uCurrentIter, uLastIter);
+
+            succeeded = 1;
+            if (this->gridView_().comm().size() > 1)
+                succeeded = this->gridView_().comm().min(succeeded);
+        }
+        catch (Dumux::NumericalProblem &e)
+        {
+            std::cout << "rank " << this->problem_().gridView().comm().rank()
+                      << " caught an exception while updating:" << e.what()
+                      << "\n";
+            succeeded = 0;
+            if (this->gridView_().comm().size() > 1)
+                succeeded = this->gridView_().comm().min(succeeded);
+        }
+
+        if (!succeeded) {
+            DUNE_THROW(NumericalProblem,
+                       "A process did not succeed in linearizing the system");
+        }
+    }
+
+    /*!
+     * \brief Returns true if the current solution can be considered to
+     *        be accurate enough
+     */
+    bool newtonConverged()
+    {
+        if (this->method().model().switched())
+            return false;
+
+        return ParentType::newtonConverged();
+    }
+};
+}
+
+#endif
diff --git a/dumux/porousmediumflow/2pnc/implicit/properties.hh b/dumux/porousmediumflow/2pnc/implicit/properties.hh
new file mode 100644
index 0000000000..44e495060a
--- /dev/null
+++ b/dumux/porousmediumflow/2pnc/implicit/properties.hh
@@ -0,0 +1,82 @@
+// -*- 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/>.   *
+ *****************************************************************************/
+/*!
+ * \ingroup Properties
+ * \ingroup ImplicitProperties
+ * \ingroup TwoPNCModel
+ *
+ * \file
+ *
+ * \brief Defines the properties required for the two-phase n-component
+ *        fully implicit model.
+ */
+#ifndef DUMUX_2PNC_PROPERTIES_HH
+#define DUMUX_2PNC_PROPERTIES_HH
+
+#include <dumux/implicit/box/properties.hh>
+#include <dumux/implicit/cellcentered/properties.hh>
+#include <dumux/porousmediumflow/nonisothermal/implicit/properties.hh>
+
+namespace Dumux
+{
+
+namespace Properties
+{
+//////////////////////////////////////////////////////////////////
+// Type tags
+//////////////////////////////////////////////////////////////////
+
+//! The type tag for the implicit isothermal two phase n component problems
+NEW_TYPE_TAG(TwoPNC);
+NEW_TYPE_TAG(BoxTwoPNC, INHERITS_FROM(BoxModel, TwoPNC));
+NEW_TYPE_TAG(CCTwoPNC, INHERITS_FROM(CCModel, TwoPNC));
+
+//! The type tag for the implicit non-isothermal two phase n component problems
+NEW_TYPE_TAG(TwoPNCNI, INHERITS_FROM(TwoPNC, NonIsothermal));
+NEW_TYPE_TAG(BoxTwoPNCNI, INHERITS_FROM(BoxModel, TwoPNCNI));
+NEW_TYPE_TAG(CCTwoPNCNI, INHERITS_FROM(CCModel, TwoPNCNI));
+
+//////////////////////////////////////////////////////////////////
+// Property tags
+//////////////////////////////////////////////////////////////////
+
+NEW_PROP_TAG(NumPhases);   //!< Number of fluid phases in the system
+NEW_PROP_TAG(NumComponents); //!< Number of fluid components in the system
+NEW_PROP_TAG(NumMajorComponents); //!< Number of major fluid components which are considered in the calculation of the phase density
+NEW_PROP_TAG(TwoPNCIndices); //!< Enumerations for the 2pncMin models
+NEW_PROP_TAG(Formulation);   //!< The formulation of the model
+NEW_PROP_TAG(SpatialParams); //!< The type of the spatial parameters
+NEW_PROP_TAG(FluidSystem); //!< Type of the multi-component relations
+NEW_PROP_TAG(FluidState); //!< Type of the fluid state of the 2pnc model
+NEW_PROP_TAG(Indices); //!< Enumerations for the model
+NEW_PROP_TAG(Chemistry); //!< The chemistry class with which solves equlibrium reactions
+
+NEW_PROP_TAG(MaterialLaw);   //!< The material law which ought to be used (extracted from the spatial parameters)
+NEW_PROP_TAG(MaterialLawParams); //!< The parameters of the material law (extracted from the spatial parameters)
+
+NEW_PROP_TAG(ReplaceCompEqIdx); //!< The index of the total mass balance equation, if one component balance is replaced (ReplaceCompEqIdx < NumComponents)
+NEW_PROP_TAG(VtkAddVelocity); //!< Returns whether velocity vectors are written into the vtk output
+NEW_PROP_TAG(ProblemEnableGravity); //!< Returns whether gravity is considered in the problem
+NEW_PROP_TAG(ImplicitMassUpwindWeight); //!< The value of the upwind weight for the mass conservation equations
+NEW_PROP_TAG(ImplicitMobilityUpwindWeight); //!< The value of the upwind parameter for the mobility
+NEW_PROP_TAG(BaseFluxVariables); //! The base flux variables
+}
+}
+
+#endif
diff --git a/dumux/porousmediumflow/2pnc/implicit/propertydefaults.hh b/dumux/porousmediumflow/2pnc/implicit/propertydefaults.hh
new file mode 100644
index 0000000000..753d77bea2
--- /dev/null
+++ b/dumux/porousmediumflow/2pnc/implicit/propertydefaults.hh
@@ -0,0 +1,225 @@
+// -*- 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/>.   *
+ *****************************************************************************/
+/*!
+ * \ingroup Properties
+ * \ingroup ImplicitProperties
+ * \ingroup TwoPNCModel
+ * \file
+ *
+ * \brief Defines default values for most properties required by the
+ *        two-phase n-component fully implicit model.
+ */
+#ifndef DUMUX_2PNC_PROPERTY_DEFAULTS_HH
+#define DUMUX_2PNC_PROPERTY_DEFAULTS_HH
+
+#include "indices.hh"
+#include "model.hh"
+#include "fluxvariables.hh"
+#include "volumevariables.hh"
+#include "properties.hh"
+#include "newtoncontroller.hh"
+
+#include <dumux/porousmediumflow/nonisothermal/implicit/propertydefaults.hh>
+#include <dumux/porousmediumflow/implicit/darcyfluxvariables.hh>
+#include <dumux/material/spatialparams/implicitspatialparams.hh>
+#include <dumux/material/fluidmatrixinteractions/2p/thermalconductivitysomerton.hh>
+
+namespace Dumux
+{
+
+namespace Properties {
+//////////////////////////////////////////////////////////////////
+// Property values
+//////////////////////////////////////////////////////////////////
+
+/*!
+ * \brief Set the property for the number of components.
+ *
+ * We just forward the number from the fluid system
+ *
+ */
+SET_PROP(TwoPNC, NumComponents)
+{
+private:
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(FluidSystem)) FluidSystem;
+
+public:
+    static const int value = FluidSystem::numComponents;
+
+};
+//! Set as default that no component mass balance is replaced by the total mass balance
+SET_PROP(TwoPNC, ReplaceCompEqIdx)
+{
+private:
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(FluidSystem)) FluidSystem;
+
+public:
+    static const int value = FluidSystem::numComponents;
+};
+//! The major components belonging to the existing phases are mentioned here e.g., 2 for water and air being the major component in the liquid and gas phases in a 2 phase system
+SET_PROP(TwoPNC, NumMajorComponents)
+{
+private:
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(FluidSystem)) FluidSystem;
+
+public:
+    static const int value = FluidSystem::numPhases;
+    static_assert(value == 2,
+                  "The model is restricted to two-phases, thus number of major components must also be two.");
+};
+
+/*!
+ * \brief Set the property for the number of fluid phases.
+ *
+ * We just forward the number from the fluid system and use an static
+ * assert to make sure it is 2.
+ */
+SET_PROP(TwoPNC, NumPhases)
+{
+private:
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(FluidSystem)) FluidSystem;
+
+public:
+    static const int value = FluidSystem::numPhases;
+    static_assert(value == 2,
+                  "Only fluid systems with 2 fluid phases are supported by the 2p-nc model!");
+};
+/*!
+ * \brief Set the property for the number of equations: For each existing component one equation has to be solved.
+ */
+SET_PROP(TwoPNC, NumEq)
+{
+private:
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(FluidSystem)) FluidSystem;
+
+public:
+    static const int value = FluidSystem::numComponents;
+};
+
+/*!
+ * \brief The fluid state which is used by the volume variables to
+ *        store the thermodynamic state. This should be chosen
+ *        appropriately for the model ((non-)isothermal, equilibrium, ...).
+ *        This can be done in the problem.
+ */
+SET_PROP(TwoPNC, FluidState){
+    private:
+        typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+        typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+    public:
+        typedef Dumux::CompositionalFluidState<Scalar, FluidSystem> type;
+};
+
+//! Set the default formulation to pl-Sg: This can be over written in the problem.
+SET_INT_PROP(TwoPNC, Formulation, TwoPNCFormulation::plSg);
+
+//! Set the property for the material parameters by extracting it from the material law.
+SET_PROP(TwoPNC, MaterialLawParams)
+{
+private:
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(MaterialLaw)) MaterialLaw;
+
+public:
+    typedef typename MaterialLaw::Params type;
+};
+
+//! Use the 2pnc local residual
+SET_TYPE_PROP(TwoPNC, LocalResidual, TwoPNCLocalResidual<TypeTag>);
+
+//! Use the 2pnc newton controller
+SET_TYPE_PROP(TwoPNC, NewtonController, TwoPNCNewtonController<TypeTag>);
+
+//! the Model property
+SET_TYPE_PROP(TwoPNC, Model, TwoPNCModel<TypeTag>);
+
+//! the VolumeVariables property
+SET_TYPE_PROP(TwoPNC, VolumeVariables, TwoPNCVolumeVariables<TypeTag>);
+
+//! the FluxVariables property
+SET_TYPE_PROP(TwoPNC, FluxVariables, TwoPNCFluxVariables<TypeTag>);
+
+//! define the base flux variables to realize Darcy flow
+SET_TYPE_PROP(TwoPNC, BaseFluxVariables, ImplicitDarcyFluxVariables<TypeTag>);
+
+//! the upwind weight for the mass conservation equations.
+SET_SCALAR_PROP(TwoPNC, ImplicitMassUpwindWeight, 1.0);
+
+//! Set default mobility upwind weight to 1.0, i.e. fully upwind
+SET_SCALAR_PROP(TwoPNC, ImplicitMobilityUpwindWeight, 1.0);
+
+//! The indices required by the isothermal 2pnc model
+SET_TYPE_PROP(TwoPNC, Indices, TwoPNCIndices <TypeTag, /*PVOffset=*/0>);
+
+//! Use the ImplicitSpatialParams by default
+SET_TYPE_PROP(TwoPNC, SpatialParams, ImplicitSpatialParams<TypeTag>);
+
+//! Enable gravity by default
+SET_BOOL_PROP(TwoPNC, ProblemEnableGravity, true);
+
+//! Disable velocity output by default
+SET_BOOL_PROP(TwoPNC, VtkAddVelocity, false);
+
+//! Somerton is used as default model to compute the effective thermal heat conductivity
+SET_PROP(TwoPNCNI, ThermalConductivityModel)
+{
+private:
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+public:
+    typedef ThermalConductivitySomerton<Scalar, Indices> type;
+};
+
+//! temperature is already written by the isothermal model
+SET_BOOL_PROP(TwoPNCNI, NiOutputLevel, 0);
+
+//////////////////////////////////////////////////////////////////
+// Property values for isothermal model required for the general non-isothermal model
+//////////////////////////////////////////////////////////////////
+
+// set isothermal Model
+SET_TYPE_PROP(TwoPNCNI, IsothermalModel, TwoPNCModel<TypeTag>);
+
+// set isothermal FluxVariables
+SET_TYPE_PROP(TwoPNCNI, IsothermalFluxVariables, TwoPNCFluxVariables<TypeTag>);
+
+//set isothermal VolumeVariables
+SET_TYPE_PROP(TwoPNCNI, IsothermalVolumeVariables, TwoPNCVolumeVariables<TypeTag>);
+
+//set isothermal LocalResidual
+SET_TYPE_PROP(TwoPNCNI, IsothermalLocalResidual, TwoPNCLocalResidual<TypeTag>);
+
+//set isothermal Indices
+SET_TYPE_PROP(TwoPNCNI, IsothermalIndices, TwoPNCIndices<TypeTag, /*PVOffset=*/0>);
+
+//set isothermal NumEq
+SET_PROP(TwoPNCNI, IsothermalNumEq)
+{
+private:
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(FluidSystem)) FluidSystem;
+
+public:
+    static const int value = FluidSystem::numComponents;
+};
+
+
+}
+
+}
+
+#endif
diff --git a/dumux/porousmediumflow/2pnc/implicit/volumevariables.hh b/dumux/porousmediumflow/2pnc/implicit/volumevariables.hh
new file mode 100644
index 0000000000..27e1a4f229
--- /dev/null
+++ b/dumux/porousmediumflow/2pnc/implicit/volumevariables.hh
@@ -0,0 +1,529 @@
+// -*- 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/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ *
+ * \brief Contains the quantities which are constant within a
+ *        finite volume in the two-phase, n-component model.
+ */
+#ifndef DUMUX_2PNC_VOLUME_VARIABLES_HH
+#define DUMUX_2PNC_VOLUME_VARIABLES_HH
+
+#include <iostream>
+#include <vector>
+
+#include <dumux/implicit/model.hh>
+#include <dumux/material/fluidstates/compositionalfluidstate.hh>
+#include <dumux/common/math.hh>
+
+#include "properties.hh"
+#include "indices.hh"
+#include <dumux/material/constraintsolvers/computefromreferencephase2pnc.hh>
+#include <dumux/material/constraintsolvers/miscible2pnccomposition.hh>
+
+namespace Dumux
+{
+
+/*!
+ * \ingroup TwoPNCModel
+ * \ingroup ImplicitVolumeVariables
+ * \brief Contains the quantities which are are constant within a
+ *        finite volume in the two-phase, n-component model.
+ */
+template <class TypeTag>
+class TwoPNCVolumeVariables : public ImplicitVolumeVariables<TypeTag>
+{
+    typedef ImplicitVolumeVariables<TypeTag> ParentType;
+    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) Implementation;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, Grid) Grid;
+    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
+    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
+    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
+    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+    typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw;
+    typedef typename GET_PROP_TYPE(TypeTag, MaterialLawParams) MaterialLawParams;
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+    enum
+    {
+        dim = GridView::dimension,
+        dimWorld=GridView::dimensionworld,
+
+        numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
+        numComponents = GET_PROP_VALUE(TypeTag, NumComponents),
+        numMajorComponents = GET_PROP_VALUE(TypeTag, NumMajorComponents),
+
+        // formulations
+        formulation = GET_PROP_VALUE(TypeTag, Formulation),
+        plSg = TwoPNCFormulation::plSg,
+        pgSl = TwoPNCFormulation::pgSl,
+
+        // phase indices
+        wPhaseIdx = FluidSystem::wPhaseIdx,
+        nPhaseIdx = FluidSystem::nPhaseIdx,
+
+        // component indices
+        wCompIdx = FluidSystem::wCompIdx,
+        nCompIdx = FluidSystem::nCompIdx,
+
+        // phase presence enums
+        nPhaseOnly = Indices::nPhaseOnly,
+        wPhaseOnly = Indices::wPhaseOnly,
+        bothPhases = Indices::bothPhases,
+
+        // primary variable indices
+        pressureIdx = Indices::pressureIdx,
+        switchIdx = Indices::switchIdx,
+
+    };
+
+    typedef typename GridView::template Codim<0>::Entity Element;
+    typedef typename Grid::ctype CoordScalar;
+    typedef Dumux::Miscible2pNCComposition<Scalar, FluidSystem> Miscible2pNCComposition;
+    typedef Dumux::ComputeFromReferencePhase2pNC<Scalar, FluidSystem> ComputeFromReferencePhase2pNC;
+
+    enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) };
+    enum { dofCodim = isBox ? dim : 0 };
+public:
+
+    typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState;
+
+    /*!
+     * \copydoc ImplicitVolumeVariables::update
+     * \param primaryVariables The primary Variables
+     */
+    void update(const PrimaryVariables &primaryVariables,
+                const Problem &problem,
+                const Element &element,
+                const FVElementGeometry &fvGeometry,
+                int scvIdx,
+                bool isOldSol)
+    {
+        ParentType::update(primaryVariables,
+                           problem,
+                           element,
+                           fvGeometry,
+                           scvIdx,
+                           isOldSol);
+
+        completeFluidState(primaryVariables, problem, element, fvGeometry, scvIdx, fluidState_, isOldSol);
+
+        /////////////
+        // calculate the remaining quantities
+        /////////////
+        const MaterialLawParams &materialParams = problem.spatialParams().materialLawParams(element, fvGeometry, scvIdx);
+
+    // Second instance of a parameter cache.
+        // Could be avoided if diffusion coefficients also
+        // became part of the fluid state.
+        typename FluidSystem::ParameterCache paramCache;
+        paramCache.updateAll(fluidState_);
+        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
+            {// relative permeabilities
+                    Scalar kr;
+                    if (phaseIdx == wPhaseIdx)
+                        kr = MaterialLaw::krw(materialParams, saturation(wPhaseIdx));
+                    else // ATTENTION: krn requires the liquid saturation
+                        // as parameter!
+                        kr = MaterialLaw::krn(materialParams, saturation(wPhaseIdx));
+                        mobility_[phaseIdx] = kr / fluidState_.viscosity(phaseIdx);
+                        Valgrind::CheckDefined(mobility_[phaseIdx]);
+                    int compIIdx = phaseIdx;
+                    for(int compIdx = 0; compIdx < numComponents; ++compIdx)
+                    {
+                    int compJIdx = compIdx;
+                    // binary diffusion coefficents
+                    diffCoeff_[phaseIdx][compIdx] = 0.0;
+                    if(compIIdx!= compJIdx)
+                    diffCoeff_[phaseIdx][compIdx] = FluidSystem::binaryDiffusionCoefficient(fluidState_,
+                                                                                    paramCache,
+                                                                                    phaseIdx,
+                                                                                    compIIdx,
+                                                                                    compJIdx);
+                    Valgrind::CheckDefined(diffCoeff_[phaseIdx][compIdx]);
+                }
+            }
+
+    // porosity
+    porosity_ = problem.spatialParams().porosity(element,
+                                                        fvGeometry,
+                                                        scvIdx);
+    Valgrind::CheckDefined(porosity_);
+    // energy related quantities not contained in the fluid state
+
+    asImp_().updateEnergy_(primaryVariables, problem,element, fvGeometry, scvIdx, isOldSol);
+    }
+
+   /*!
+    * \copydoc ImplicitModel::completeFluidState
+    * \param isOldSol Specifies whether this is the previous solution or the current one
+    * \param primaryVariables The primary Variables
+    */
+    static void completeFluidState(const PrimaryVariables& primaryVariables,
+                    const Problem& problem,
+                    const Element& element,
+                    const FVElementGeometry& fvGeometry,
+                    int scvIdx,
+                    FluidState& fluidState,
+                    bool isOldSol = false)
+
+    {
+        Scalar t = Implementation::temperature_(primaryVariables, problem, element,
+                                                fvGeometry, scvIdx);
+        fluidState.setTemperature(t);
+
+        int dofIdxGlobal = problem.model().dofMapper().subIndex(element, scvIdx, dofCodim);
+        int phasePresence = problem.model().phasePresence(dofIdxGlobal, isOldSol);
+
+        /////////////
+        // set the saturations
+        /////////////
+
+    Scalar Sg;
+        if (phasePresence == nPhaseOnly)
+            Sg = 1.0;
+        else if (phasePresence == wPhaseOnly) {
+            Sg = 0.0;
+        }
+        else if (phasePresence == bothPhases) {
+            if (formulation == plSg)
+                Sg = primaryVariables[switchIdx];
+            else if (formulation == pgSl)
+                Sg = 1.0 - primaryVariables[switchIdx];
+            else DUNE_THROW(Dune::InvalidStateException, "Formulation: " << formulation << " is invalid.");
+        }
+    else DUNE_THROW(Dune::InvalidStateException, "phasePresence: " << phasePresence << " is invalid.");
+        fluidState.setSaturation(nPhaseIdx, Sg);
+        fluidState.setSaturation(wPhaseIdx, 1.0 - Sg);
+
+        /////////////
+        // set the pressures of the fluid phases
+        /////////////
+
+        // calculate capillary pressure
+        const MaterialLawParams &materialParams
+        = problem.spatialParams().materialLawParams(element, fvGeometry, scvIdx);
+        Scalar pc = MaterialLaw::pc(materialParams, 1 - Sg);
+
+        // extract the pressures
+        if (formulation == plSg) {
+            fluidState.setPressure(wPhaseIdx, primaryVariables[pressureIdx]);
+            if (primaryVariables[pressureIdx] + pc < 0.0)
+                 DUNE_THROW(Dumux::NumericalProblem,"Capillary pressure is too low");
+            fluidState.setPressure(nPhaseIdx, primaryVariables[pressureIdx] + pc);
+        }
+        else if (formulation == pgSl) {
+            fluidState.setPressure(nPhaseIdx, primaryVariables[pressureIdx]);
+            // Here we check for (p_g - pc) in order to ensure that (p_l > 0)
+            if (primaryVariables[pressureIdx] - pc < 0.0)
+            {
+                std::cout<< "p_g: "<< primaryVariables[pressureIdx]<<" Cap_press: "<< pc << std::endl;
+                DUNE_THROW(Dumux::NumericalProblem,"Capillary pressure is too high");
+            }
+            fluidState.setPressure(wPhaseIdx, primaryVariables[pressureIdx] - pc);
+        }
+        else DUNE_THROW(Dune::InvalidStateException, "Formulation: " << formulation << " is invalid.");
+
+        /////////////
+        // calculate the phase compositions
+        /////////////
+
+    typename FluidSystem::ParameterCache paramCache;
+
+        // now comes the tricky part: calculate phase composition
+        if (phasePresence == bothPhases) {
+            // both phases are present, phase composition results from
+            // the gas <-> liquid equilibrium. This is
+            // the job of the "MiscibleMultiPhaseComposition"
+            // constraint solver
+
+            // set the known mole fractions in the fluidState so that they
+            // can be used by the Miscible2pNCComposition constraint solver
+            for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx)
+            {
+                fluidState.setMoleFraction(wPhaseIdx, compIdx, primaryVariables[compIdx]);
+            }
+
+            Miscible2pNCComposition::solve(fluidState,
+                        paramCache,
+                        wPhaseIdx,  //known phaseIdx
+                        /*setViscosity=*/true,
+                        /*setInternalEnergy=*/false);
+        }
+        else if (phasePresence == nPhaseOnly){
+
+            Dune::FieldVector<Scalar, numComponents> moleFrac;
+
+
+            moleFrac[wCompIdx] =  primaryVariables[switchIdx];
+
+            for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx)
+                    moleFrac[compIdx] = primaryVariables[compIdx];
+
+
+            Scalar sumMoleFracNotGas = 0;
+            for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx)
+                    sumMoleFracNotGas+=moleFrac[compIdx];
+
+            sumMoleFracNotGas += moleFrac[wCompIdx];
+            moleFrac[nCompIdx] = 1 - sumMoleFracNotGas;
+
+
+            // Set fluid state mole fractions
+            for (int compIdx=0; compIdx<numComponents; ++compIdx)
+                    fluidState.setMoleFraction(nPhaseIdx, compIdx, moleFrac[compIdx]);
+
+
+            // calculate the composition of the remaining phases (as
+            // well as the densities of all phases). this is the job
+            // of the "ComputeFromReferencePhase2pNC" constraint solver
+                ComputeFromReferencePhase2pNC::solve(fluidState,
+                                                paramCache,
+                                                nPhaseIdx,
+                                                /*setViscosity=*/true,
+                                                /*setInternalEnergy=*/false);
+
+            }
+        else if (phasePresence == wPhaseOnly){
+        // only the liquid phase is present, i.e. liquid phase
+        // composition is stored explicitly.
+        // extract _mass_ fractions in the gas phase
+            Dune::FieldVector<Scalar, numComponents> moleFrac;
+
+            for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx)
+            {
+                moleFrac[compIdx] = primaryVariables[compIdx];
+            }
+            moleFrac[nCompIdx] = primaryVariables[switchIdx];
+            Scalar sumMoleFracNotWater = 0;
+            for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx)
+            {
+                    sumMoleFracNotWater+=moleFrac[compIdx];
+            }
+            sumMoleFracNotWater += moleFrac[nCompIdx];
+            moleFrac[wCompIdx] = 1 -sumMoleFracNotWater;
+
+
+            // convert mass to mole fractions and set the fluid state
+            for (int compIdx=0; compIdx<numComponents; ++compIdx)
+            {
+                fluidState.setMoleFraction(wPhaseIdx, compIdx, moleFrac[compIdx]);
+            }
+
+            // calculate the composition of the remaining phases (as
+            // well as the densities of all phases). this is the job
+            // of the "ComputeFromReferencePhase2pNC" constraint solver
+            ComputeFromReferencePhase2pNC::solve(fluidState,
+                                                paramCache,
+                                                wPhaseIdx,
+                                                /*setViscosity=*/true,
+                                                /*setInternalEnergy=*/false);
+        }
+        paramCache.updateAll(fluidState);
+        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
+        {
+            Scalar rho = FluidSystem::density(fluidState, paramCache, phaseIdx);
+            Scalar mu = FluidSystem::viscosity(fluidState, paramCache, phaseIdx);
+
+            fluidState.setDensity(phaseIdx, rho);
+            fluidState.setViscosity(phaseIdx, mu);
+        }
+    }
+
+    /*!
+     * \brief Returns the phase state for the control-volume.
+     */
+    const FluidState &fluidState() const
+    { return fluidState_; }
+
+    /*!
+     * \brief Returns the saturation of a given phase within
+     *        the control volume in \f$[-]\f$.
+     *
+     * \param phaseIdx The phase index
+     */
+    Scalar saturation(int phaseIdx) const
+    { return fluidState_.saturation(phaseIdx); }
+
+    /*!
+     * \brief Returns the mass density of a given phase within the
+     *        control volume.
+     *
+     * \param phaseIdx The phase index
+     */
+    Scalar density(int phaseIdx) const
+    {
+        if (phaseIdx < numPhases)
+            return fluidState_.density(phaseIdx);
+
+        else
+            DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx);
+    }
+
+    /*!
+     * \brief Returns the mass density of a given phase within the
+     *        control volume.
+     *
+     * \param phaseIdx The phase index
+     */
+    Scalar molarDensity(int phaseIdx) const
+    {
+        if (phaseIdx < numPhases)
+            return fluidState_.molarDensity(phaseIdx);
+
+        else
+            DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx);
+    }
+
+    /*!
+     * \brief Returns the effective pressure of a given phase within
+     *        the control volume.
+     *
+     * \param phaseIdx The phase index
+     */
+    Scalar pressure(int phaseIdx) const
+    {
+        return fluidState_.pressure(phaseIdx);
+    }
+
+    /*!
+     * \brief Returns temperature inside the sub-control volume.
+     *
+     * Note that we assume thermodynamic equilibrium, i.e. the
+     * temperature of the rock matrix and of all fluid phases are
+     * identical.
+     */
+    Scalar temperature() const
+    { return fluidState_.temperature(/*phaseIdx=*/0); }
+
+    /*!
+     * \brief Returns the effective mobility of a given phase within
+     *        the control volume.
+     *
+     * \param phaseIdx The phase index
+     */
+    Scalar mobility(int phaseIdx) const
+    {
+        return mobility_[phaseIdx];
+    }
+
+    /*!
+     * \brief Returns the effective capillary pressure within the control volume
+     *        in \f$[kg/(m*s^2)=N/m^2=Pa]\f$.
+     */
+    Scalar capillaryPressure() const
+    { return fluidState_.pressure(FluidSystem::nPhaseIdx) - fluidState_.pressure(FluidSystem::wPhaseIdx); }
+
+    /*!
+     * \brief Returns the average porosity within the control volume.
+     */
+    Scalar porosity() const
+    { return porosity_; }
+
+
+    /*!
+     * \brief Returns the binary diffusion coefficients for a phase in \f$[m^2/s]\f$.
+     */
+    Scalar diffCoeff(int phaseIdx, int compIdx) const
+    { return diffCoeff_[phaseIdx][compIdx]; }
+
+    /*!
+     * \brief Returns the molarity of a component in the phase
+     *
+     * \param phaseIdx the index of the fluid phase
+     * \param compIdx the index of the component
+     */
+     Scalar molarity(int phaseIdx, int compIdx) const // [moles/m^3]
+    { return this->fluidState_.molarity(phaseIdx, compIdx);}
+
+     /*!
+      * \brief Returns the mass fraction of a component in the phase
+      *
+      * \param phaseIdx the index of the fluid phase
+      * \param compIdx the index of the component
+      */
+     Scalar massFraction(int phaseIdx, int compIdx) const
+     {
+        return this->fluidState_.massFraction(phaseIdx, compIdx);
+     }
+
+     /*!
+      * \brief Returns the mole fraction of a component in the phase
+      *
+      * \param phaseIdx the index of the fluid phase
+      * \param compIdx the index of the component
+      */
+     Scalar moleFraction(int phaseIdx, int compIdx) const
+     {
+        return this->fluidState_.moleFraction(phaseIdx, compIdx);
+     }
+
+protected:
+
+    static Scalar temperature_(const PrimaryVariables &priVars,
+                               const Problem& problem,
+                               const Element &element,
+                               const FVElementGeometry &fvGeometry,
+                               int scvIdx)
+    {
+        return problem.temperatureAtPos(fvGeometry.subContVol[scvIdx].global);
+    }
+
+    template<class ParameterCache>
+    static Scalar enthalpy_(const FluidState& fluidState,
+                            const ParameterCache& paramCache,
+                            int phaseIdx)
+    {
+        return 0;
+    }
+
+    /*!
+        * \brief Called by update() to compute the energy related quantities
+        */
+    void updateEnergy_(const PrimaryVariables &priVars,
+                        const Problem &problem,
+                        const Element &element,
+                        const FVElementGeometry &fvGeometry,
+                        const int scvIdx,
+                        bool isOldSol)
+    { };
+
+    Scalar porosity_;        //!< Effective porosity within the control volume
+    Scalar mobility_[numPhases];  //!< Effective mobility within the control volume
+    Scalar density_;
+    FluidState fluidState_;
+    Scalar theta_;
+    Scalar InitialPorosity_;
+    Scalar molWtPhase_[numPhases];
+    Dune::FieldMatrix<Scalar, numPhases, numComponents> diffCoeff_;
+
+private:
+    Implementation &asImp_()
+    { return *static_cast<Implementation*>(this); }
+
+    const Implementation &asImp_() const
+    { return *static_cast<const Implementation*>(this); }
+
+};
+
+} // end namespace
+
+#endif
diff --git a/dumux/porousmediumflow/2pncmin/implicit/fluxvariables.hh b/dumux/porousmediumflow/2pncmin/implicit/fluxvariables.hh
new file mode 100644
index 0000000000..8a87062691
--- /dev/null
+++ b/dumux/porousmediumflow/2pncmin/implicit/fluxvariables.hh
@@ -0,0 +1,162 @@
+// -**- 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/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ * \brief Contains the data which is required to calculate
+ *        all fluxes of components over a face of a finite volume for
+ *        the two-phase two-component mineralization model fully implicit model.
+ */
+#ifndef DUMUX_2PNCMIN_FLUX_VARIABLES_HH
+#define DUMUX_2PNCMIN_FLUX_VARIABLES_HH
+
+#include <dumux/common/math.hh>
+#include <dumux/common/spline.hh>
+#include <dumux/porousmediumflow/2pnc/implicit/fluxvariables.hh>
+#include "properties.hh"
+
+namespace Dumux
+{
+
+/*!
+ * \ingroup TwoPNCMinModel
+ * \ingroup ImplicitFluxVariables
+ * \brief Contains the data which is required to calculate
+ *        all fluxes of components over a face of a finite volume for
+ *        the two-phase n-component mineralization fully implicit model.
+ *
+ * This means pressure and concentration gradients, phase densities at
+ * the integration point, etc.
+ */
+
+template <class TypeTag>
+class TwoPNCMinFluxVariables : public TwoPNCFluxVariables<TypeTag>
+{
+    typedef TwoPNCFluxVariables<TypeTag> ParentType;
+    typedef TwoPNCMinFluxVariables<TypeTag> ThisType;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
+    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
+
+    typedef typename GridView::ctype CoordScalar;
+    typedef typename GridView::template Codim<0>::Entity Element;
+    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
+
+    enum {
+        dim = GridView::dimension,
+        dimWorld = GridView::dimensionworld,
+        numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
+        numComponents = GET_PROP_VALUE(TypeTag, NumComponents),
+    };
+
+    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
+    typedef typename GET_PROP_TYPE(TypeTag, SpatialParams) SpatialParams;
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+    typedef typename FVElementGeometry::SubControlVolume SCV;
+    typedef typename FVElementGeometry::SubControlVolumeFace SCVFace;
+
+    typedef Dune::FieldVector<CoordScalar, dimWorld> DimVector;
+    typedef Dune::FieldMatrix<CoordScalar, dim, dim> DimMatrix;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+    enum {
+        wPhaseIdx = FluidSystem::wPhaseIdx,
+        nPhaseIdx = FluidSystem::nPhaseIdx,
+        wCompIdx  = FluidSystem::wCompIdx,
+    };
+
+public:
+    /*!
+     * \brief The constructor
+     *
+     * \param problem The problem
+     * \param element The finite element
+     * \param fvGeometry The finite-volume geometry in the fully implicit scheme
+     * \param fIdx The local index of the sub-control-volume face
+     * \param elemVolVars The volume variables of the current element
+     * \param onBoundary Evaluate flux at inner sub-control-volume face or on a boundary face
+     */
+    TwoPNCMinFluxVariables(const Problem &problem,
+                     const Element &element,
+                     const FVElementGeometry &fvGeometry,
+                     const int fIdx,
+                     const ElementVolumeVariables &elemVolVars,
+                     const bool onBoundary = false)
+    : ParentType(problem, element, fvGeometry, fIdx, elemVolVars, onBoundary)
+    {
+        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
+            this->density_[phaseIdx] = Scalar(0);
+            this->molarDensity_[phaseIdx] = Scalar(0);
+            this->potentialGrad_[phaseIdx] = Scalar(0);
+            for (int compIdx = 0; compIdx < numComponents; ++compIdx)
+            {
+                this->massFractionGrad_[phaseIdx][compIdx] = Scalar(0);
+                this->moleFractionGrad_[phaseIdx][compIdx] = Scalar(0);
+            }
+        }
+        this->calculateGradients_(problem, element, elemVolVars);
+        this->calculateVelocities_(problem, element, elemVolVars);
+        this->calculateporousDiffCoeff_(problem, element, elemVolVars);
+    };
+
+protected:
+    void calculateVelocities_(const Problem &problem,
+                              const Element &element,
+                              const ElementVolumeVariables &elemVolVars)
+    {
+        const SpatialParams &spatialParams = problem.spatialParams();
+        // multiply the pressure potential with the intrinsic permeability
+        DimMatrix K(0.0);
+
+        for (int phaseIdx=0; phaseIdx < numPhases; phaseIdx++)
+        {
+            const VolumeVariables &volVarsI = elemVolVars[this->face().i];
+            const VolumeVariables &volVarsJ = elemVolVars[this->face().j];
+
+            auto K_i = spatialParams.intrinsicPermeability(element,this->fvGeometry_,this->face().i);
+            K_i *= volVarsI.permeabilityFactor();
+
+            auto K_j = spatialParams.intrinsicPermeability(element,this->fvGeometry_,this->face().j);
+            K_j *= volVarsJ.permeabilityFactor();
+
+            spatialParams.meanK(K,K_i,K_j);
+
+            K.mv(this->potentialGrad_[phaseIdx], this->Kmvp_[phaseIdx]);
+            this->KmvpNormal_[phaseIdx] = - (this->Kmvp_[phaseIdx] * this->face().normal);
+        }
+
+        // set the upstream and downstream vertices
+        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
+        {
+            this->upstreamIdx_[phaseIdx] = this->face().i;
+            this->downstreamIdx_[phaseIdx] = this->face().j;
+
+            if (this->KmvpNormal_[phaseIdx] < 0) {
+                std::swap(this->upstreamIdx_[phaseIdx],
+                          this->downstreamIdx_[phaseIdx]);
+            }
+        }
+    }
+};
+
+} // end namespace
+
+#endif
diff --git a/dumux/porousmediumflow/2pncmin/implicit/indices.hh b/dumux/porousmediumflow/2pncmin/implicit/indices.hh
new file mode 100644
index 0000000000..eac1763171
--- /dev/null
+++ b/dumux/porousmediumflow/2pncmin/implicit/indices.hh
@@ -0,0 +1,48 @@
+// -*- 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/>.   *
+ *****************************************************************************/
+
+/*!
+ * \file
+ * \brief Defines the indices required for the two-phase n-component mineralization
+ *        fully implicit model.
+ */
+#ifndef DUMUX_2PNCMIN_INDICES_HH
+#define DUMUX_2PNCMIN_INDICES_HH
+
+#include <dumux/porousmediumflow/2pnc/implicit/indices.hh>
+
+namespace Dumux
+{
+/*!
+ * \ingroup TwoPNCMinModel
+ * \ingroup ImplicitIndices
+ * \brief The indices for the isothermal two-phase n-component mineralization model.
+ *
+ * \tparam PVOffset The first index in a primary variable vector.
+ */
+template <class TypeTag, int PVOffset = 0>
+    class TwoPNCMinIndices: public TwoPNCIndices<TypeTag, PVOffset>
+{
+};
+
+// \}
+
+}
+
+#endif
diff --git a/dumux/porousmediumflow/2pncmin/implicit/localresidual.hh b/dumux/porousmediumflow/2pncmin/implicit/localresidual.hh
new file mode 100644
index 0000000000..638ef7d391
--- /dev/null
+++ b/dumux/porousmediumflow/2pncmin/implicit/localresidual.hh
@@ -0,0 +1,140 @@
+// -*- 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/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ *
+ * \brief Element-wise calculation of the Jacobian matrix for problems
+ *        using the two-phase n-component mineralisation box model.
+ */
+
+#ifndef DUMUX_2PNCMIN_LOCAL_RESIDUAL_BASE_HH
+#define DUMUX_2PNCMIN_LOCAL_RESIDUAL_BASE_HH
+
+#include "properties.hh"
+#include <dumux/porousmediumflow/2pnc/implicit/localresidual.hh>
+
+namespace Dumux
+{
+/*!
+ * \ingroup TwoPNCMinModel
+ * \ingroup ImplicitLocalResidual
+ * \brief Element-wise calculation of the Jacobian matrix for problems
+ *        using the two-phase n-component mineralization fully implicit box model.
+ *
+ * This class is used to fill the gaps in ImplicitLocalResidual for the two-phase n-component flow.
+ */
+template<class TypeTag>
+class TwoPNCMinLocalResidual: public TwoPNCLocalResidual<TypeTag>
+{
+protected:
+    typedef TwoPNCLocalResidual<TypeTag> ParentType;
+    typedef TwoPNCMinLocalResidual<TypeTag> ThisType;
+    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+    typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector;
+    typedef typename GET_PROP_TYPE(TypeTag, ElementSolutionVector) ElementSolutionVector;
+    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, BoundaryTypes) BoundaryTypes;
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+    typedef typename GET_PROP_TYPE(TypeTag, LocalResidual) Implementation;
+
+
+    enum
+    {
+        numEq = GET_PROP_VALUE(TypeTag, NumEq),
+        numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
+        numSPhases = GET_PROP_VALUE(TypeTag, NumSPhases),
+        numComponents = GET_PROP_VALUE(TypeTag, NumComponents),
+
+        replaceCompEqIdx = GET_PROP_VALUE(TypeTag, ReplaceCompEqIdx),
+
+        pressureIdx = Indices::pressureIdx,
+        switchIdx = Indices::switchIdx,
+
+        wPhaseIdx = FluidSystem::wPhaseIdx,
+        nPhaseIdx = FluidSystem::nPhaseIdx,
+
+        wCompIdx = FluidSystem::wCompIdx,
+        nCompIdx = FluidSystem::nCompIdx,
+
+        conti0EqIdx = Indices::conti0EqIdx,
+
+        wPhaseOnly = Indices::wPhaseOnly,
+        nPhaseOnly = Indices::nPhaseOnly,
+        bothPhases = Indices::bothPhases,
+
+        plSg = TwoPNCFormulation::plSg,
+        pgSl = TwoPNCFormulation::pgSl,
+        formulation = GET_PROP_VALUE(TypeTag, Formulation)
+    };
+
+    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, ElementBoundaryTypes) ElementBoundaryTypes;
+    typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, SpatialParams) SpatialParams;
+    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
+
+public:
+    /*!
+     * \brief Constructor. Sets the upwind weight.
+     */
+    TwoPNCMinLocalResidual()
+    {
+        // retrieve the upwind weight for the mass conservation equations. Use the value
+        // specified via the property system as default, and overwrite
+        // it by the run-time parameter from the Dune::ParameterTree
+        this->massUpwindWeight_ = GET_PARAM_FROM_GROUP(TypeTag, Scalar, Implicit, MassUpwindWeight);
+    };
+
+    /*!
+     * \brief Evaluate the amount all conservation quantities
+     *        (e.g. phase mass) within a sub-control volume.
+     *
+     * The result should be averaged over the volume (e.g. phase mass
+     * inside a sub control volume divided by the volume).
+     * In contrast to the 2pnc model, here, the storage of solid phases is included too.
+     *
+     *  \param storage the mass of the component within the sub-control volume
+     *  \param scvIdx The SCV (sub-control-volume) index
+     *  \param usePrevSol Evaluate function with solution of current or previous time step
+     */
+  void computeStorage(PrimaryVariables &storage, int scvIdx, bool usePrevSol) const
+  {
+      //call parenttype function
+      ParentType::computeStorage(storage, scvIdx, usePrevSol);
+
+      const ElementVolumeVariables &elemVolVars = usePrevSol ? this->prevVolVars_()
+      : this->curVolVars_();
+    const VolumeVariables &volVars = elemVolVars[scvIdx];
+
+    // Compute storage term of all solid (precipitated) phases (excluding the non-reactive matrix)
+    for (int phaseIdx = numPhases; phaseIdx < numPhases + numSPhases; ++phaseIdx)
+    {
+      int eqIdx = conti0EqIdx + numComponents-numPhases + phaseIdx;
+      storage[eqIdx] += volVars.precipitateVolumeFraction(phaseIdx)*volVars.molarDensity(phaseIdx);
+    }
+
+      Valgrind::CheckDefined(storage);
+  }
+};
+} // end namespace
+
+#endif
diff --git a/dumux/porousmediumflow/2pncmin/implicit/model.hh b/dumux/porousmediumflow/2pncmin/implicit/model.hh
new file mode 100644
index 0000000000..9649493ab9
--- /dev/null
+++ b/dumux/porousmediumflow/2pncmin/implicit/model.hh
@@ -0,0 +1,551 @@
+// -*- 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/>.   *
+ *****************************************************************************/
+/*!
+* \file
+*
+* \brief Adaption of the fully implicit box scheme to the two-phase n-component flow model.
+*/
+
+#ifndef DUMUX_2PNCMIN_MODEL_HH
+#define DUMUX_2PNCMIN_MODEL_HH
+
+#include "properties.hh"
+#include "indices.hh"
+
+#include <dumux/material/constants.hh>
+#include <dumux/porousmediumflow/2pnc/implicit/model.hh>
+#include "localresidual.hh"
+#include <dumux/porousmediumflow/implicit/velocityoutput.hh>
+
+namespace Dumux
+{
+/*!
+ * \ingroup TwoPNCMinModel
+ * \brief Adaption of the fully implicit scheme to the
+ *        two-phase n-component fully implicit model.
+ *
+ * This model implements two-phase n-component flow of two compressible and
+ * partially miscible fluids \f$\alpha \in \{ w, n \}\f$ composed of the n components
+ * \f$\kappa \in \{ w, a,\cdots \}\f$. The standard multiphase Darcy
+ * approach is used as the equation for the conservation of momentum:
+ * \f[
+ v_\alpha = - \frac{k_{r\alpha}}{\mu_\alpha} \mbox{\bf K}
+ \left(\text{grad}\, p_\alpha - \varrho_{\alpha} \mbox{\bf g} \right)
+ * \f]
+ *
+ * By inserting this into the equations for the conservation of the
+ * components, one gets one transport equation for each component
+ * \f{eqnarray}
+ && \phi \frac{\partial (\sum_\alpha \varrho_\alpha X_\alpha^\kappa S_\alpha )}
+ {\partial t}
+ - \sum_\alpha  \text{div} \left\{ \varrho_\alpha X_\alpha^\kappa
+ \frac{k_{r\alpha}}{\mu_\alpha} \mbox{\bf K}
+ (\text{grad}\, p_\alpha - \varrho_{\alpha}  \mbox{\bf g}) \right\}
+ \nonumber \\ \nonumber \\
+    &-& \sum_\alpha \text{div} \left\{{\bf D_{\alpha, pm}^\kappa} \varrho_{\alpha} \text{grad}\, X^\kappa_{\alpha} \right\}
+ - \sum_\alpha q_\alpha^\kappa = 0 \qquad \kappa \in \{w, a,\cdots \} \, ,
+ \alpha \in \{w, g\}
+ \f}
+ *
+ * All equations are discretized using a vertex-centered finite volume (box)
+ * or cell-centered finite volume scheme (this is not done for 2pnc approach yet, however possible) as
+ * spatial and the implicit Euler method as time discretization.
+ *
+ * By using constitutive relations for the capillary pressure \f$p_c =
+ * p_n - p_w\f$ and relative permeability \f$k_{r\alpha}\f$ and taking
+ * advantage of the fact that \f$S_w + S_n = 1\f$ and \f$X^\kappa_w + X^\kappa_n = 1\f$, the number of
+ * unknowns can be reduced to number of components.
+ *
+ * The used primary variables are, like in the two-phase model, either \f$p_w\f$ and \f$S_n\f$
+ * or \f$p_n\f$ and \f$S_w\f$. The formulation which ought to be used can be
+ * specified by setting the <tt>Formulation</tt> property to either
+ * TwoPTwoCIndices::pWsN or TwoPTwoCIndices::pNsW. By
+ * default, the model uses \f$p_w\f$ and \f$S_n\f$.
+ *
+ * Moreover, the second primary variable depends on the phase state, since a
+ * primary variable switch is included. The phase state is stored for all nodes
+ * of the system. The model is uses mole fractions.
+ *Following cases can be distinguished:
+ * <ul>
+ *  <li> Both phases are present: The saturation is used (either \f$S_n\f$ or \f$S_w\f$, dependent on the chosen <tt>Formulation</tt>),
+ *      as long as \f$ 0 < S_\alpha < 1\f$</li>.
+ *  <li> Only wetting phase is present: The mass fraction of, e.g., air in the wetting phase \f$X^a_w\f$ is used,
+ *      as long as the maximum mass fraction is not exceeded (\f$X^a_w<X^a_{w,max}\f$)</li>
+ *  <li> Only non-wetting phase is present: The mass fraction of, e.g., water in the non-wetting phase, \f$X^w_n\f$, is used,
+ *      as long as the maximum mass fraction is not exceeded (\f$X^w_n<X^w_{n,max}\f$)</li>
+ * </ul>
+ */
+
+template<class TypeTag>
+class TwoPNCMinModel: public TwoPNCModel<TypeTag>
+{
+    typedef TwoPNCMinModel<TypeTag> ThisType;
+    typedef TwoPNCModel<TypeTag> ParentType;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
+
+    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
+    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, ElementBoundaryTypes) ElementBoundaryTypes;
+    typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, VertexMapper) VertexMapper;
+    typedef typename GET_PROP_TYPE(TypeTag, ElementMapper) ElementMapper;
+    typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector;
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+    typedef Dumux::Constants<Scalar> Constant;
+
+    enum {
+        dim = GridView::dimension,
+        dimWorld = GridView::dimensionworld,
+
+        numEq = GET_PROP_VALUE(TypeTag, NumEq),
+        numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
+        numSPhases = GET_PROP_VALUE(TypeTag, NumSPhases),
+        numComponents = GET_PROP_VALUE(TypeTag, NumComponents),
+        numSecComponents = GET_PROP_VALUE(TypeTag, NumSecComponents),
+        numMajorComponents = GET_PROP_VALUE(TypeTag, NumMajorComponents),
+
+        pressureIdx = Indices::pressureIdx,
+        switchIdx = Indices::switchIdx,
+
+        wPhaseIdx = Indices::wPhaseIdx,
+        nPhaseIdx = Indices::nPhaseIdx,
+
+        wCompIdx = FluidSystem::wCompIdx,
+        nCompIdx = FluidSystem::nCompIdx,
+
+        wPhaseOnly = Indices::wPhaseOnly,
+        nPhaseOnly = Indices::nPhaseOnly,
+        bothPhases = Indices::bothPhases,
+
+        plSg = TwoPNCFormulation::plSg,
+        pgSl = TwoPNCFormulation::pgSl,
+        formulation = GET_PROP_VALUE(TypeTag, Formulation)
+    };
+
+    typedef typename GridView::template Codim<dim>::Entity Vertex;
+    typedef typename GridView::template Codim<0>::Entity Element;
+
+    typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition;
+    typedef typename GridView::ctype CoordScalar;
+    typedef Dune::FieldMatrix<CoordScalar, dimWorld, dimWorld> Tensor;
+    typedef Dune::FieldVector<Scalar, numPhases> PhasesVector;
+
+    enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) };
+    enum { dofCodim = isBox ? dim : 0 };
+
+public:
+
+    /*!
+     * \brief Append all quantities of interest which can be derived
+     *        from the solution of the current time step to the VTK
+     *        writer.
+     *
+     * \param sol The solution vector
+     * \param writer The writer for multi-file VTK datasets
+     */
+    template<class MultiWriter>
+    //additional output of the permeability and the precipitate volume fractions
+    void addOutputVtkFields(const SolutionVector &sol,
+                            MultiWriter &writer)
+    {
+        typedef Dune::BlockVector<Dune::FieldVector<Scalar, 1> > ScalarField;
+        typedef Dune::BlockVector<Dune::FieldVector<double, dim> > VectorField;
+
+        // get the number of degrees of freedom
+        unsigned numDofs = this->numDofs();
+
+        // create the required scalar fields
+        ScalarField *Sg           = writer.allocateManagedBuffer (numDofs);
+        ScalarField *Sl        = writer.allocateManagedBuffer (numDofs);
+        ScalarField *pg           = writer.allocateManagedBuffer (numDofs);
+        ScalarField *pl           = writer.allocateManagedBuffer (numDofs);
+        ScalarField *pc        = writer.allocateManagedBuffer (numDofs);
+        ScalarField *rhoL       = writer.allocateManagedBuffer (numDofs);
+        ScalarField *rhoG       = writer.allocateManagedBuffer (numDofs);
+        ScalarField *mobL       = writer.allocateManagedBuffer (numDofs);
+        ScalarField *mobG        = writer.allocateManagedBuffer (numDofs);
+        ScalarField *phasePresence = writer.allocateManagedBuffer (numDofs);
+        ScalarField *temperature   = writer.allocateManagedBuffer (numDofs);
+        ScalarField *poro          = writer.allocateManagedBuffer (numDofs);
+        ScalarField *boxVolume     = writer.allocateManagedBuffer (numDofs);
+        ScalarField *cellNum        = writer.allocateManagedBuffer (numDofs);
+        ScalarField *permeabilityFactor    = writer.allocateManagedBuffer (numDofs);
+        ScalarField *precipitateVolumeFraction[numSPhases] ;
+
+        for (int i = 0; i < numSPhases; ++i)
+        {
+            precipitateVolumeFraction[i]= writer.allocateManagedBuffer (numDofs);
+        }
+
+        ScalarField *massFraction[numPhases][numComponents];
+        for (int i = 0; i < numPhases; ++i)
+            for (int j = 0; j < numComponents; ++j)
+                massFraction[i][j] = writer.allocateManagedBuffer(numDofs);
+
+        ScalarField *molarity[numComponents];
+        for (int j = 0; j < numComponents ; ++j)
+            molarity[j] = writer.allocateManagedBuffer(numDofs);
+
+        ScalarField *Perm[dim];
+        for (int j = 0; j < dim; ++j) //Permeability only in main directions xx and yy
+            Perm[j] = writer.allocateManagedBuffer(numDofs);
+
+        *boxVolume = 0;
+
+        VectorField *velocityN = writer.template allocateManagedBuffer<double, dim>(numDofs);
+        VectorField *velocityW = writer.template allocateManagedBuffer<double, dim>(numDofs);
+        ImplicitVelocityOutput<TypeTag> velocityOutput(this->problem_());
+
+        if (velocityOutput.enableOutput()) // check if velocity output is demanded
+        {
+            // initialize velocity fields
+            for (unsigned int i = 0; i < numDofs; ++i)
+            {
+                (*velocityN)[i] = Scalar(0);
+                (*velocityW)[i] = Scalar(0);
+                (*cellNum)[i] = Scalar(0.0);
+            }
+        }
+
+        unsigned numElements = this->gridView_().size(0);
+        ScalarField *rank =
+                writer.allocateManagedBuffer (numElements);
+
+        FVElementGeometry fvGeometry;
+        VolumeVariables volVars;
+        ElementVolumeVariables elemVolVars;
+
+        for (const auto& element : Dune::elements(this->gridView_()))
+        {
+            int idx = this->problem_().elementMapper().index(element);
+            (*rank)[idx] = this->gridView_().comm().rank();
+            fvGeometry.update(this->gridView_(), element);
+
+            elemVolVars.update(this->problem_(),
+                    element,
+                    fvGeometry,
+                    false /* oldSol? */);
+
+            int numVerts = element.subEntities(dim);
+
+            for (int i = 0; i < numVerts; ++i)
+            {
+                int globalIdx = this->vertexMapper().subIndex(element, i, dim);
+                volVars.update(sol[globalIdx],
+                               this->problem_(),
+                               element,
+                               fvGeometry,
+                               i,
+                               false);
+
+                (*Sg)[globalIdx]              = volVars.saturation(nPhaseIdx);
+                (*Sl)[globalIdx]              = volVars.saturation(wPhaseIdx);
+                (*pg)[globalIdx]                = volVars.pressure(nPhaseIdx);
+                (*pl)[globalIdx]                 = volVars.pressure(wPhaseIdx);
+                (*pc)[globalIdx]              = volVars.capillaryPressure();
+                (*rhoL)[globalIdx]               = volVars.density(wPhaseIdx);
+                (*rhoG)[globalIdx]               = volVars.density(nPhaseIdx);
+                (*mobL)[globalIdx]               = volVars.mobility(wPhaseIdx);
+                (*mobG)[globalIdx]               = volVars.mobility(nPhaseIdx);
+                (*boxVolume)[globalIdx]        += fvGeometry.subContVol[i].volume;
+                (*poro)[globalIdx]              = volVars.porosity();
+
+                for (int sPhaseIdx = 0; sPhaseIdx < numSPhases; ++sPhaseIdx)
+                {
+                    (*precipitateVolumeFraction[sPhaseIdx])[globalIdx]   = volVars.precipitateVolumeFraction(sPhaseIdx + numPhases);
+                }
+                (*temperature)[globalIdx]      = volVars.temperature();
+                (*permeabilityFactor)[globalIdx]      = volVars.permeabilityFactor();
+                (*phasePresence)[globalIdx]  = this->staticDat_[globalIdx].phasePresence;
+
+                for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
+                    for (int compIdx = 0; compIdx < numComponents; ++compIdx)
+                    {
+                        (*massFraction[phaseIdx][compIdx])[globalIdx]= volVars.massFraction(phaseIdx,compIdx);
+
+                        Valgrind::CheckDefined((*massFraction[phaseIdx][compIdx])[globalIdx]);
+
+                    }
+                for (int compIdx = 0; compIdx < numComponents; ++compIdx)
+                    (*molarity[compIdx])[globalIdx] = (volVars.molarity(wPhaseIdx, compIdx));
+
+                Tensor K = this->perm_(this->problem_().spatialParams().intrinsicPermeability(element, fvGeometry, i));
+
+                for (int j = 0; j<dim; ++j)
+                    (*Perm[j])[globalIdx] = K[j][j] * volVars.permeabilityFactor();
+            };
+
+            // velocity output
+            if(velocityOutput.enableOutput()){
+                velocityOutput.calculateVelocity(*velocityW, elemVolVars, fvGeometry, element, wPhaseIdx);
+                velocityOutput.calculateVelocity(*velocityN, elemVolVars, fvGeometry, element, nPhaseIdx);
+            }
+        }  // loop over element
+
+        writer.attachVertexData(*Sg, "Sg");
+        writer.attachVertexData(*Sl, "Sl");
+        writer.attachVertexData(*pg, "pg");
+        writer.attachVertexData(*pl, "pl");
+        writer.attachVertexData(*pc, "pc");
+        writer.attachVertexData(*rhoL, "rhoL");
+        writer.attachVertexData(*rhoG, "rhoG");
+        writer.attachVertexData(*mobL, "mobL");
+        writer.attachVertexData(*mobG, "mobG");
+        writer.attachVertexData(*poro, "porosity");
+        writer.attachVertexData(*permeabilityFactor, "permeabilityFactor");
+        writer.attachVertexData(*temperature, "temperature");
+        writer.attachVertexData(*phasePresence, "phase presence");
+        writer.attachVertexData(*boxVolume, "boxVolume");
+
+
+        for (int i = 0; i < numSPhases; ++i)
+        {
+            std::ostringstream oss;
+            oss << "precipitateVolumeFraction_"
+                << FluidSystem::phaseName(numPhases + i);
+            writer.attachDofData(*precipitateVolumeFraction[i], oss.str().c_str(), isBox);
+        }
+
+        writer.attachVertexData(*Perm[0], "Kxx");
+        if (dim >= 2)
+            writer.attachVertexData(*Perm[1], "Kyy");
+        if (dim == 3)
+            writer.attachVertexData(*Perm[2], "Kzz");
+
+        for (int i = 0; i < numPhases; ++i)
+        {
+            for (int j = 0; j < numComponents; ++j)
+            {
+                std::ostringstream oss;
+                oss << "X^"
+                << FluidSystem::phaseName(i)
+                << "_"
+                << FluidSystem::componentName(j);
+                writer.attachVertexData(*massFraction[i][j], oss.str().c_str());
+            }
+        }
+
+        for (int j = 0; j < numComponents; ++j)
+        {
+            std::ostringstream oss;
+            oss << "m^w_"
+                << FluidSystem::componentName(j);
+            writer.attachVertexData(*molarity[j], oss.str().c_str());
+        }
+
+        if (velocityOutput.enableOutput()) // check if velocity output is demanded
+        {
+            writer.attachDofData(*velocityW,  "velocityW", isBox, dim);
+            writer.attachDofData(*velocityN,  "velocityN", isBox, dim);
+        }
+
+        writer.attachCellData(*rank, "process rank");
+    }
+
+    /*!
+     * \brief Update the static data of all vertices in the grid.
+     *
+     * \param curGlobalSol The current global solution
+     * \param oldGlobalSol The previous global solution
+     */
+    void updateStaticData(SolutionVector &curGlobalSol,
+                          const SolutionVector &oldGlobalSol)
+    {
+        bool wasSwitched = false;
+
+        for (unsigned i = 0; i < this->staticDat_.size(); ++i)
+            this->staticDat_[i].visited = false;
+
+        FVElementGeometry fvGeometry;
+        static VolumeVariables volVars;
+        for (const auto& element : Dune::elements(this->gridView_()))
+        {
+            fvGeometry.update(this->gridView_(), element);
+            for (int i = 0; i < fvGeometry.numScv; ++i)
+            {
+                int globalIdx = this->vertexMapper().subIndex(element, i, dim);
+
+                if (this->staticDat_[globalIdx].visited)
+                    continue;
+
+                this->staticDat_[globalIdx].visited = true;
+                volVars.update(curGlobalSol[globalIdx],
+                               this->problem_(),
+                               element,
+                               fvGeometry,
+                               i,
+                               false);
+                const GlobalPosition &global = element.geometry().corner(i);
+                if (primaryVarSwitch_(curGlobalSol,
+                                      volVars,
+                                      globalIdx,
+                                      global))
+                { wasSwitched = true;
+                }
+            }
+        }
+
+        // make sure that if there was a variable switch in an
+        // other partition we will also set the switch flag
+        // for our partition.
+        if (this->gridView_().comm().size() > 1)
+        wasSwitched = this->gridView_().comm().max(wasSwitched);
+
+        setSwitched_(wasSwitched);
+    }
+protected:
+
+    /*!
+     * \brief Set whether there was a primary variable switch after in
+     *        the last timestep.
+     */
+    void setSwitched_(bool yesno)
+    {
+        switchFlag_ = yesno;
+    }
+
+    /*!
+     * \copydoc 2pnc::primaryVarSwitch_
+     */
+    bool primaryVarSwitch_(SolutionVector &globalSol,
+                           const VolumeVariables &volVars, int globalIdx,
+                           const GlobalPosition &globalPos)
+    {
+            // evaluate primary variable switch
+            bool wouldSwitch = false;
+            int phasePresence = this->staticDat_[globalIdx].phasePresence;
+            int newPhasePresence = phasePresence;
+
+            //check if a primary variable switch is necessary
+            if (phasePresence == bothPhases)
+            {
+                Scalar Smin = 0.0; //saturation threshold
+                if (this->staticDat_[globalIdx].wasSwitched)
+                    Smin = -0.01;
+
+                //if saturation of liquid phase is smaller 0 switch
+                if (volVars.saturation(wPhaseIdx) <= Smin)
+                {
+                    wouldSwitch = true;
+                    //liquid phase has to disappear
+                    std::cout << "Liquid Phase disappears at vertex " << globalIdx
+                                << ", coordinated: " << globalPos << ", Sl: "
+                                << volVars.saturation(wPhaseIdx) << std::endl;
+                    newPhasePresence = nPhaseOnly;
+
+                    //switch not depending on formulation
+                    //switch "Sl" to "xgH20"
+                    globalSol[globalIdx][switchIdx]
+                            = volVars.moleFraction(nPhaseIdx, wCompIdx /*H2O*/);
+                    //Here unlike 2pnc model we do not switch all components to to mole fraction in gas phase
+                }
+                //if saturation of gas phase is smaller than 0 switch
+                else if (volVars.saturation(nPhaseIdx) <= Smin)
+                {
+                    wouldSwitch = true;
+                    //gas phase has to disappear
+                    std::cout << "Gas Phase disappears at vertex " << globalIdx
+                                << ", coordinated: " << globalPos << ", Sg: "
+                                << volVars.saturation(nPhaseIdx) << std::endl;
+                    newPhasePresence = wPhaseOnly;
+
+                    //switch "Sl" to "xlN2"
+                    globalSol[globalIdx][switchIdx]
+                            = volVars.moleFraction(wPhaseIdx, nCompIdx /*N2*/);
+                }
+            }
+            else if (phasePresence == nPhaseOnly)
+            {
+            Scalar sumxl = 0;
+            //Calculate sum of mole fractions (water and air) in the hypothetical liquid phase
+            //WARNING: Here numComponents is replaced by numMajorComponents as the solutes
+            //are only present in the liquid phase and cannot condense as the liquid (water).
+            for (int compIdx = 0; compIdx < numComponents; compIdx++)
+                {
+                    sumxl += volVars.moleFraction(wPhaseIdx, compIdx);
+                }
+                    Scalar xlmax = 1.0;
+                    if (sumxl > xlmax)
+                wouldSwitch = true;
+                    if (this->staticDat_[globalIdx].wasSwitched)
+                xlmax *=1.02;
+
+            //if the sum of the mole fractions would be larger than
+            //1, wetting phase appears
+                    if (sumxl/*sum of mole fractions*/ > xlmax/*1*/)
+                    {
+                        // liquid phase appears
+                        std::cout << "Liquid Phase appears at vertex " << globalIdx
+                                << ", coordinated: " << globalPos << ", sumxl: "
+                                << sumxl << std::endl;
+                        newPhasePresence = bothPhases;
+                        if (formulation == pgSl)
+                            globalSol[globalIdx][switchIdx] = 0.0;
+                        else if (formulation == plSg)
+                            globalSol[globalIdx][switchIdx] = 1.0;
+                    //Here unlike 2pnc model we do not switch all components to to mole fraction in gas phase
+                    }
+            }
+            else if (phasePresence == wPhaseOnly)
+            {
+                Scalar xgmax = 1;
+                Scalar sumxg = 0;
+                //Calculate sum of mole fractions in the hypothetical gas phase
+                for (int compIdx = 0; compIdx < numComponents; compIdx++)
+                {
+                    sumxg += volVars.moleFraction(nPhaseIdx, compIdx);
+                }
+                if (sumxg > xgmax)
+                    wouldSwitch = true;
+                if (this->staticDat_[globalIdx].wasSwitched)
+                    xgmax *=1.02;
+                //liquid phase appears if sum is larger than one
+                if (sumxg > xgmax)
+                {
+                    std::cout << "Gas Phase appears at vertex " << globalIdx
+                            << ", coordinated: " << globalPos << ", sumxg: "
+                            << sumxg << std::endl;
+                    newPhasePresence = bothPhases;
+                    //saturation of the liquid phase set to 0.9999 (if formulation pgSl and vice versa)
+                    if (formulation == pgSl)
+                        globalSol[globalIdx][switchIdx] = 0.999;
+                    else if (formulation == plSg)
+                        globalSol[globalIdx][switchIdx] = 0.001;
+
+                }
+            }
+            this->staticDat_[globalIdx].phasePresence = newPhasePresence;
+            this->staticDat_[globalIdx].wasSwitched = wouldSwitch;
+            return phasePresence != newPhasePresence;
+        }
+        // parameters given in constructor
+        bool switchFlag_;
+};
+
+}
+
+#include "propertydefaults.hh"
+
+#endif
diff --git a/dumux/porousmediumflow/2pncmin/implicit/properties.hh b/dumux/porousmediumflow/2pncmin/implicit/properties.hh
new file mode 100644
index 0000000000..2171d0bc83
--- /dev/null
+++ b/dumux/porousmediumflow/2pncmin/implicit/properties.hh
@@ -0,0 +1,65 @@
+// -**- 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/>.   *
+ *****************************************************************************/
+/*!
+ * \ingroup Properties
+ * \ingroup ImplicitProperties
+ * \ingroup TwoPNCMinModel
+ *
+ * \file
+ *
+ * \brief Defines the properties required for the two-phase n-component mineralization
+ *        fully implicit model.
+ */
+#ifndef DUMUX_2PNCMIN_PROPERTIES_HH
+#define DUMUX_2PNCMIN_PROPERTIES_HH
+
+#include <dumux/porousmediumflow/2pnc/implicit/properties.hh>
+
+namespace Dumux
+{
+
+namespace Properties
+{
+//////////////////////////////////////////////////////////////////
+// Type tags
+//////////////////////////////////////////////////////////////////
+
+//! The type tag for the isothermal two phase n component mineralisation problems
+NEW_TYPE_TAG(TwoPNCMin, INHERITS_FROM(TwoPNC));
+NEW_TYPE_TAG(BoxTwoPNCMin, INHERITS_FROM(BoxModel, TwoPNCMin));
+NEW_TYPE_TAG(CCTwoPNCMin, INHERITS_FROM(CCModel, TwoPNCMin));
+
+//////////////////////////////////////////////////////////////////
+// Property tags
+//////////////////////////////////////////////////////////////////
+
+NEW_PROP_TAG(NumSPhases); //!< Number of solid phases in the system
+NEW_PROP_TAG(NumFSPhases); //!< Number of fluid and solid phases in the system
+NEW_PROP_TAG(NumSComponents); //!< Number of solid components in the system
+NEW_PROP_TAG(NumPSComponents); //!< Number of fluid and solid components in the system
+NEW_PROP_TAG(NumTraceComponents); //!< Number of trace fluid components which are not considered in the calculation of the phase density
+NEW_PROP_TAG(NumSecComponents); //!< Number of secondary components which are not primary variables
+NEW_PROP_TAG(TwoPNCMinIndices); //!< Enumerations for the 2pncMin models
+NEW_PROP_TAG(useSalinity); //!< Determines if salinity is used
+NEW_PROP_TAG(SpatialParamsForchCoeff); //!< Property for the forchheimer coefficient
+
+}
+}
+
+#endif
diff --git a/dumux/porousmediumflow/2pncmin/implicit/propertydefaults.hh b/dumux/porousmediumflow/2pncmin/implicit/propertydefaults.hh
new file mode 100644
index 0000000000..e3854eb01e
--- /dev/null
+++ b/dumux/porousmediumflow/2pncmin/implicit/propertydefaults.hh
@@ -0,0 +1,143 @@
+// -**- 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/>.   *
+ *****************************************************************************/
+/*!
+ * \ingroup Properties
+ * \ingroup ImplicitProperties
+ * \ingroup TwoPNCMinModel
+ * \file
+ *
+ * \brief Defines default values for most properties required by the
+ *        two-phase n-component mineralization fully implicit model.
+ */
+#ifndef DUMUX_2PNCMIN_PROPERTY_DEFAULTS_HH
+#define DUMUX_2PNCMIN_PROPERTY_DEFAULTS_HH
+
+#include "indices.hh"
+#include "model.hh"
+#include "indices.hh"
+#include "fluxvariables.hh"
+#include "volumevariables.hh"
+#include "properties.hh"
+
+#include <dumux/porousmediumflow/2pnc/implicit/newtoncontroller.hh>
+#include <dumux/porousmediumflow/implicit/darcyfluxvariables.hh>
+#include <dumux/material/spatialparams/implicitspatialparams.hh>
+
+namespace Dumux
+{
+
+namespace Properties {
+//////////////////////////////////////////////////////////////////
+// Property values
+//////////////////////////////////////////////////////////////////
+
+/*!
+ * \brief Set the property for the number of secondary components.
+ * Secondary components are components calculated from
+ * primary components by equilibrium relations and
+ * do not have mass balance equation on their own.
+ * These components are important in the context of bio-mineralization applications.
+ * We just forward the number from the fluid system
+ *
+ */
+SET_PROP(TwoPNCMin, NumSecComponents)
+{
+private:
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(FluidSystem)) FluidSystem;
+
+public:
+    static const int value = FluidSystem::numSecComponents;
+
+};
+/*!
+ * \brief Set the property for the number of solid phases, excluding the non-reactive matrix.
+ *
+ * We just forward the number from the fluid system
+ *
+ */
+SET_PROP(TwoPNCMin, NumSPhases)
+{
+private:
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(FluidSystem)) FluidSystem;
+
+public:
+    static const int value = FluidSystem::numSPhases;
+};
+
+/*!
+ * \brief Set the property for the number of equations.
+ * For each component and each precipitated mineral/solid phase one equation has to
+ * be solved.
+ */
+SET_PROP(TwoPNCMin, NumEq)
+{
+private:
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(FluidSystem)) FluidSystem;
+
+public:
+    static const int value = FluidSystem::numComponents + FluidSystem::numSPhases;
+};
+
+/*!
+ * \brief The fluid state which is used by the volume variables to
+ *        store the thermodynamic state. This should be chosen
+ *        appropriately for the model ((non-)isothermal, equilibrium, ...).
+ *        This can be done in the problem.
+ */
+SET_PROP(TwoPNCMin, FluidState){
+    private:
+        typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+        typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+    public:
+        typedef Dumux::CompositionalFluidState<Scalar, FluidSystem> type;
+};
+
+//! Use the 2pncmin local residual operator
+SET_TYPE_PROP(TwoPNCMin,
+              LocalResidual,
+              TwoPNCMinLocalResidual<TypeTag>);
+
+//! the Model property
+SET_TYPE_PROP(TwoPNCMin, Model, TwoPNCMinModel<TypeTag>);
+
+//! the VolumeVariables property
+SET_TYPE_PROP(TwoPNCMin, VolumeVariables, TwoPNCMinVolumeVariables<TypeTag>);
+
+//! the FluxVariables property
+SET_TYPE_PROP(TwoPNCMin, FluxVariables, TwoPNCMinFluxVariables<TypeTag>);
+
+//! The indices required by the isothermal 2pNcMin model
+SET_TYPE_PROP(TwoPNCMin, Indices, TwoPNCMinIndices <TypeTag, /*PVOffset=*/0>);
+
+//! disable useSalinity for the calculation of osmotic pressure by default
+SET_BOOL_PROP(TwoPNCMin, useSalinity, false);
+
+
+//! default value for the forchheimer coefficient
+// Source: Ward, J.C. 1964 Turbulent flow in porous media. ASCE J. Hydraul. Div 90.
+//        Actually the Forchheimer coefficient is also a function of the dimensions of the
+//        porous medium. Taking it as a constant is only a first approximation
+//        (Nield, Bejan, Convection in porous media, 2006, p. 10)
+SET_SCALAR_PROP(TwoPNCMin, SpatialParamsForchCoeff, 0.55);
+
+}
+
+}
+
+#endif
diff --git a/dumux/porousmediumflow/2pncmin/implicit/volumevariables.hh b/dumux/porousmediumflow/2pncmin/implicit/volumevariables.hh
new file mode 100644
index 0000000000..84850e8988
--- /dev/null
+++ b/dumux/porousmediumflow/2pncmin/implicit/volumevariables.hh
@@ -0,0 +1,549 @@
+// -**- 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/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ *
+ * \brief Contains the quantities which are constant within a
+ *        finite volume in the two-phase, n-component mineralization model.
+ */
+#ifndef DUMUX_2PNCMin_VOLUME_VARIABLES_HH
+#define DUMUX_2PNCMin_VOLUME_VARIABLES_HH
+
+#include <dumux/implicit/model.hh>
+#include <dumux/material/fluidstates/compositionalfluidstate.hh>
+#include <dumux/common/math.hh>
+#include <vector>
+#include <iostream>
+
+#include "properties.hh"
+#include "indices.hh"
+#include <dumux/material/constraintsolvers/computefromreferencephase2pncmin.hh>
+#include <dumux/material/constraintsolvers/miscible2pnccomposition.hh>
+#include <dumux/porousmediumflow/2pnc/implicit/volumevariables.hh>
+
+namespace Dumux
+{
+
+/*!
+ * \ingroup TwoPNCMinModel
+ * \ingroup ImplicitVolumeVariables
+ * \brief Contains the quantities which are are constant within a
+ *        finite volume in the two-phase, n-component model.
+ */
+template <class TypeTag>
+class TwoPNCMinVolumeVariables : public TwoPNCVolumeVariables<TypeTag>
+{
+    typedef TwoPNCVolumeVariables<TypeTag> ParentType;
+    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) Implementation;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, Grid) Grid;
+    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
+    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
+    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
+    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+    typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw;
+    typedef typename GET_PROP_TYPE(TypeTag, MaterialLawParams) MaterialLawParams;
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+
+    enum
+    {
+        dim = GridView::dimension,
+        dimWorld=GridView::dimensionworld,
+
+        numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
+        numSPhases =  GET_PROP_VALUE(TypeTag, NumSPhases),
+        numComponents = GET_PROP_VALUE(TypeTag, NumComponents),
+        numMajorComponents = GET_PROP_VALUE(TypeTag, NumMajorComponents),
+
+        // formulations
+        formulation = GET_PROP_VALUE(TypeTag, Formulation),
+        plSg = TwoPNCFormulation::plSg,
+        pgSl = TwoPNCFormulation::pgSl,
+
+        // phase indices
+        wPhaseIdx = FluidSystem::wPhaseIdx,
+        nPhaseIdx = FluidSystem::nPhaseIdx,
+
+        // component indices
+        wCompIdx = FluidSystem::wCompIdx,
+        nCompIdx = FluidSystem::nCompIdx,
+
+        // phase presence enums
+        nPhaseOnly = Indices::nPhaseOnly,
+        wPhaseOnly = Indices::wPhaseOnly,
+        bothPhases = Indices::bothPhases,
+
+        // primary variable indices
+        pressureIdx = Indices::pressureIdx,
+        switchIdx = Indices::switchIdx,
+
+        useSalinity = GET_PROP_VALUE(TypeTag, useSalinity)
+    };
+
+    typedef typename GridView::template Codim<0>::Entity Element;
+    typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition;
+    typedef typename Grid::ctype CoordScalar;
+    typedef Dumux::Miscible2pNCComposition<Scalar, FluidSystem> Miscible2pNCComposition;
+    typedef Dumux::ComputeFromReferencePhase2pNCMin<Scalar, FluidSystem> ComputeFromReferencePhase2pNCMin;
+
+    enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) };
+    enum { dofCodim = isBox ? dim : 0 };
+public:
+
+    typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState;
+
+    /*!
+     * \copydoc ImplicitVolumeVariables::update
+     */
+    void update(const PrimaryVariables &priVars,
+                const Problem &problem,
+                const Element &element,
+                const FVElementGeometry &fvGeometry,
+                int scvIdx,
+                bool isOldSol)
+    {
+        ParentType::update(priVars,
+                           problem,
+                           element,
+                           fvGeometry,
+                           scvIdx,
+                           isOldSol);
+
+        completeFluidState(priVars, problem, element, fvGeometry, scvIdx, this->fluidState_, isOldSol);
+
+    /////////////
+        // calculate the remaining quantities
+        /////////////
+
+    // porosity evaluation
+    initialPorosity_ = problem.spatialParams().porosity(element, fvGeometry, scvIdx);
+    minimumPorosity_ = problem.spatialParams().porosityMin(element, fvGeometry, scvIdx);
+
+
+    sumPrecipitates_ = 0.0;
+    for(int sPhaseIdx = 0; sPhaseIdx < numSPhases; ++sPhaseIdx)
+    {
+       precipitateVolumeFraction_[sPhaseIdx] = priVars[numComponents + sPhaseIdx];
+       sumPrecipitates_+= precipitateVolumeFraction_[sPhaseIdx];
+    }
+
+//         for(int sPhaseIdx = 0; sPhaseIdx < numSPhases; ++sPhaseIdx)
+//     {
+//         Chemistry chemistry; // the non static functions can not be called without abject
+//         saturationIdx_[sPhaseIdx] = chemistry.omega(sPhaseIdx);
+//     }
+// TODO/FIXME: The salt crust porosity is not clearly defined. However form literature review it is
+//    found that the salt crust have porosity of approx. 10 %. Thus we restrict the decrease in porosity
+//    to this limit. Moreover in the Problem files the precipitation should also be made dependent on local
+//    porosity value, as the porous media media properties change related to salt precipitation will not be
+//    accounted otherwise.
+
+//      this->porosity_ = initialPorosity_ - sumPrecipitates_;
+
+     this->porosity_ = std::max(minimumPorosity_, std::max(0.0, initialPorosity_ - sumPrecipitates_));
+
+   salinity_= 0.0;
+   moleFractionSalinity_ = 0.0;
+   for (int compIdx = numMajorComponents; compIdx< numComponents; compIdx++)    //sum of the mass fraction of the components
+   {
+       if(this->fluidState_.moleFraction(wPhaseIdx, compIdx)> 0)
+       {
+          salinity_+= this->fluidState_.massFraction(wPhaseIdx, compIdx);
+          moleFractionSalinity_ += this->fluidState_.moleFraction(wPhaseIdx, compIdx);
+       }
+    }
+
+// TODO/FIXME: Different relations for the porosoty-permeability changes are given here. We have to fins a way
+//    so that one can select the relation form the input file.
+
+    // kozeny-Carman relation
+    permeabilityFactor_  =  std::pow(((1-initialPorosity_)/(1-this->porosity_)),2)
+            * std::pow((this->porosity_/initialPorosity_),3);
+
+    // Verma-Pruess relation
+//  permeabilityFactor_  =  100 * std::pow(((this->porosity_/initialPorosity_)-0.9),2);
+
+    // Modified Fair-Hatch relation with final porosity set to 0.2 and E1=1
+//  permeabilityFactor_  =  std::pow((this->porosity_/initialPorosity_),3)
+//         * std::pow((std::pow((1 - initialPorosity_),2/3))+(std::pow((0.2 - initialPorosity_),2/3)),2)
+//         / std::pow((std::pow((1 -this->porosity_),2/3))+(std::pow((0.2 -this->porosity_),2/3)),2);
+
+    //Timur relation with residual water saturation set to 0.001
+//    permeabilityFactor_ =  0.136 * (std::pow(this->porosity_,4.4)) / (2000 * (std::pow(0.001,2)));
+
+    //Timur relation1 with residual water saturation set to 0.001
+//    permeabilityFactor_ =  0.136 * (std::pow(this->porosity_,4.4)) / (200000 * (std::pow(0.001,2)));
+
+
+    //Bern. relation
+   // permeabilityFactor_ = std::pow((this->porosity_/initialPorosity_),8);
+
+    //Tixier relation with residual water saturation set to 0.001
+    //permeabilityFactor_ = (std::pow((250 * (std::pow(this->porosity_,3)) / 0.001),2)) / initialPermeability_;
+
+    //Coates relation with residual water saturation set to 0.001
+    //permeabilityFactor_ = (std::pow((100 * (std::pow(this->porosity_,2)) * (1-0.001) / 0.001,2))) / initialPermeability_ ;
+
+
+    // energy related quantities not contained in the fluid state
+    //asImp_().updateEnergy_(priVars, problem,element, fvGeometry, scvIdx, isOldSol);
+    }
+
+   /*!
+    * \copydoc ImplicitModel::completeFluidState
+    * \param isOldSol Specifies whether this is the previous solution or the current one
+    */
+  static void completeFluidState(const PrimaryVariables& priVars,
+                                 const Problem& problem,
+                                 const Element& element,
+                                 const FVElementGeometry& fvGeometry,
+                                 int scvIdx,
+                                 FluidState& fluidState,
+                                 bool isOldSol = false)
+
+    {
+        Scalar t = Implementation::temperature_(priVars, problem, element,fvGeometry, scvIdx);
+        fluidState.setTemperature(t);
+
+        int dofIdxGlobal = problem.model().dofMapper().subIndex(element, scvIdx, dofCodim);
+        int phasePresence = problem.model().phasePresence(dofIdxGlobal, isOldSol);
+
+        /////////////
+        // set the saturations
+        /////////////
+
+        Scalar Sg;
+        if (phasePresence == nPhaseOnly)
+            Sg = 1.0;
+        else if (phasePresence == wPhaseOnly) {
+            Sg = 0.0;
+        }
+        else if (phasePresence == bothPhases) {
+            if (formulation == plSg)
+                Sg = priVars[switchIdx];
+            else if (formulation == pgSl)
+                Sg = 1.0 - priVars[switchIdx];
+            else DUNE_THROW(Dune::InvalidStateException, "Formulation: " << formulation << " is invalid.");
+        }
+        else DUNE_THROW(Dune::InvalidStateException, "phasePresence: " << phasePresence << " is invalid.");
+        fluidState.setSaturation(nPhaseIdx, Sg);
+        fluidState.setSaturation(wPhaseIdx, 1.0 - Sg);
+
+        /////////////
+        // set the pressures of the fluid phases
+        /////////////
+
+        // calculate capillary pressure
+        const MaterialLawParams &materialParams = problem.spatialParams().materialLawParams(element, fvGeometry, scvIdx);
+        Scalar pc = MaterialLaw::pc(materialParams, 1 - Sg);
+
+        // extract the pressures
+        if (formulation == plSg) {
+            fluidState.setPressure(wPhaseIdx, priVars[pressureIdx]);
+            fluidState.setPressure(nPhaseIdx, priVars[pressureIdx] + pc);
+        }
+        else if (formulation == pgSl) {
+            fluidState.setPressure(nPhaseIdx, priVars[pressureIdx]);
+            fluidState.setPressure(wPhaseIdx, priVars[pressureIdx] - pc);
+        }
+        else DUNE_THROW(Dune::InvalidStateException, "Formulation: " << formulation << " is invalid.");
+
+        /////////////
+        // calculate the phase compositions
+        /////////////
+
+    typename FluidSystem::ParameterCache paramCache;
+
+        // now comes the tricky part: calculate phase composition
+        if (phasePresence == bothPhases) {
+            // both phases are present, phase composition results from
+            // the gas <-> liquid equilibrium. This is
+            // the job of the "MiscibleMultiPhaseComposition"
+            // constraint solver
+
+            // set the known mole fractions in the fluidState so that they
+            // can be used by the Miscible2pNcComposition constraint solver
+            for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx)
+            {
+                fluidState.setMoleFraction(wPhaseIdx, compIdx, priVars[compIdx]);
+            }
+
+            Miscible2pNCComposition::solve(fluidState,
+                                            paramCache,
+                                            wPhaseIdx,  //known phaseIdx
+                                            /*setViscosity=*/true,
+                                            /*setInternalEnergy=*/false);
+        }
+        else if (phasePresence == nPhaseOnly){
+
+            Dune::FieldVector<Scalar, numComponents> moleFrac;
+            Dune::FieldVector<Scalar, numComponents> fugCoeffL;
+            Dune::FieldVector<Scalar, numComponents> fugCoeffG;
+
+            for (int compIdx=0; compIdx<numComponents; ++compIdx)
+            {
+                fugCoeffL[compIdx] = FluidSystem::fugacityCoefficient(fluidState,
+                                        paramCache,
+                                        wPhaseIdx,
+                                        compIdx);
+                fugCoeffG[compIdx] = FluidSystem::fugacityCoefficient(fluidState,
+                                        paramCache,
+                                        nPhaseIdx,
+                                        compIdx);
+            }
+            for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx)
+                moleFrac[compIdx] = (priVars[compIdx]*fugCoeffL[compIdx]*fluidState.pressure(wPhaseIdx))
+                /(fugCoeffG[compIdx]*fluidState.pressure(nPhaseIdx));
+
+            moleFrac[wCompIdx] =  priVars[switchIdx];
+            Scalar sumMoleFracNotGas = 0;
+            for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx)
+            {
+                    sumMoleFracNotGas+=moleFrac[compIdx];
+            }
+            sumMoleFracNotGas += moleFrac[wCompIdx];
+            moleFrac[nCompIdx] = 1 - sumMoleFracNotGas;
+
+//          typedef Dune::FieldMatrix<Scalar, numComponents, numComponents> Matrix;
+//          typedef Dune::FieldVector<Scalar, numComponents> Vector;
+
+
+            // Set fluid state mole fractions
+            for (int compIdx=0; compIdx<numComponents; ++compIdx)
+            {
+                fluidState.setMoleFraction(nPhaseIdx, compIdx, moleFrac[compIdx]);
+            }
+
+            // calculate the composition of the remaining phases (as
+            // well as the densities of all phases). this is the job
+            // of the "ComputeFromReferencePhase2pNc" constraint solver
+            ComputeFromReferencePhase2pNCMin::solve(fluidState,
+                                                    paramCache,
+                                                    nPhaseIdx,
+                                                    nPhaseOnly,
+                                                    /*setViscosity=*/true,
+                                                    /*setInternalEnergy=*/false);
+
+            }
+        else if (phasePresence == wPhaseOnly){
+
+        // only the liquid phase is present, i.e. liquid phase
+        // composition is stored explicitly.
+        // extract _mass_ fractions in the gas phase
+            Dune::FieldVector<Scalar, numComponents> moleFrac;
+
+            for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx)
+            {
+                moleFrac[compIdx] = priVars[compIdx];
+            }
+            moleFrac[nCompIdx] = priVars[switchIdx];
+            Scalar sumMoleFracNotWater = 0;
+            for (int compIdx=numMajorComponents; compIdx<numComponents; ++compIdx)
+            {
+                    sumMoleFracNotWater+=moleFrac[compIdx];
+            }
+            sumMoleFracNotWater += moleFrac[nCompIdx];
+            moleFrac[wCompIdx] = 1 -sumMoleFracNotWater;
+
+//             convert mass to mole fractions and set the fluid state
+            for (int compIdx=0; compIdx<numComponents; ++compIdx)
+            {
+                fluidState.setMoleFraction(wPhaseIdx, compIdx, moleFrac[compIdx]);
+            }
+
+//             calculate the composition of the remaining phases (as
+//             well as the densities of all phases). this is the job
+//             of the "ComputeFromReferencePhase2pNc" constraint solver
+            ComputeFromReferencePhase2pNCMin::solve(fluidState,
+                                                    paramCache,
+                                                    wPhaseIdx,
+                                                    wPhaseOnly,
+                                                    /*setViscosity=*/true,
+                                                    /*setInternalEnergy=*/false);
+        }
+        paramCache.updateAll(fluidState);
+        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
+        {
+            Scalar h = Implementation::enthalpy_(fluidState, paramCache, phaseIdx);
+            fluidState.setEnthalpy(phaseIdx, h);
+        }
+    }
+    /*!
+     * \brief Returns the volume fraction of the precipitate (solid phase)
+     * for the given phaseIdx
+     *
+     * \param phaseIdx the index of the solid phase
+     */
+    Scalar precipitateVolumeFraction(int phaseIdx) const
+    { return precipitateVolumeFraction_[phaseIdx - numPhases]; }
+
+    /*!
+     * \brief Returns the inital porosity of the
+     * pure, precipitate-free porous medium
+     */
+    Scalar initialPorosity() const
+    { return initialPorosity_;}
+
+    /*!
+     * \brief Returns the inital permeability of the
+     * pure, precipitate-free porous medium
+     */
+    Scalar initialPermeability() const
+    { return initialPermeability_;}
+
+    /*!
+     * \brief Returns the factor for the reduction of the initial permeability
+     * due precipitates in the porous medium
+     */
+    Scalar permeabilityFactor() const
+    { return permeabilityFactor_; }
+
+//    /*!
+//     * \brief Returns the mole fraction of a component in the phase
+//     *
+//     * \param phaseIdx the index of the fluid phase
+//     * \param compIdx the index of the component
+//     */
+//    Scalar moleFraction(int phaseIdx, int compIdx) const
+//    {
+//       return this->fluidState_.moleFraction(phaseIdx, compIdx);
+//    }
+
+    /*!
+     * \brief Returns the mole fraction of the salinity in the liquid phase
+     */
+    Scalar moleFracSalinity() const
+    {
+        return moleFractionSalinity_;
+    }
+
+    /*!
+     * \brief Returns the salinity (mass fraction) in the liquid phase
+     */
+    Scalar salinity() const
+    {
+        return salinity_;
+    }
+
+    /*!
+     * \brief Returns the density of the phase for all fluid and solid phases
+     *
+     * \param phaseIdx the index of the fluid phase
+     */
+    Scalar density(int phaseIdx) const
+    {
+        if (phaseIdx < numPhases)
+            return this->fluidState_.density(phaseIdx);
+        else if (phaseIdx >= numPhases)
+            return FluidSystem::precipitateDensity(phaseIdx);
+        else
+            DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx);
+    }
+    /*!
+     * \brief Returns the mass density of a given phase within the
+     *        control volume.
+     *
+     * \param phaseIdx The phase index
+     */
+    Scalar molarDensity(int phaseIdx) const
+    {
+        if (phaseIdx < numPhases)
+            return this->fluidState_.molarDensity(phaseIdx);
+        else if (phaseIdx >= numPhases)
+            return FluidSystem::precipitateMolarDensity(phaseIdx);
+        else
+            DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx);
+    }
+
+    /*!
+     * \brief Returns the molality of a component in the phase
+     *
+     * \param phaseIdx the index of the fluid phase
+     * \param compIdx the index of the component
+     * molality=\frac{n_{component}}{m_{solvent}}
+     * =\frac{n_{component}}{n_{solvent}*M_{solvent}}
+     * compIdx of the main component (solvent) in the
+     * phase is equal to the phaseIdx
+     */
+     Scalar molality(int phaseIdx, int compIdx) const // [moles/Kg]
+    { return this->fluidState_.moleFraction(phaseIdx, compIdx)
+                  /(fluidState_.moleFraction(phaseIdx, phaseIdx)
+                  * FluidSystem::molarMass(phaseIdx));}
+
+protected:
+    friend class TwoPNCVolumeVariables<TypeTag>;
+    static Scalar temperature_(const PrimaryVariables &priVars,
+                                const Problem& problem,
+                                const Element &element,
+                                const FVElementGeometry &fvGeometry,
+                                int scvIdx)
+    {
+        return problem.temperatureAtPos(fvGeometry.subContVol[scvIdx].global);
+    }
+
+    template<class ParameterCache>
+    static Scalar enthalpy_(const FluidState& fluidState,
+                            const ParameterCache& paramCache,
+                            int phaseIdx)
+    {
+        return 0;
+    }
+
+   /*!
+    * \brief Update all quantities for a given control volume.
+    *
+    * \param priVars The solution primary variables
+    * \param problem The problem
+    * \param element The element
+    * \param fvGeometry Evaluate function with solution of current or previous time step
+    * \param scvIdx The local index of the SCV (sub-control volume)
+    * \param isOldSol Evaluate function with solution of current or previous time step
+    */
+        void updateEnergy_(const PrimaryVariables &priVars,
+                           const Problem &problem,
+                           const Element &element,
+                           const FVElementGeometry &fvGeometry,
+                           const int scvIdx,
+                           bool isOldSol)
+        { };
+
+    Scalar precipitateVolumeFraction_[numSPhases];
+//     Scalar saturationIdx_[numSPhases];
+    Scalar permeabilityFactor_;
+    Scalar initialPorosity_;
+    Scalar initialPermeability_;
+    Scalar minimumPorosity_;
+    Scalar sumPrecipitates_;
+    Scalar salinity_;
+    Scalar moleFractionSalinity_;
+    FluidState fluidState_;
+
+private:
+    Implementation &asImp_()
+    { return *static_cast<Implementation*>(this); }
+
+    const Implementation &asImp_() const
+    { return *static_cast<const Implementation*>(this); }
+};
+
+} // end namespace
+
+#endif
diff --git a/dumux/porousmediumflow/3p3c/implicit/fluxvariables.hh b/dumux/porousmediumflow/3p3c/implicit/fluxvariables.hh
new file mode 100644
index 0000000000..a579e5090d
--- /dev/null
+++ b/dumux/porousmediumflow/3p3c/implicit/fluxvariables.hh
@@ -0,0 +1,386 @@
+// -*- 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/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ * \brief This file contains the data which is required to calculate
+ *        all fluxes of components over a face of a finite volume for
+ *        the three-phase three-component model.
+ */
+#ifndef DUMUX_3P3C_FLUX_VARIABLES_HH
+#define DUMUX_3P3C_FLUX_VARIABLES_HH
+
+#include <dumux/common/math.hh>
+#include <dumux/common/spline.hh>
+
+#include "properties.hh"
+
+namespace Dumux
+{
+
+/*!
+ * \ingroup ThreePThreeCModel
+ * \ingroup ImplicitFluxVariables
+ * \brief This template class contains the data which is required to
+ *        calculate all fluxes of components over a face of a finite
+ *        volume for the three-phase three-component model.
+ *
+ * This means pressure and concentration gradients, phase densities at
+ * the integration point, etc.
+ */
+template <class TypeTag>
+class ThreePThreeCFluxVariables : public GET_PROP_TYPE(TypeTag, BaseFluxVariables)
+{
+    typedef typename GET_PROP_TYPE(TypeTag, BaseFluxVariables) BaseFluxVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
+    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
+
+    typedef typename GridView::template Codim<0>::Entity Element;
+    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, EffectiveDiffusivityModel) EffectiveDiffusivityModel;
+
+    enum {
+        dim = GridView::dimension,
+        dimWorld = GridView::dimensionworld,
+        numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
+        numComponents = GET_PROP_VALUE(TypeTag, NumComponents)
+    };
+
+    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
+
+    typedef Dune::FieldVector<Scalar, dim>  DimVector;
+    typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+    enum {
+        wPhaseIdx = Indices::wPhaseIdx,
+        nPhaseIdx = Indices::nPhaseIdx,
+        gPhaseIdx = Indices::gPhaseIdx,
+
+        wCompIdx = Indices::wCompIdx,
+        nCompIdx = Indices::nCompIdx,
+        gCompIdx = Indices::gCompIdx
+    };
+
+public:
+    /*!
+     * \brief The constructor
+     *
+     * \param problem The problem
+     * \param element The finite element
+     * \param fvGeometry The finite-volume geometry in the fully implicit scheme
+     * \param fIdx The local index of the SCV (sub-control-volume) face
+     * \param elemVolVars The volume variables of the current element
+     * \param onBoundary Evaluate flux at inner sub-control-volume face or on a boundary face
+     */
+    ThreePThreeCFluxVariables(const Problem &problem,
+                              const Element &element,
+                              const FVElementGeometry &fvGeometry,
+                              const int fIdx,
+                              const ElementVolumeVariables &elemVolVars,
+                              const bool onBoundary = false)
+    : BaseFluxVariables(problem, element, fvGeometry, fIdx, elemVolVars, onBoundary)
+    {
+        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
+            density_[phaseIdx] = Scalar(0);
+            molarDensity_[phaseIdx] = Scalar(0);
+            massFractionCompWGrad_[phaseIdx] = Scalar(0);
+            massFractionCompNGrad_[phaseIdx] = Scalar(0);
+            massFractionCompGGrad_[phaseIdx] = Scalar(0);
+            moleFractionCompWGrad_[phaseIdx] = Scalar(0);
+            moleFractionCompNGrad_[phaseIdx] = Scalar(0);
+            moleFractionCompGGrad_[phaseIdx] = Scalar(0);
+        }
+
+        calculateGradients_(problem, element, elemVolVars);
+        calculatePorousDiffCoeff_(problem, element, elemVolVars);
+    };
+
+private:
+    void calculateGradients_(const Problem &problem,
+                             const Element &element,
+                             const ElementVolumeVariables &elemVolVars)
+    {
+        // calculate gradients
+        GlobalPosition tmp(0.0);
+        for (unsigned int idx = 0;
+             idx < this->face().numFap;
+             idx++) // loop over adjacent vertices
+        {
+            // FE gradient at vertex idx
+            const GlobalPosition &feGrad = this->face().grad[idx];
+
+            // index for the element volume variables
+            int volVarsIdx = this->face().fapIndices[idx];
+
+            // the concentration gradient of the components
+            // component in the phases
+            tmp = feGrad;
+            tmp *= elemVolVars[volVarsIdx].massFraction(wPhaseIdx, wCompIdx);
+            massFractionCompWGrad_[wPhaseIdx] += tmp;
+
+            tmp = feGrad;
+            tmp *= elemVolVars[volVarsIdx].massFraction(nPhaseIdx, wCompIdx);
+            massFractionCompWGrad_[nPhaseIdx] += tmp;
+
+            tmp = feGrad;
+            tmp *= elemVolVars[volVarsIdx].massFraction(gPhaseIdx, wCompIdx);
+            massFractionCompWGrad_[gPhaseIdx] += tmp;
+
+            tmp = feGrad;
+            tmp *= elemVolVars[volVarsIdx].massFraction(wPhaseIdx, nCompIdx);
+            massFractionCompNGrad_[wPhaseIdx] += tmp;
+
+            tmp = feGrad;
+            tmp *= elemVolVars[volVarsIdx].massFraction(nPhaseIdx, nCompIdx);
+            massFractionCompNGrad_[nPhaseIdx] += tmp;
+
+            tmp = feGrad;
+            tmp *= elemVolVars[volVarsIdx].massFraction(gPhaseIdx, nCompIdx);
+            massFractionCompNGrad_[gPhaseIdx] += tmp;
+
+            tmp = feGrad;
+            tmp *= elemVolVars[volVarsIdx].massFraction(wPhaseIdx, gCompIdx);
+            massFractionCompGGrad_[wPhaseIdx] += tmp;
+
+            tmp = feGrad;
+            tmp *= elemVolVars[volVarsIdx].massFraction(nPhaseIdx, gCompIdx);
+            massFractionCompGGrad_[nPhaseIdx] += tmp;
+
+            tmp = feGrad;
+            tmp *= elemVolVars[volVarsIdx].massFraction(gPhaseIdx, gCompIdx);
+            massFractionCompGGrad_[gPhaseIdx] += tmp;
+
+            // the molar concentration gradients of the components
+            // in the phases
+            tmp = feGrad;
+            tmp *= elemVolVars[volVarsIdx].moleFraction(wPhaseIdx, wCompIdx);
+            moleFractionCompWGrad_[wPhaseIdx] += tmp;
+
+            tmp = feGrad;
+            tmp *= elemVolVars[volVarsIdx].moleFraction(nPhaseIdx, wCompIdx);
+            moleFractionCompWGrad_[nPhaseIdx] += tmp;
+
+            tmp = feGrad;
+            tmp *= elemVolVars[volVarsIdx].moleFraction(gPhaseIdx, wCompIdx);
+            moleFractionCompWGrad_[gPhaseIdx] += tmp;
+
+            tmp = feGrad;
+            tmp *= elemVolVars[volVarsIdx].moleFraction(wPhaseIdx, nCompIdx);
+            moleFractionCompNGrad_[wPhaseIdx] += tmp;
+
+            tmp = feGrad;
+            tmp *= elemVolVars[volVarsIdx].moleFraction(nPhaseIdx, nCompIdx);
+            moleFractionCompNGrad_[nPhaseIdx] += tmp;
+
+            tmp = feGrad;
+            tmp *= elemVolVars[volVarsIdx].moleFraction(gPhaseIdx, nCompIdx);
+            moleFractionCompNGrad_[gPhaseIdx] += tmp;
+
+            tmp = feGrad;
+            tmp *= elemVolVars[volVarsIdx].moleFraction(wPhaseIdx, gCompIdx);
+            moleFractionCompGGrad_[wPhaseIdx] += tmp;
+
+            tmp = feGrad;
+            tmp *= elemVolVars[volVarsIdx].moleFraction(nPhaseIdx, gCompIdx);
+            moleFractionCompGGrad_[nPhaseIdx] += tmp;
+
+            tmp = feGrad;
+            tmp *= elemVolVars[volVarsIdx].moleFraction(gPhaseIdx, gCompIdx);
+            moleFractionCompGGrad_[gPhaseIdx] += tmp;
+        }
+    }
+
+    Scalar rhoFactor_(int phaseIdx, int scvIdx, const ElementVolumeVariables &elemVolVars)
+    {
+        static const Scalar eps = 1e-2;
+        const Scalar sat = elemVolVars[scvIdx].density(phaseIdx);
+        if (sat > eps)
+            return 0.5;
+        if (sat <= 0)
+            return 0;
+
+        static const Dumux::Spline<Scalar> sp(0, eps, // x0, x1
+                                              0, 0.5, // y0, y1
+                                              0, 0); // m0, m1
+        return sp.eval(sat);
+    }
+
+    void calculatePorousDiffCoeff_(const Problem &problem,
+                               const Element &element,
+                               const ElementVolumeVariables &elemVolVars)
+    {
+
+        const VolumeVariables &volVarsI = elemVolVars[this->face().i];
+        const VolumeVariables &volVarsJ = elemVolVars[this->face().j];
+
+        Dune::FieldMatrix<Scalar, numPhases, numComponents> diffusionCoefficientMatrix_i = volVarsI.diffusionCoefficient();
+        Dune::FieldMatrix<Scalar, numPhases, numComponents> diffusionCoefficientMatrix_j = volVarsJ.diffusionCoefficient();
+
+        // the effective diffusion coefficients at vertex i and j
+        Scalar diffCoeffI;
+        Scalar diffCoeffJ;
+
+        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
+        {
+            // make sure to calculate only diffusion coefficents
+            // for phases which exist in both finite volumes
+            /* \todo take care: This should be discussed once again
+             * as long as a meaningful value can be found for the required mole fraction
+             * diffusion should work even without this one here */
+            if (volVarsI.saturation(phaseIdx) <= 0 ||
+                volVarsJ.saturation(phaseIdx) <= 0)
+            {
+                porousDiffCoeff_[phaseIdx][wCompIdx] = 0.0;
+                porousDiffCoeff_[phaseIdx][nCompIdx] = 0.0;
+                porousDiffCoeff_[phaseIdx][gCompIdx] = 0.0;
+                continue;
+            }
+
+            // Diffusion coefficient in the porous medium
+            diffCoeffI = EffectiveDiffusivityModel::effectiveDiffusivity(volVarsI.porosity(),
+                                                                         volVarsI.saturation(phaseIdx),
+                                                                         diffusionCoefficientMatrix_i[phaseIdx][wCompIdx]);
+            diffCoeffJ = EffectiveDiffusivityModel::effectiveDiffusivity(volVarsJ.porosity(),
+                                                                         volVarsJ.saturation(phaseIdx),
+                                                                         diffusionCoefficientMatrix_j[phaseIdx][wCompIdx]);
+
+            // -> harmonic mean
+            porousDiffCoeff_[phaseIdx][wCompIdx] = harmonicMean(diffCoeffI, diffCoeffJ);
+
+            // Diffusion coefficient in the porous medium
+            diffCoeffI = EffectiveDiffusivityModel::effectiveDiffusivity(volVarsI.porosity(),
+                                                                         volVarsI.saturation(phaseIdx),
+                                                                         diffusionCoefficientMatrix_i[phaseIdx][nCompIdx]);
+            diffCoeffJ = EffectiveDiffusivityModel::effectiveDiffusivity(volVarsJ.porosity(),
+                                                                         volVarsJ.saturation(phaseIdx),
+                                                                         diffusionCoefficientMatrix_j[phaseIdx][nCompIdx]);
+
+            // -> harmonic mean
+            porousDiffCoeff_[phaseIdx][nCompIdx] = harmonicMean(diffCoeffI, diffCoeffJ);
+
+            // Diffusion coefficient in the porous medium
+            diffCoeffI = EffectiveDiffusivityModel::effectiveDiffusivity(volVarsI.porosity(),
+                                                                         volVarsI.saturation(phaseIdx),
+                                                                         diffusionCoefficientMatrix_i[phaseIdx][gCompIdx]);
+            diffCoeffJ = EffectiveDiffusivityModel::effectiveDiffusivity(volVarsJ.porosity(),
+                                                                         volVarsJ.saturation(phaseIdx),
+                                                                         diffusionCoefficientMatrix_j[phaseIdx][gCompIdx]);
+
+            // -> harmonic mean
+            porousDiffCoeff_[phaseIdx][gCompIdx] = harmonicMean(diffCoeffI, diffCoeffJ);
+        }
+    }
+
+public:
+    /*!
+     * \brief The diffusivity matrix
+     *
+     * \tparam Scalar Field type
+     * \tparam numPhases The number of phases of the problem
+     * \tparam numComponents The number of components of the problem
+     */
+    Dune::FieldMatrix<Scalar, numPhases, numComponents> porousDiffCoeff() const
+    { return porousDiffCoeff_; };
+
+    /*!
+     * \brief Return density \f$\mathrm{[kg/m^3]}\f$ of a phase.
+     *
+     * \param phaseIdx The phase index
+     */
+    Scalar density(int phaseIdx) const
+    { return density_[phaseIdx]; }
+
+    /*!
+     * \brief Return molar density \f$\mathrm{[mol/m^3]}\f$ of a phase.
+     *
+     * \param phaseIdx The phase index
+     */
+    Scalar molarDensity(int phaseIdx) const
+    { return molarDensity_[phaseIdx]; }
+
+    /*!
+     * \brief The mass fraction gradient of the water in a phase.
+     *
+     * \param phaseIdx The phase index
+     */
+    const GlobalPosition &massFractionCompWGrad(int phaseIdx) const
+    {return massFractionCompWGrad_[phaseIdx];}
+
+    /*!
+     * \brief The mass fraction gradient of the contaminant in a phase.
+     *
+     * \param phaseIdx The phase index
+     */
+    const GlobalPosition &massFractionCompNGrad(int phaseIdx) const
+    { return massFractionCompNGrad_[phaseIdx]; };
+
+    /*!
+     * \brief The mass fraction gradient of gas in a phase.
+     *
+     * \param phaseIdx The phase index
+     */
+    const GlobalPosition &massFractionCompGGrad(int phaseIdx) const
+    { return massFractionCompGGrad_[phaseIdx]; };
+
+    /*!
+     * \brief The mole fraction gradient of the water in a phase.
+     *
+     * \param phaseIdx The phase index
+     */
+    const GlobalPosition &moleFractionCompWGrad(int phaseIdx) const
+    { return moleFractionCompWGrad_[phaseIdx]; };
+
+    /*!
+     * \brief The mole fraction gradient of the contaminant in a phase.
+     *
+     * \param phaseIdx The phase index
+     */
+    const GlobalPosition &moleFractionCompNGrad(int phaseIdx) const
+    { return moleFractionCompNGrad_[phaseIdx]; };
+
+    /*!
+     * \brief The mole fraction gradient of gas in a phase.
+     *
+     * \param phaseIdx The phase index
+     */
+    const GlobalPosition &moleFractionCompGGrad(int phaseIdx) const
+    { return moleFractionCompGGrad_[phaseIdx]; };
+
+protected:
+    // gradients
+    GlobalPosition massFractionCompWGrad_[numPhases];
+    GlobalPosition massFractionCompNGrad_[numPhases];
+    GlobalPosition massFractionCompGGrad_[numPhases];
+    GlobalPosition moleFractionCompWGrad_[numPhases];
+    GlobalPosition moleFractionCompNGrad_[numPhases];
+    GlobalPosition moleFractionCompGGrad_[numPhases];
+
+    // density of each face at the integration point
+    Scalar density_[numPhases], molarDensity_[numPhases];
+
+    // the diffusivity matrix for the porous medium
+    Dune::FieldMatrix<Scalar, numPhases, numComponents> porousDiffCoeff_;
+};
+
+} // end namespace
+
+#endif
diff --git a/dumux/porousmediumflow/3p3c/implicit/indices.hh b/dumux/porousmediumflow/3p3c/implicit/indices.hh
new file mode 100644
index 0000000000..cd832f5ec6
--- /dev/null
+++ b/dumux/porousmediumflow/3p3c/implicit/indices.hh
@@ -0,0 +1,90 @@
+// -*- 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/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ * \brief Defines the indices required for the three-phase three-component
+ *        fully implicit model.
+ */
+#ifndef DUMUX_3P3C_INDICES_HH
+#define DUMUX_3P3C_INDICES_HH
+
+#include "properties.hh"
+
+namespace Dumux
+{
+
+/*!
+ * \ingroup ThreePThreeCModel
+ * \ingroup ImplicitIndices
+ * \brief The indices for the isothermal three-phase three-component model.
+ *
+ * \tparam formulation The formulation, only pgSwSn is available.
+ * \tparam PVOffset The first index in a primary variable vector.
+ */
+template <class TypeTag, int PVOffset = 0>
+class ThreePThreeCIndices
+{
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+
+public:
+    // Phase indices
+    static const int wPhaseIdx = FluidSystem::wPhaseIdx; //!< index of the wetting liquid phase
+    static const int nPhaseIdx = FluidSystem::nPhaseIdx; //!< index of the nonwetting liquid phase
+    static const int gPhaseIdx = FluidSystem::gPhaseIdx; //!< index of the gas phase
+
+    // Component indices to indicate the main component
+    // of the corresponding phase at atmospheric pressure 1 bar
+    // and room temperature 20°C:
+    static const int wCompIdx = FluidSystem::wCompIdx;
+    static const int nCompIdx = FluidSystem::nCompIdx;
+    static const int gCompIdx = FluidSystem::gCompIdx;
+
+    // present phases (-> 'pseudo' primary variable)
+    static const int threePhases = 1; //!< All three phases are present
+    static const int wPhaseOnly = 2; //!< Only the water phase is present
+    static const int gnPhaseOnly = 3; //!< Only gas and NAPL phases are present
+    static const int wnPhaseOnly = 4; //!< Only water and NAPL phases are present
+    static const int gPhaseOnly = 5; //!< Only gas phase is present
+    static const int wgPhaseOnly = 6; //!< Only water and gas phases are present
+
+    // Primary variable indices
+    static const int pressureIdx = PVOffset + 0; //!< Index for gas phase pressure in a solution vector
+    static const int switch1Idx = PVOffset + 1; //!< Index 1 of saturation or mole fraction
+    static const int switch2Idx = PVOffset + 2; //!< Index 2 of saturation or mole fraction
+
+    //! Index for gas phase pressure in a solution vector
+    static const int pgIdx = pressureIdx;
+    //! Index of either the saturation of the wetting phase or the mole fraction secondary component if a phase is not present
+    static const int sOrX1Idx = switch1Idx;
+    //! Index of either the saturation of the nonwetting phase or the mole fraction secondary component if a phase is not present
+    static const int sOrX2Idx = switch2Idx;
+
+    // equation indices
+    static const int conti0EqIdx = PVOffset    + wCompIdx; //!< Index of the mass conservation equation for the water component
+    static const int conti1EqIdx = conti0EqIdx + nCompIdx; //!< Index of the mass conservation equation for the contaminant component
+    static const int conti2EqIdx = conti0EqIdx + gCompIdx; //!< Index of the mass conservation equation for the gas component
+
+    static const int contiWEqIdx = conti0EqIdx + wCompIdx; //!< index of the mass conservation equation for the water component
+    static const int contiNEqIdx = conti0EqIdx + nCompIdx; //!< index of the mass conservation equation for the contaminant component
+    static const int contiGEqIdx = conti0EqIdx + gCompIdx; //!< index of the mass conservation equation for the air component
+};
+
+}
+
+#endif
diff --git a/dumux/porousmediumflow/3p3c/implicit/localresidual.hh b/dumux/porousmediumflow/3p3c/implicit/localresidual.hh
new file mode 100644
index 0000000000..79014d6c22
--- /dev/null
+++ b/dumux/porousmediumflow/3p3c/implicit/localresidual.hh
@@ -0,0 +1,238 @@
+// -*- 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/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ *
+ * \brief Element-wise calculation of the Jacobian matrix for problems
+ *        using the three-phase three-component fully implicit model.
+ */
+#ifndef DUMUX_3P3C_LOCAL_RESIDUAL_HH
+#define DUMUX_3P3C_LOCAL_RESIDUAL_HH
+
+#include "properties.hh"
+
+namespace Dumux
+{
+/*!
+ * \ingroup ThreePThreeCModel
+ * \ingroup ImplicitLocalResidual
+ * \brief Element-wise calculation of the Jacobian matrix for problems
+ *        using the three-phase three-component fully implicit model.
+ *
+ * This class is used to fill the gaps in BoxLocalResidual for the 3P3C flow.
+ */
+template<class TypeTag>
+class ThreePThreeCLocalResidual: public GET_PROP_TYPE(TypeTag, BaseLocalResidual)
+{
+protected:
+    typedef typename GET_PROP_TYPE(TypeTag, LocalResidual) Implementation;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+
+    enum {
+        numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
+        numComponents = GET_PROP_VALUE(TypeTag, NumComponents),
+
+        conti0EqIdx = Indices::conti0EqIdx,//!< Index of the mass conservation equation for the water component
+        conti1EqIdx = Indices::conti1EqIdx,//!< Index of the mass conservation equation for the contaminant component
+        conti2EqIdx = Indices::conti2EqIdx,//!< Index of the mass conservation equation for the gas component
+
+        wPhaseIdx = Indices::wPhaseIdx,
+        nPhaseIdx = Indices::nPhaseIdx,
+        gPhaseIdx = Indices::gPhaseIdx,
+
+        wCompIdx = Indices::wCompIdx,
+        nCompIdx = Indices::nCompIdx,
+        gCompIdx = Indices::gCompIdx
+    };
+
+    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, FluxVariables) FluxVariables;
+
+public:
+    /*!
+     * \brief Evaluate the amount of all conservation quantities
+     *        (e.g. phase mass) within a sub-control volume.
+     *
+     * The result should be averaged over the volume (e.g. phase mass
+     * inside a sub control volume divided by the volume)
+     *
+     *  \param storage The mass of the component within the sub-control volume
+     *  \param scvIdx The SCV (sub-control-volume) index
+     *  \param usePrevSol Evaluate function with solution of current or previous time step
+     */
+    void computeStorage(PrimaryVariables &storage, const int scvIdx, bool usePrevSol) const
+    {
+        // 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 &elemVolVars =
+            usePrevSol
+            ? this->prevVolVars_()
+            : this->curVolVars_();
+        const VolumeVariables &volVars = elemVolVars[scvIdx];
+
+        // compute storage term of all components within all phases
+        storage = 0;
+        for (int compIdx = 0; compIdx < numComponents; ++compIdx)
+        {
+            for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
+            {
+                storage[conti0EqIdx + compIdx] +=
+                    volVars.porosity()
+                    * volVars.saturation(phaseIdx)
+                    * volVars.molarDensity(phaseIdx)
+                    * volVars.moleFraction(phaseIdx, compIdx);
+            }
+        }
+    }
+
+    /*!
+     * \brief Evaluates the total flux of all conservation quantities
+     *        over a face of a sub-control volume.
+     *
+     * \param flux The flux over the SCV (sub-control-volume) face for each component
+     * \param fIdx The index of the SCV face
+     * \param onBoundary A boolean variable to specify whether the flux variables
+     *        are calculated for interior SCV faces or boundary faces, default=false
+     */
+    void computeFlux(PrimaryVariables &flux, const int fIdx, const bool onBoundary=false) const
+    {
+        FluxVariables fluxVars(this->problem_(),
+                           this->element_(),
+                           this->fvGeometry_(),
+                           fIdx,
+                           this->curVolVars_(),
+                           onBoundary);
+
+        flux = 0;
+        asImp_()->computeAdvectiveFlux(flux, fluxVars);
+        asImp_()->computeDiffusiveFlux(flux, fluxVars);
+    }
+
+    /*!
+     * \brief Evaluates the advective mass flux of all components over
+     *        a face of a subcontrol volume.
+     *
+     * \param flux The advective flux over the sub-control-volume face for each component
+     * \param fluxVars The flux variables at the current SCV
+     */
+
+    void computeAdvectiveFlux(PrimaryVariables &flux, const FluxVariables &fluxVars) const
+    {
+        Scalar massUpwindWeight = GET_PARAM_FROM_GROUP(TypeTag, Scalar, Implicit, MassUpwindWeight);
+
+        ////////
+        // advective fluxes of all components in all phases
+        ////////
+        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
+        {
+            // data attached to upstream and the downstream vertices
+            // of the current phase
+            const VolumeVariables &up = this->curVolVars_(fluxVars.upstreamIdx(phaseIdx));
+            const VolumeVariables &dn = this->curVolVars_(fluxVars.downstreamIdx(phaseIdx));
+
+            for (int compIdx = 0; compIdx < numComponents; ++compIdx)
+            {
+                // add advective flux of current component in current
+                // phase
+                // if alpha > 0 and alpha < 1 then both upstream and downstream
+                // nodes need their contribution
+                // if alpha == 1 (which is mostly the case) then, the downstream
+                // node is not evaluated
+                int eqIdx = conti0EqIdx + compIdx;
+                flux[eqIdx] += fluxVars.volumeFlux(phaseIdx)
+                    * (massUpwindWeight
+                       * up.molarDensity(phaseIdx)
+                       * up.moleFraction(phaseIdx, compIdx)
+                       +
+                       (1.0 - massUpwindWeight)
+                       * dn.molarDensity(phaseIdx)
+                       * dn.moleFraction(phaseIdx, compIdx));
+            }
+        }
+    }
+
+    /*!
+     * \brief Adds the diffusive mass flux of all components over
+     *        a face of a subcontrol volume.
+     *
+     * \param flux The diffusive flux over the sub-control-volume face for each component
+     * \param fluxVars The flux variables at the current SCV
+     */
+
+    void computeDiffusiveFlux(PrimaryVariables &flux, const FluxVariables &fluxVars) const
+    {
+        // TODO: reference!?  Dune::FieldMatrix<Scalar, numPhases, numComponents> averagedPorousDiffCoeffMatrix = fluxVars.porousDiffCoeff();
+        // add diffusive flux of gas component in liquid phase
+        Scalar tmp = - fluxVars.porousDiffCoeff()[wPhaseIdx][gCompIdx] * fluxVars.molarDensity(wPhaseIdx);
+        tmp *= (fluxVars.moleFractionCompGGrad(wPhaseIdx) * fluxVars.face().normal);
+        Scalar jGW = tmp;
+
+        tmp = - fluxVars.porousDiffCoeff()[wPhaseIdx][nCompIdx] * fluxVars.molarDensity(wPhaseIdx);
+        tmp *= (fluxVars.moleFractionCompNGrad(wPhaseIdx) * fluxVars.face().normal);
+        Scalar jNW = tmp;
+
+        Scalar jWW = -(jGW+jNW);
+
+        tmp = - fluxVars.porousDiffCoeff()[gPhaseIdx][wCompIdx] * fluxVars.molarDensity(gPhaseIdx);
+        tmp *= (fluxVars.moleFractionCompWGrad(gPhaseIdx) * fluxVars.face().normal);
+        Scalar jWG = tmp;
+
+        tmp = - fluxVars.porousDiffCoeff()[gPhaseIdx][nCompIdx] * fluxVars.molarDensity(gPhaseIdx);
+        tmp *= (fluxVars.moleFractionCompNGrad(gPhaseIdx) * fluxVars.face().normal);
+        Scalar jNG = tmp;
+
+        Scalar jGG = -(jWG+jNG);
+
+        tmp = - fluxVars.porousDiffCoeff()[nPhaseIdx][wCompIdx] * fluxVars.molarDensity(nPhaseIdx);
+        tmp *= (fluxVars.moleFractionCompWGrad(nPhaseIdx) * fluxVars.face().normal);
+        Scalar jWN = tmp;
+
+        tmp = - fluxVars.porousDiffCoeff()[nPhaseIdx][gCompIdx] * fluxVars.molarDensity(nPhaseIdx);
+        tmp *= (fluxVars.moleFractionCompGGrad(nPhaseIdx) * fluxVars.face().normal);
+        Scalar jGN = tmp;
+
+        Scalar jNN = -(jGN+jWN);
+
+        flux[conti0EqIdx] += jWW+jWG+jWN;
+        flux[conti1EqIdx] += jNW+jNG+jNN;
+        flux[conti2EqIdx] += jGW+jGG+jGN;
+    }
+
+protected:
+    Implementation *asImp_()
+    {
+        return static_cast<Implementation *> (this);
+    }
+
+    const Implementation *asImp_() const
+    {
+        return static_cast<const Implementation *> (this);
+    }
+};
+
+} // end namespace
+
+#endif
diff --git a/dumux/porousmediumflow/3p3c/implicit/model.hh b/dumux/porousmediumflow/3p3c/implicit/model.hh
new file mode 100644
index 0000000000..6801ed9d4d
--- /dev/null
+++ b/dumux/porousmediumflow/3p3c/implicit/model.hh
@@ -0,0 +1,1020 @@
+// -*- 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/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ *
+ * \brief Adaption of the fully implicit scheme to the three-phase three-component
+ *        flow model.
+ *
+ * The model is designed for simulating three fluid phases with water, gas, and
+ * a liquid contaminant (NAPL - non-aqueous phase liquid)
+ */
+#ifndef DUMUX_3P3C_MODEL_HH
+#define DUMUX_3P3C_MODEL_HH
+
+#include <dumux/porousmediumflow/implicit/velocityoutput.hh>
+#include "properties.hh"
+
+namespace Dumux
+{
+/*!
+ * \ingroup ThreePThreeCModel
+ * \brief Adaption of the fully implicit scheme to the three-phase three-component
+ *        flow model.
+ *
+ * This model implements three-phase three-component flow of three fluid phases
+ * \f$\alpha \in \{ water, gas, NAPL \}\f$ each composed of up to three components
+ * \f$\kappa \in \{ water, air, contaminant \}\f$. The standard multiphase Darcy
+ * approach is used as the equation for the conservation of momentum:
+ * \f[
+ v_\alpha = - \frac{k_{r\alpha}}{\mu_\alpha} \mathbf{K}
+ \left(\textbf{grad}\, p_\alpha - \varrho_{\alpha} \mbox{\bf g} \right)
+ * \f]
+ *
+ * By inserting this into the equations for the conservation of the
+ * components, one transport equation for each component is obtained as
+ * \f{eqnarray*}
+ && \phi \frac{\partial (\sum_\alpha \varrho_{\alpha,mol} x_\alpha^\kappa
+ S_\alpha )}{\partial t}
+ - \sum\limits_\alpha \text{div} \left\{ \frac{k_{r\alpha}}{\mu_\alpha}
+ \varrho_{\alpha,mol} x_\alpha^\kappa \mathbf{K}
+ (\textbf{grad}\, p_\alpha - \varrho_{\alpha,mass} \mbox{\bf g}) \right\}
+ \nonumber \\
+ \nonumber \\
+ && - \sum\limits_\alpha \text{div} \left\{ D_\text{pm}^\kappa \varrho_{\alpha,mol}
+ \textbf{grad} x^\kappa_{\alpha} \right\}
+ - q^\kappa = 0 \qquad \forall \kappa , \; \forall \alpha
+ \f}
+ *
+ * Note that these balance equations are molar.
+ *
+ * All equations are discretized using a vertex-centered finite volume (box)
+ * or cell-centered finite volume scheme as spatial
+ * and the implicit Euler method as time discretization.
+ *
+ * The model uses commonly applied auxiliary conditions like
+ * \f$S_w + S_n + S_g = 1\f$ for the saturations and
+ * \f$x^w_\alpha + x^a_\alpha + x^c_\alpha = 1\f$ for the mole fractions.
+ * Furthermore, the phase pressures are related to each other via
+ * capillary pressures between the fluid phases, which are functions of
+ * the saturation, e.g. according to the approach of Parker et al.
+ *
+ * The used primary variables are dependent on the locally present fluid phases.
+ * An adaptive primary variable switch is included. The phase state is stored for all nodes
+ * of the system. The following cases can be distinguished:
+ * <ul>
+ *  <li> All three phases are present: Primary variables are two saturations \f$(S_w\f$ and \f$S_n)\f$,
+ *       and a pressure, in this case \f$p_g\f$. </li>
+ *  <li> Only the water phase is present: Primary variables are now the mole fractions of air and
+ *       contaminant in the water phase \f$(x_w^a\f$ and \f$x_w^c)\f$, as well as the gas pressure, which is,
+ *       of course, in a case where only the water phase is present, just the same as the water pressure. </li>
+ *  <li> Gas and NAPL phases are present: Primary variables \f$(S_n\f$, \f$x_g^w\f$, \f$p_g)\f$. </li>
+ *  <li> Water and NAPL phases are present: Primary variables \f$(S_n\f$, \f$x_w^a\f$, \f$p_g)\f$. </li>
+ *  <li> Only gas phase is present: Primary variables \f$(x_g^w\f$, \f$x_g^c\f$, \f$p_g)\f$. </li>
+ *  <li> Water and gas phases are present: Primary variables \f$(S_w\f$, \f$x_w^g\f$, \f$p_g)\f$. </li>
+ * </ul>
+ */
+template<class TypeTag>
+class ThreePThreeCModel: public GET_PROP_TYPE(TypeTag, BaseModel)
+{
+    typedef typename GET_PROP_TYPE(TypeTag, BaseModel) ParentType;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
+
+    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
+    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) VolumeVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, ElementVolumeVariables) ElementVolumeVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector;
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+
+    enum {
+        dim = GridView::dimension,
+        dimWorld = GridView::dimensionworld,
+
+        numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
+        numComponents = GET_PROP_VALUE(TypeTag, NumComponents),
+
+        switch1Idx = Indices::switch1Idx,
+        switch2Idx = Indices::switch2Idx,
+
+
+        wPhaseIdx = Indices::wPhaseIdx,
+        nPhaseIdx = Indices::nPhaseIdx,
+        gPhaseIdx = Indices::gPhaseIdx,
+
+        wCompIdx = Indices::wCompIdx,
+        nCompIdx = Indices::nCompIdx,
+        gCompIdx = Indices::gCompIdx,
+
+        threePhases = Indices::threePhases,
+        wPhaseOnly  = Indices::wPhaseOnly,
+        gnPhaseOnly = Indices::gnPhaseOnly,
+        wnPhaseOnly = Indices::wnPhaseOnly,
+        gPhaseOnly  = Indices::gPhaseOnly,
+        wgPhaseOnly = Indices::wgPhaseOnly
+
+    };
+
+    typedef Dune::FieldVector<Scalar, dimWorld> GlobalPosition;
+    enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) };
+    enum { dofCodim = isBox ? dim : 0 };
+
+public:
+    /*!
+     * \brief Initialize the static data with the initial solution.
+     *
+     * \param problem The problem to be solved
+     */
+    void init(Problem &problem)
+    {
+        ParentType::init(problem);
+
+        staticDat_.resize(this->numDofs());
+
+        setSwitched_(false);
+
+        if (isBox)
+        {
+            for (const auto& vertex : Dune::vertices(this->gridView_()))
+            {
+                int vIdxGlobal = this->dofMapper().index(vertex);
+
+                const GlobalPosition &globalPos = vertex.geometry().corner(0);
+
+                // initialize phase presence
+                staticDat_[vIdxGlobal].phasePresence
+                    = this->problem_().initialPhasePresence(vertex, vIdxGlobal,
+                                                        globalPos);
+                staticDat_[vIdxGlobal].wasSwitched = false;
+
+                staticDat_[vIdxGlobal].oldPhasePresence
+                    = staticDat_[vIdxGlobal].phasePresence;
+            }
+        }
+        else
+        {
+            for (const auto& element : Dune::elements(this->gridView_()))
+            {
+                int eIdxGlobal = this->dofMapper().index(element);
+                const GlobalPosition &globalPos = element.geometry().center();
+
+                // initialize phase presence
+                staticDat_[eIdxGlobal].phasePresence
+                    = this->problem_().initialPhasePresence(*this->gridView_().template begin<dim> (),
+                                                            eIdxGlobal, globalPos);
+                staticDat_[eIdxGlobal].wasSwitched = false;
+
+                staticDat_[eIdxGlobal].oldPhasePresence
+                    = staticDat_[eIdxGlobal].phasePresence;
+            }
+        }
+    }
+
+    /*!
+     * \brief Compute the total storage inside one phase of all
+     *        conservation quantities.
+     *
+     * \param storage Contains the storage of each component for one phase
+     * \param phaseIdx The phase index
+     */
+    void globalPhaseStorage(PrimaryVariables &storage, const int phaseIdx)
+    {
+        storage = 0;
+
+        for (const auto& element : Dune::elements(this->gridView_())) {
+            if(element.partitionType() == Dune::InteriorEntity)
+            {
+                this->localResidual().evalPhaseStorage(element, phaseIdx);
+
+                for (unsigned int i = 0; i < this->localResidual().storageTerm().size(); ++i)
+                    storage += this->localResidual().storageTerm()[i];
+            }
+        }
+        if (this->gridView_().comm().size() > 1)
+            storage = this->gridView_().comm().sum(storage);
+    }
+
+
+    /*!
+     * \brief Called by the update() method if applying the newton
+     *        method was unsuccessful.
+     */
+    void updateFailed()
+    {
+        ParentType::updateFailed();
+
+        setSwitched_(false);
+        resetPhasePresence_();
+    };
+
+    /*!
+     * \brief Called by the problem if a time integration was
+     *        successful, post processing of the solution is done and the
+     *        result has been written to disk.
+     *
+     * This should prepare the model for the next time integration.
+     */
+    void advanceTimeLevel()
+    {
+        ParentType::advanceTimeLevel();
+
+        // update the phase state
+        updateOldPhasePresence_();
+        setSwitched_(false);
+    }
+
+    /*!
+     * \brief Return true if the primary variables were switched for
+     *        at least one vertex after the last timestep.
+     */
+    bool switched() const
+    {
+        return switchFlag_;
+    }
+
+    /*!
+     * \brief Returns the phase presence of the current or the old solution of a degree of freedom.
+     *
+     * \param dofIdxGlobal The global index of the degree of freedom
+     * \param oldSol Evaluate function with solution of current or previous time step
+     */
+    int phasePresence(int dofIdxGlobal, bool oldSol) const
+    {
+        return
+            oldSol
+            ? staticDat_[dofIdxGlobal].oldPhasePresence
+            : staticDat_[dofIdxGlobal].phasePresence;
+    }
+
+    /*!
+     * \brief Append all quantities of interest which can be derived
+     *        from the solution of the current time step to the VTK
+     *        writer.
+     *
+     * \param sol The solution vector
+     * \param writer The writer for multi-file VTK datasets
+     */
+    template<class MultiWriter>
+    void addOutputVtkFields(const SolutionVector &sol,
+                            MultiWriter &writer)
+    {
+        typedef Dune::BlockVector<Dune::FieldVector<double, 1> > ScalarField;
+        typedef Dune::BlockVector<Dune::FieldVector<double, dimWorld> > VectorField;
+
+        // get the number of degrees of freedom
+        unsigned numDofs = this->numDofs();
+
+        // create the required scalar fields
+        ScalarField *saturation[numPhases];
+        ScalarField *pressure[numPhases];
+        ScalarField *density[numPhases];
+
+        for (int phaseIdx = 0; phaseIdx < numPhases; ++ phaseIdx) {
+            saturation[phaseIdx] = writer.allocateManagedBuffer(numDofs);
+            pressure[phaseIdx] = writer.allocateManagedBuffer(numDofs);
+            density[phaseIdx] = writer.allocateManagedBuffer(numDofs);
+        }
+
+        ScalarField *phasePresence = writer.allocateManagedBuffer (numDofs);
+        ScalarField *moleFraction[numPhases][numComponents];
+        for (int i = 0; i < numPhases; ++i)
+            for (int j = 0; j < numComponents; ++j)
+                moleFraction[i][j] = writer.allocateManagedBuffer (numDofs);
+        ScalarField *temperature = writer.allocateManagedBuffer (numDofs);
+        ScalarField *poro = writer.allocateManagedBuffer(numDofs);
+        VectorField *velocityN = writer.template allocateManagedBuffer<double, dimWorld>(numDofs);
+        VectorField *velocityW = writer.template allocateManagedBuffer<double, dimWorld>(numDofs);
+        VectorField *velocityG = writer.template allocateManagedBuffer<double, dimWorld>(numDofs);
+        ImplicitVelocityOutput<TypeTag> velocityOutput(this->problem_());
+
+        if (velocityOutput.enableOutput()) // check if velocity output is demanded
+        {
+            // initialize velocity fields
+            for (unsigned int i = 0; i < numDofs; ++i)
+            {
+                (*velocityN)[i] = Scalar(0);
+                (*velocityW)[i] = Scalar(0);
+                (*velocityG)[i] = Scalar(0);
+            }
+        }
+
+        unsigned numElements = this->gridView_().size(0);
+        ScalarField *rank = writer.allocateManagedBuffer (numElements);
+
+        for (const auto& element : Dune::elements(this->gridView_()))
+        {
+            if(element.partitionType() == Dune::InteriorEntity)
+            {
+                int eIdx = this->problem_().elementMapper().index(element);
+                (*rank)[eIdx] = this->gridView_().comm().rank();
+
+                FVElementGeometry fvGeometry;
+                fvGeometry.update(this->gridView_(), element);
+
+
+                ElementVolumeVariables elemVolVars;
+                elemVolVars.update(this->problem_(),
+                                   element,
+                                   fvGeometry,
+                                   false /* oldSol? */);
+
+                for (int scvIdx = 0; scvIdx < fvGeometry.numScv; ++scvIdx)
+                {
+                    int dofIdxGlobal = this->dofMapper().subIndex(element, scvIdx, dofCodim);
+
+                    for (int phaseIdx = 0; phaseIdx < numPhases; ++ phaseIdx) {
+                        (*saturation[phaseIdx])[dofIdxGlobal] = elemVolVars[scvIdx].saturation(phaseIdx);
+                        (*pressure[phaseIdx])[dofIdxGlobal] = elemVolVars[scvIdx].pressure(phaseIdx);
+                        (*density[phaseIdx])[dofIdxGlobal] = elemVolVars[scvIdx].density(phaseIdx);
+                    }
+
+                    for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
+                        for (int compIdx = 0; compIdx < numComponents; ++compIdx) {
+                            (*moleFraction[phaseIdx][compIdx])[dofIdxGlobal] =
+                                elemVolVars[scvIdx].moleFraction(phaseIdx,
+                                                                  compIdx);
+
+                            Valgrind::CheckDefined((*moleFraction[phaseIdx][compIdx])[dofIdxGlobal]);
+                        }
+                    }
+
+                    (*poro)[dofIdxGlobal] = elemVolVars[scvIdx].porosity();
+                    (*temperature)[dofIdxGlobal] = elemVolVars[scvIdx].temperature();
+                    (*phasePresence)[dofIdxGlobal] = staticDat_[dofIdxGlobal].phasePresence;
+                }
+
+                // velocity output
+                velocityOutput.calculateVelocity(*velocityW, elemVolVars, fvGeometry, element, wPhaseIdx);
+                velocityOutput.calculateVelocity(*velocityN, elemVolVars, fvGeometry, element, nPhaseIdx);
+                velocityOutput.calculateVelocity(*velocityN, elemVolVars, fvGeometry, element, gPhaseIdx);
+            }
+        }
+
+        writer.attachDofData(*saturation[wPhaseIdx], "Sw", isBox);
+        writer.attachDofData(*saturation[nPhaseIdx], "Sn", isBox);
+        writer.attachDofData(*saturation[gPhaseIdx], "Sg", isBox);
+        writer.attachDofData(*pressure[wPhaseIdx], "pw", isBox);
+        writer.attachDofData(*pressure[nPhaseIdx], "pn", isBox);
+        writer.attachDofData(*pressure[gPhaseIdx], "pg", isBox);
+        writer.attachDofData(*density[wPhaseIdx], "rhow", isBox);
+        writer.attachDofData(*density[nPhaseIdx], "rhon", isBox);
+        writer.attachDofData(*density[gPhaseIdx], "rhog", isBox);
+
+        for (int i = 0; i < numPhases; ++i)
+        {
+            for (int j = 0; j < numComponents; ++j)
+            {
+                std::ostringstream oss;
+                oss << "x^"
+                    << FluidSystem::componentName(j)
+                    << "_"
+                    << FluidSystem::phaseName(i);
+                writer.attachDofData(*moleFraction[i][j], oss.str().c_str(), isBox);
+            }
+        }
+        writer.attachDofData(*poro, "porosity", isBox);
+        writer.attachDofData(*temperature, "temperature", isBox);
+        writer.attachDofData(*phasePresence, "phase presence", isBox);
+
+        if (velocityOutput.enableOutput()) // check if velocity output is demanded
+        {
+            writer.attachDofData(*velocityW,  "velocityW", isBox, dim);
+            writer.attachDofData(*velocityN,  "velocityN", isBox, dim);
+            writer.attachDofData(*velocityG,  "velocityG", isBox, dim);
+        }
+
+        writer.attachCellData(*rank, "process rank");
+    }
+
+    /*!
+     * \brief Write the current solution to a restart file.
+     *
+     * \param outStream The output stream of one entity for the restart file
+     * \param entity The entity, either a vertex or an element
+     */
+    template<class Entity>
+    void serializeEntity(std::ostream &outStream, const Entity &entity)
+    {
+        // write primary variables
+        ParentType::serializeEntity(outStream, entity);
+
+        int dofIdxGlobal = this->dofMapper().index(entity);
+
+        if (!outStream.good())
+            DUNE_THROW(Dune::IOError, "Could not serialize entity " << dofIdxGlobal);
+
+        outStream << staticDat_[dofIdxGlobal].phasePresence << " ";
+    }
+
+    /*!
+     * \brief Reads the current solution from a restart file.
+     *
+     * \param inStream The input stream of one entity from the restart file
+     * \param entity The entity, either a vertex or an element
+     */
+    template<class Entity>
+    void deserializeEntity(std::istream &inStream, const Entity &entity)
+    {
+        // read primary variables
+        ParentType::deserializeEntity(inStream, entity);
+
+        // read phase presence
+        int dofIdxGlobal = this->dofMapper().index(entity);
+
+        if (!inStream.good())
+            DUNE_THROW(Dune::IOError,
+                       "Could not deserialize entity " << dofIdxGlobal);
+
+        inStream >> staticDat_[dofIdxGlobal].phasePresence;
+        staticDat_[dofIdxGlobal].oldPhasePresence
+            = staticDat_[dofIdxGlobal].phasePresence;
+
+    }
+
+    /*!
+     * \brief Update the static data of all vertices in the grid.
+     *
+     * \param curGlobalSol The current global solution
+     * \param oldGlobalSol The previous global solution
+     */
+    void updateStaticData(SolutionVector &curGlobalSol,
+                          const SolutionVector &oldGlobalSol)
+    {
+        bool wasSwitched = false;
+        int succeeded;
+        try {
+
+            for (unsigned i = 0; i < staticDat_.size(); ++i)
+                staticDat_[i].visited = false;
+
+            FVElementGeometry fvGeometry;
+            static VolumeVariables volVars;
+            for (const auto& element : Dune::elements(this->gridView_()))
+            {
+                fvGeometry.update(this->gridView_(), element);
+                for (int scvIdx = 0; scvIdx < fvGeometry.numScv; ++scvIdx)
+                {
+                    int dofIdxGlobal = this->dofMapper().subIndex(element, scvIdx, dofCodim);
+
+                    if (staticDat_[dofIdxGlobal].visited)
+                        continue;
+
+                    staticDat_[dofIdxGlobal].visited = true;
+                    volVars.update(curGlobalSol[dofIdxGlobal],
+                            this->problem_(),
+                            element,
+                            fvGeometry,
+                            scvIdx,
+                            false);
+                    const GlobalPosition &globalPos = fvGeometry.subContVol[scvIdx].global;
+                    if (primaryVarSwitch_(curGlobalSol,
+                            volVars,
+                            dofIdxGlobal,
+                            globalPos))
+                    {
+                        this->jacobianAssembler().markDofRed(dofIdxGlobal);
+                        wasSwitched = true;
+                    }
+                }
+            }
+            succeeded = 1;
+        }
+        catch (Dumux::NumericalProblem &e)
+        {
+            std::cout << "\n"
+                      << "Rank " << this->problem_().gridView().comm().rank()
+                      << " caught an exception while updating the static data." << e.what()
+                      << "\n";
+            succeeded = 0;
+        }
+        //make sure that all processes succeeded. If not throw a NumericalProblem to decrease the time step size.
+        if (this->gridView_().comm().size() > 1)
+            succeeded = this->gridView_().comm().min(succeeded);
+
+        if (!succeeded) {
+                DUNE_THROW(NumericalProblem,
+                        "A process did not succeed in updating the static data.");
+            return;
+        }
+
+        // make sure that if there was a variable switch in an
+        // other partition we will also set the switch flag
+        // for our partition.
+        if (this->gridView_().comm().size() > 1)
+            wasSwitched = this->gridView_().comm().max(wasSwitched);
+
+        setSwitched_(wasSwitched);
+    }
+
+protected:
+    /*!
+     * \brief Data which is attached to each vertex and is not only
+     *        stored locally.
+     */
+    struct StaticVars
+    {
+        int phasePresence;
+        bool wasSwitched;
+
+        int oldPhasePresence;
+        bool visited;
+    };
+
+    /*!
+     * \brief Reset the current phase presence of all vertices to the old one.
+     *
+     * This is done after an update failed.
+     */
+    void resetPhasePresence_()
+    {
+        for (unsigned int i = 0; i < this->numDofs(); ++i)
+        {
+            staticDat_[i].phasePresence
+                = staticDat_[i].oldPhasePresence;
+            staticDat_[i].wasSwitched = false;
+        }
+    }
+
+    /*!
+     * \brief Set the old phase of all verts state to the current one.
+     */
+    void updateOldPhasePresence_()
+    {
+        for (unsigned int i = 0; i < this->numDofs(); ++i)
+        {
+            staticDat_[i].oldPhasePresence
+                = staticDat_[i].phasePresence;
+            staticDat_[i].wasSwitched = false;
+        }
+    }
+
+    /*!
+     * \brief Set whether there was a primary variable switch after in
+     *        the last timestep.
+     */
+    void setSwitched_(bool yesno)
+    {
+        switchFlag_ = yesno;
+    }
+
+    //  perform variable switch at a vertex; Returns true if a
+    //  variable switch was performed.
+    bool primaryVarSwitch_(SolutionVector &globalSol,
+                           const VolumeVariables &volVars,
+                           int dofIdxGlobal,
+                           const GlobalPosition &globalPos)
+    {
+        // evaluate primary variable switch
+        bool wouldSwitch = false;
+        int phasePresence = staticDat_[dofIdxGlobal].phasePresence;
+        int newPhasePresence = phasePresence;
+
+        // check if a primary var switch is necessary
+        if (phasePresence == threePhases)
+        {
+            Scalar Smin = 0;
+            if (staticDat_[dofIdxGlobal].wasSwitched)
+                Smin = -0.01;
+
+            if (volVars.saturation(gPhaseIdx) <= Smin)
+            {
+                wouldSwitch = true;
+                // gas phase disappears
+                std::cout << "Gas phase disappears at vertex " << dofIdxGlobal
+                          << ", coordinates: " << globalPos << ", sg: "
+                          << volVars.saturation(gPhaseIdx) << std::endl;
+                newPhasePresence = wnPhaseOnly;
+
+                globalSol[dofIdxGlobal][switch1Idx]
+                    = volVars.moleFraction(wPhaseIdx, gCompIdx);
+            }
+            else if (volVars.saturation(wPhaseIdx) <= Smin)
+            {
+                wouldSwitch = true;
+                // water phase disappears
+                std::cout << "Water phase disappears at vertex " << dofIdxGlobal
+                          << ", coordinates: " << globalPos << ", sw: "
+                          << volVars.saturation(wPhaseIdx) << std::endl;
+                newPhasePresence = gnPhaseOnly;
+
+                globalSol[dofIdxGlobal][switch1Idx]
+                    = volVars.moleFraction(gPhaseIdx, wCompIdx);
+            }
+            else if (volVars.saturation(nPhaseIdx) <= Smin)
+            {
+                wouldSwitch = true;
+                // NAPL phase disappears
+                std::cout << "NAPL phase disappears at vertex " << dofIdxGlobal
+                          << ", coordinates: " << globalPos << ", sn: "
+                          << volVars.saturation(nPhaseIdx) << std::endl;
+                newPhasePresence = wgPhaseOnly;
+
+                globalSol[dofIdxGlobal][switch2Idx]
+                    = volVars.moleFraction(gPhaseIdx, nCompIdx);
+            }
+        }
+        else if (phasePresence == wPhaseOnly)
+        {
+            bool gasFlag = 0;
+            bool nonwettingFlag = 0;
+            // calculate fractions of the partial pressures in the
+            // hypothetical gas phase
+            Scalar xwg = volVars.moleFraction(gPhaseIdx, wCompIdx);
+            Scalar xgg = volVars.moleFraction(gPhaseIdx, gCompIdx);
+            Scalar xng = volVars.moleFraction(gPhaseIdx, nCompIdx);
+            /* take care:
+               for xgg in case wPhaseOnly we compute xgg=henry_air*x2w
+               for xwg in case wPhaseOnly we compute xwg=pwsat
+               for xng in case wPhaseOnly we compute xng=henry_NAPL*x1w
+            */
+
+            Scalar xgMax = 1.0;
+            if (xwg + xgg + xng > xgMax)
+                wouldSwitch = true;
+            if (staticDat_[dofIdxGlobal].wasSwitched)
+                xgMax *= 1.02;
+
+            // if the sum of the mole fractions would be larger than
+            // 100%, gas phase appears
+            if (xwg + xgg + xng > xgMax)
+            {
+                // gas phase appears
+                std::cout << "gas phase appears at vertex " << dofIdxGlobal
+                          << ", coordinates: " << globalPos << ", xwg + xgg + xng: "
+                          << xwg + xgg + xng << std::endl;
+                gasFlag = 1;
+            }
+
+            // calculate fractions in the hypothetical NAPL phase
+            Scalar xnn = volVars.moleFraction(nPhaseIdx, nCompIdx);
+            /* take care:
+               for xnn in case wPhaseOnly we compute xnn=henry_mesitylene*x1w,
+               where a hypothetical gas pressure is assumed for the Henry
+               x0n is set to NULL  (all NAPL phase is dirty)
+               x2n is set to NULL  (all NAPL phase is dirty)
+            */
+
+            Scalar xnMax = 1.0;
+            if (xnn > xnMax)
+                wouldSwitch = true;
+            if (staticDat_[dofIdxGlobal].wasSwitched)
+                xnMax *= 1.02;
+
+            // if the sum of the hypothetical mole fractions would be larger than
+            // 100%, NAPL phase appears
+            if (xnn > xnMax)
+            {
+                // NAPL phase appears
+                std::cout << "NAPL phase appears at vertex " << dofIdxGlobal
+                          << ", coordinates: " << globalPos << ", xnn: "
+                          << xnn << std::endl;
+                nonwettingFlag = 1;
+            }
+
+            if ((gasFlag == 1) && (nonwettingFlag == 0))
+            {
+                newPhasePresence = wgPhaseOnly;
+                globalSol[dofIdxGlobal][switch1Idx] = 0.9999;
+                globalSol[dofIdxGlobal][switch2Idx] = 0.0001;
+            }
+            else if ((gasFlag == 1) && (nonwettingFlag == 1))
+            {
+                newPhasePresence = threePhases;
+                globalSol[dofIdxGlobal][switch1Idx] = 0.9999;
+                globalSol[dofIdxGlobal][switch2Idx] = 0.0001;
+            }
+            else if ((gasFlag == 0) && (nonwettingFlag == 1))
+            {
+                newPhasePresence = wnPhaseOnly;
+                globalSol[dofIdxGlobal][switch1Idx]
+                    = volVars.moleFraction(wPhaseIdx, gCompIdx);
+                globalSol[dofIdxGlobal][switch2Idx] = 0.0001;
+            }
+        }
+        else if (phasePresence == gnPhaseOnly)
+        {
+            bool nonwettingFlag = 0;
+            bool wettingFlag = 0;
+
+            Scalar Smin = 0.0;
+            if (staticDat_[dofIdxGlobal].wasSwitched)
+                Smin = -0.01;
+
+            if (volVars.saturation(nPhaseIdx) <= Smin)
+            {
+                wouldSwitch = true;
+                // NAPL phase disappears
+                std::cout << "NAPL phase disappears at vertex " << dofIdxGlobal
+                          << ", coordinates: " << globalPos << ", sn: "
+                          << volVars.saturation(nPhaseIdx) << std::endl;
+                nonwettingFlag = 1;
+            }
+
+
+            // calculate fractions of the hypothetical water phase
+            Scalar xww = volVars.moleFraction(wPhaseIdx, wCompIdx);
+            /*
+              take care:, xww, if no water is present, then take xww=xwg*pg/pwsat .
+              If this is larger than 1, then water appears
+            */
+            Scalar xwMax = 1.0;
+            if (xww > xwMax)
+                wouldSwitch = true;
+            if (staticDat_[dofIdxGlobal].wasSwitched)
+                xwMax *= 1.02;
+
+            // if the sum of the mole fractions would be larger than
+            // 100%, gas phase appears
+            if (xww > xwMax)
+            {
+                // water phase appears
+                std::cout << "water phase appears at vertex " << dofIdxGlobal
+                          << ", coordinates: " << globalPos << ", xww=xwg*pg/pwsat : "
+                          << xww << std::endl;
+                wettingFlag = 1;
+            }
+
+            if ((wettingFlag == 1) && (nonwettingFlag == 0))
+            {
+                newPhasePresence = threePhases;
+                globalSol[dofIdxGlobal][switch1Idx] = 0.0001;
+                globalSol[dofIdxGlobal][switch2Idx] = volVars.saturation(nPhaseIdx);
+            }
+            else if ((wettingFlag == 1) && (nonwettingFlag == 1))
+            {
+                newPhasePresence = wgPhaseOnly;
+                globalSol[dofIdxGlobal][switch1Idx] = 0.0001;
+                globalSol[dofIdxGlobal][switch2Idx]
+                    = volVars.moleFraction(gPhaseIdx, nCompIdx);
+            }
+            else if ((wettingFlag == 0) && (nonwettingFlag == 1))
+            {
+                newPhasePresence = gPhaseOnly;
+                globalSol[dofIdxGlobal][switch1Idx]
+                    = volVars.moleFraction(gPhaseIdx, wCompIdx);
+                globalSol[dofIdxGlobal][switch2Idx]
+                    = volVars.moleFraction(gPhaseIdx, nCompIdx);
+            }
+        }
+        else if (phasePresence == wnPhaseOnly)
+        {
+            bool nonwettingFlag = 0;
+            bool gasFlag = 0;
+
+            Scalar Smin = 0.0;
+            if (staticDat_[dofIdxGlobal].wasSwitched)
+                Smin = -0.01;
+
+            if (volVars.saturation(nPhaseIdx) <= Smin)
+            {
+                wouldSwitch = true;
+                // NAPL phase disappears
+                std::cout << "NAPL phase disappears at vertex " << dofIdxGlobal
+                          << ", coordinates: " << globalPos << ", sn: "
+                          << volVars.saturation(nPhaseIdx) << std::endl;
+                nonwettingFlag = 1;
+            }
+
+            // calculate fractions of the partial pressures in the
+            // hypothetical gas phase
+            Scalar xwg = volVars.moleFraction(gPhaseIdx, wCompIdx);
+            Scalar xgg = volVars.moleFraction(gPhaseIdx, gCompIdx);
+            Scalar xng = volVars.moleFraction(gPhaseIdx, nCompIdx);
+            /* take care:
+               for xgg in case wPhaseOnly we compute xgg=henry_air*x2w
+               for xwg in case wPhaseOnly we compute xwg=pwsat
+               for xng in case wPhaseOnly we compute xng=henry_NAPL*x1w
+            */
+            Scalar xgMax = 1.0;
+            if (xwg + xgg + xng > xgMax)
+                wouldSwitch = true;
+            if (staticDat_[dofIdxGlobal].wasSwitched)
+                xgMax *= 1.02;
+
+            // if the sum of the mole fractions would be larger than
+            // 100%, gas phase appears
+            if (xwg + xgg + xng > xgMax)
+            {
+                // gas phase appears
+                std::cout << "gas phase appears at vertex " << dofIdxGlobal
+                          << ", coordinates: " << globalPos << ", xwg + xgg + xng: "
+                          << xwg + xgg + xng << std::endl;
+                gasFlag = 1;
+            }
+
+            if ((gasFlag == 1) && (nonwettingFlag == 0))
+            {
+                newPhasePresence = threePhases;
+                globalSol[dofIdxGlobal][switch1Idx] = volVars.saturation(wPhaseIdx);
+                globalSol[dofIdxGlobal][switch2Idx] = volVars.saturation(nPhaseIdx);
+            }
+            else if ((gasFlag == 1) && (nonwettingFlag == 1))
+            {
+                newPhasePresence = wgPhaseOnly;
+                globalSol[dofIdxGlobal][switch1Idx] = volVars.saturation(wPhaseIdx);
+                globalSol[dofIdxGlobal][switch2Idx]
+                    = volVars.moleFraction(gPhaseIdx, nCompIdx);
+            }
+            else if ((gasFlag == 0) && (nonwettingFlag == 1))
+            {
+                newPhasePresence = wPhaseOnly;
+                globalSol[dofIdxGlobal][switch1Idx]
+                    = volVars.moleFraction(wPhaseIdx, gCompIdx);
+                globalSol[dofIdxGlobal][switch2Idx]
+                    = volVars.moleFraction(wPhaseIdx, nCompIdx);
+            }
+        }
+        else if (phasePresence == gPhaseOnly)
+        {
+            bool nonwettingFlag = 0;
+            bool wettingFlag = 0;
+
+            // calculate fractions in the hypothetical NAPL phase
+            Scalar xnn = volVars.moleFraction(nPhaseIdx, nCompIdx);
+            /*
+              take care:, xnn, if no NAPL phase is there, take xnn=xng*pg/pcsat
+              if this is larger than 1, then NAPL appears
+            */
+
+            Scalar xnMax = 1.0;
+            if (xnn > xnMax)
+                wouldSwitch = true;
+            if (staticDat_[dofIdxGlobal].wasSwitched)
+                xnMax *= 1.02;
+
+            // if the sum of the hypothetical mole fraction would be larger than
+            // 100%, NAPL phase appears
+            if (xnn > xnMax)
+            {
+                // NAPL phase appears
+                std::cout << "NAPL phase appears at vertex " << dofIdxGlobal
+                          << ", coordinates: " << globalPos << ", xnn: "
+                          << xnn << std::endl;
+                nonwettingFlag = 1;
+            }
+            // calculate fractions of the hypothetical water phase
+            Scalar xww = volVars.moleFraction(wPhaseIdx, wCompIdx);
+            /*
+              take care:, xww, if no water is present, then take xww=xwg*pg/pwsat .
+              If this is larger than 1, then water appears
+            */
+            Scalar xwMax = 1.0;
+            if (xww > xwMax)
+                wouldSwitch = true;
+            if (staticDat_[dofIdxGlobal].wasSwitched)
+                xwMax *= 1.02;
+
+            // if the sum of the mole fractions would be larger than
+            // 100%, gas phase appears
+            if (xww > xwMax)
+            {
+                // water phase appears
+                std::cout << "water phase appears at vertex " << dofIdxGlobal
+                          << ", coordinates: " << globalPos << ", xww=xwg*pg/pwsat : "
+                          << xww << std::endl;
+                wettingFlag = 1;
+            }
+            if ((wettingFlag == 1) && (nonwettingFlag == 0))
+            {
+                newPhasePresence = wgPhaseOnly;
+                globalSol[dofIdxGlobal][switch1Idx] = 0.0001;
+                globalSol[dofIdxGlobal][switch2Idx]
+                    = volVars.moleFraction(gPhaseIdx, nCompIdx);
+            }
+            else if ((wettingFlag == 1) && (nonwettingFlag == 1))
+            {
+                newPhasePresence = threePhases;
+                globalSol[dofIdxGlobal][switch1Idx] = 0.0001;
+                globalSol[dofIdxGlobal][switch2Idx] = 0.0001;
+            }
+            else if ((wettingFlag == 0) && (nonwettingFlag == 1))
+            {
+                newPhasePresence = gnPhaseOnly;
+                globalSol[dofIdxGlobal][switch1Idx]
+                    = volVars.moleFraction(gPhaseIdx, wCompIdx);
+                globalSol[dofIdxGlobal][switch2Idx] = 0.0001;
+            }
+        }
+        else if (phasePresence == wgPhaseOnly)
+        {
+            bool nonwettingFlag = 0;
+            bool gasFlag = 0;
+            bool wettingFlag = 0;
+
+            // get the fractions in the hypothetical NAPL phase
+            Scalar xnn = volVars.moleFraction(nPhaseIdx, nCompIdx);
+
+            // take care: if the NAPL phase is not present, take
+            // xnn=xng*pg/pcsat if this is larger than 1, then NAPL
+            // appears
+            Scalar xnMax = 1.0;
+            if (xnn > xnMax)
+                wouldSwitch = true;
+            if (staticDat_[dofIdxGlobal].wasSwitched)
+                xnMax *= 1.02;
+
+            // if the sum of the hypothetical mole fraction would be larger than
+            // 100%, NAPL phase appears
+            if (xnn > xnMax)
+            {
+                // NAPL phase appears
+                std::cout << "NAPL phase appears at vertex " << dofIdxGlobal
+                          << ", coordinates: " << globalPos << ", xnn: "
+                          << xnn << std::endl;
+                nonwettingFlag = 1;
+            }
+
+            Scalar Smin = -1.e-6;
+            if (staticDat_[dofIdxGlobal].wasSwitched)
+                Smin = -0.01;
+
+            if (volVars.saturation(gPhaseIdx) <= Smin)
+            {
+                wouldSwitch = true;
+                // gas phase disappears
+                std::cout << "Gas phase disappears at vertex " << dofIdxGlobal
+                          << ", coordinates: " << globalPos << ", sg: "
+                          << volVars.saturation(gPhaseIdx) << std::endl;
+                gasFlag = 1;
+            }
+
+            Smin = 0.0;
+            if (staticDat_[dofIdxGlobal].wasSwitched)
+                Smin = -0.01;
+
+            if (volVars.saturation(wPhaseIdx) <= Smin)
+            {
+                wouldSwitch = true;
+                // gas phase disappears
+                std::cout << "Water phase disappears at vertex " << dofIdxGlobal
+                          << ", coordinates: " << globalPos << ", sw: "
+                          << volVars.saturation(wPhaseIdx) << std::endl;
+                wettingFlag = 1;
+            }
+
+            if ((gasFlag == 0) && (nonwettingFlag == 1) && (wettingFlag == 1))
+            {
+                newPhasePresence = gnPhaseOnly;
+                globalSol[dofIdxGlobal][switch1Idx]
+                    = volVars.moleFraction(gPhaseIdx, wCompIdx);
+                globalSol[dofIdxGlobal][switch2Idx] = 0.0001;
+            }
+            else if ((gasFlag == 0) && (nonwettingFlag == 1) && (wettingFlag == 0))
+            {
+                newPhasePresence = threePhases;
+                globalSol[dofIdxGlobal][switch1Idx] = volVars.saturation(wPhaseIdx);
+                globalSol[dofIdxGlobal][switch2Idx] = 0.0;
+            }
+            else if ((gasFlag == 1) && (nonwettingFlag == 0) && (wettingFlag == 0))
+            {
+                newPhasePresence = wPhaseOnly;
+                globalSol[dofIdxGlobal][switch1Idx]
+                    = volVars.moleFraction(wPhaseIdx, gCompIdx);
+                globalSol[dofIdxGlobal][switch2Idx]
+                    = volVars.moleFraction(wPhaseIdx, nCompIdx);
+            }
+            else if ((gasFlag == 0) && (nonwettingFlag == 0) && (wettingFlag == 1))
+            {
+                newPhasePresence = gPhaseOnly;
+                globalSol[dofIdxGlobal][switch1Idx]
+                    = volVars.moleFraction(gPhaseIdx, wCompIdx);
+                globalSol[dofIdxGlobal][switch2Idx]
+                    = volVars.moleFraction(gPhaseIdx, nCompIdx);
+            }
+        }
+
+        staticDat_[dofIdxGlobal].phasePresence = newPhasePresence;
+        staticDat_[dofIdxGlobal].wasSwitched = wouldSwitch;
+        return phasePresence != newPhasePresence;
+    }
+
+    // parameters given in constructor
+    std::vector<StaticVars> staticDat_;
+    bool switchFlag_;
+};
+
+}
+
+#include "propertydefaults.hh"
+
+#endif
diff --git a/dumux/porousmediumflow/3p3c/implicit/newtoncontroller.hh b/dumux/porousmediumflow/3p3c/implicit/newtoncontroller.hh
new file mode 100644
index 0000000000..053b2cb01f
--- /dev/null
+++ b/dumux/porousmediumflow/3p3c/implicit/newtoncontroller.hh
@@ -0,0 +1,86 @@
+// -*- 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/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ * \brief A three-phase three-component specific controller for the newton solver.
+ *
+ * This controller 'knows' what a 'physically meaningful' solution is
+ * which allows the newton method to abort quicker if the solution is
+ * way out of bounds.
+ */
+#ifndef DUMUX_3P3C_NEWTON_CONTROLLER_HH
+#define DUMUX_3P3C_NEWTON_CONTROLLER_HH
+
+#include "properties.hh"
+
+#include <dumux/nonlinear/newtoncontroller.hh>
+
+namespace Dumux {
+/*!
+ * \ingroup Newton
+ * \ingroup ThreePThreeCModel
+ * \brief A three-phase three-component specific controller for the newton solver.
+ *
+ * This controller 'knows' what a 'physically meaningful' solution is
+ * which allows the newton method to abort quicker if the solution is
+ * way out of bounds.
+ */
+template <class TypeTag>
+class ThreePThreeCNewtonController : public NewtonController<TypeTag>
+{
+    typedef NewtonController<TypeTag> ParentType;
+    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
+    typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector;
+
+public:
+    ThreePThreeCNewtonController(const Problem &problem)
+        : ParentType(problem)
+    {};
+
+
+    /*!
+     * \brief Called after each Newton update
+     *
+     * \param uCurrentIter The current global solution vector
+     * \param uLastIter The previous global solution vector
+     */
+    void newtonEndStep(SolutionVector &uCurrentIter,
+                       const SolutionVector &uLastIter)
+    {
+        // call the method of the base class
+        this->method().model().updateStaticData(uCurrentIter, uLastIter);
+        ParentType::newtonEndStep(uCurrentIter, uLastIter);
+    }
+
+
+    /*!
+     * \brief Returns true if the current solution can be considered to
+     *        be accurate enough
+     */
+    bool newtonConverged()
+    {
+        if (this->method().model().switched())
+            return false;
+
+        return ParentType::newtonConverged();
+    };
+};
+}
+
+#endif
diff --git a/dumux/porousmediumflow/3p3c/implicit/properties.hh b/dumux/porousmediumflow/3p3c/implicit/properties.hh
new file mode 100644
index 0000000000..52a2762e8c
--- /dev/null
+++ b/dumux/porousmediumflow/3p3c/implicit/properties.hh
@@ -0,0 +1,82 @@
+// -*- 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/>.   *
+ *****************************************************************************/
+/*!
+ * \ingroup Properties
+ * \ingroup ImplicitProperties
+ * \ingroup ThreePThreeCModel
+ */
+/*!
+ * \file
+ *
+ * \brief Defines the properties required for the three-phase three-component
+ *        fully implicit model.
+ */
+#ifndef DUMUX_3P3C_PROPERTIES_HH
+#define DUMUX_3P3C_PROPERTIES_HH
+
+#include <dumux/implicit/box/properties.hh>
+#include <dumux/implicit/cellcentered/properties.hh>
+#include <dumux/porousmediumflow/nonisothermal/implicit/properties.hh>
+
+
+namespace Dumux
+{
+
+namespace Properties
+{
+//////////////////////////////////////////////////////////////////
+// Type tags
+//////////////////////////////////////////////////////////////////
+
+//! The type tags for the implicit three-phase three-component problems
+NEW_TYPE_TAG(ThreePThreeC);
+NEW_TYPE_TAG(BoxThreePThreeC, INHERITS_FROM(BoxModel, ThreePThreeC));
+NEW_TYPE_TAG(CCThreePThreeC, INHERITS_FROM(CCModel, ThreePThreeC));
+
+//! The type tags for the corresponding non-isothermal problems
+NEW_TYPE_TAG(ThreePThreeCNI, INHERITS_FROM(ThreePThreeC, NonIsothermal));
+NEW_TYPE_TAG(BoxThreePThreeCNI, INHERITS_FROM(BoxModel, ThreePThreeCNI));
+NEW_TYPE_TAG(CCThreePThreeCNI, INHERITS_FROM(CCModel, ThreePThreeCNI));
+
+//////////////////////////////////////////////////////////////////
+// Property tags
+//////////////////////////////////////////////////////////////////
+
+NEW_PROP_TAG(NumPhases);   //!< Number of fluid phases in the system
+NEW_PROP_TAG(NumComponents); //!< Number of fluid components in the system
+NEW_PROP_TAG(Indices); //!< Enumerations for the model
+NEW_PROP_TAG(SpatialParams); //!< The type of the spatial parameters
+NEW_PROP_TAG(FluidSystem); //!< Type of the multi-component relations
+NEW_PROP_TAG(FluidState); //!< Type of the fluid state to be used
+
+NEW_PROP_TAG(MaterialLaw);   //!< The material law which ought to be used (extracted from the spatial parameters)
+NEW_PROP_TAG(MaterialLawParams); //!< The parameters of the material law (extracted from the spatial parameters)
+NEW_PROP_TAG(EffectiveDiffusivityModel); //!< The employed model for the computation of the effective diffusivity
+
+NEW_PROP_TAG(ProblemEnableGravity); //!< Returns whether gravity is considered in the problem
+NEW_PROP_TAG(ImplicitMassUpwindWeight); //!< The value of the upwind parameter for the mobility
+NEW_PROP_TAG(ImplicitMobilityUpwindWeight); //!< Weight for the upwind mobility in the velocity calculation
+NEW_PROP_TAG(UseConstraintSolver); //!< Determines whether a constraint solver should be used explicitly
+NEW_PROP_TAG(BaseFluxVariables); //! The base flux variables
+NEW_PROP_TAG(SpatialParamsForchCoeff); //!< Property for the forchheimer coefficient
+NEW_PROP_TAG(VtkAddVelocity); //!< Returns whether velocity vectors are written into the vtk output
+}
+}
+
+#endif
diff --git a/dumux/porousmediumflow/3p3c/implicit/propertydefaults.hh b/dumux/porousmediumflow/3p3c/implicit/propertydefaults.hh
new file mode 100644
index 0000000000..aff1b567da
--- /dev/null
+++ b/dumux/porousmediumflow/3p3c/implicit/propertydefaults.hh
@@ -0,0 +1,210 @@
+// -*- 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/>.   *
+ *****************************************************************************/
+/*!
+ * \ingroup Properties
+ * \ingroup ImplicitProperties
+ * \ingroup ThreePThreeCModel
+ * \file
+ *
+ * \brief Defines default values for most properties required by the
+ *        three-phase three-component fully implicit model.
+ */
+#ifndef DUMUX_3P3C_PROPERTY_DEFAULTS_HH
+#define DUMUX_3P3C_PROPERTY_DEFAULTS_HH
+
+#include "indices.hh"
+
+#include "model.hh"
+#include "fluxvariables.hh"
+#include "volumevariables.hh"
+#include "properties.hh"
+#include "newtoncontroller.hh"
+#include "localresidual.hh"
+
+#include <dumux/porousmediumflow/nonisothermal/implicit/propertydefaults.hh>
+#include <dumux/material/fluidmatrixinteractions/diffusivitymillingtonquirk.hh>
+#include <dumux/porousmediumflow/implicit/darcyfluxvariables.hh>
+#include <dumux/material/spatialparams/implicitspatialparams.hh>
+#include <dumux/material/fluidmatrixinteractions/3p/thermalconductivitysomerton3p.hh>
+
+namespace Dumux
+{
+
+namespace Properties {
+//////////////////////////////////////////////////////////////////
+// Property values
+//////////////////////////////////////////////////////////////////
+
+/*!
+ * \brief Set the property for the number of components.
+ *
+ * We just forward the number from the fluid system and use an static
+ * assert to make sure it is 3.
+ */
+SET_PROP(ThreePThreeC, NumComponents)
+{
+ private:
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+
+ public:
+    static const int value = FluidSystem::numComponents;
+
+    static_assert(value == 3,
+                  "Only fluid systems with 3 components are supported by the 3p3c model!");
+};
+
+/*!
+ * \brief Set the property for the number of fluid phases.
+ *
+ * We just forward the number from the fluid system and use an static
+ * assert to make sure it is 3.
+ */
+SET_PROP(ThreePThreeC, NumPhases)
+{
+ private:
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+
+ public:
+    static const int value = FluidSystem::numPhases;
+    static_assert(value == 3,
+                  "Only fluid systems with 3 phases are supported by the 3p3c model!");
+};
+
+/*!
+ * \brief The fluid state which is used by the volume variables to
+ *        store the thermodynamic state. This should be chosen
+ *        appropriately for the model ((non-)isothermal, equilibrium, ...).
+ *        This can be done in the problem.
+ */
+SET_PROP(ThreePThreeC, FluidState){
+    private:
+        typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+        typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+    public:
+        typedef Dumux::CompositionalFluidState<Scalar, FluidSystem> type;
+};
+
+SET_INT_PROP(ThreePThreeC, NumEq, 3); //!< set the number of equations to 2
+
+/*!
+ * \brief Set the property for the material parameters by extracting
+ *        it from the material law.
+ */
+SET_TYPE_PROP(ThreePThreeC, MaterialLawParams, typename GET_PROP_TYPE(TypeTag, MaterialLaw)::Params);
+
+//! The local residual function of the conservation equations
+SET_TYPE_PROP(ThreePThreeC, LocalResidual, ThreePThreeCLocalResidual<TypeTag>);
+
+//! Use the 3p3c specific newton controller for the 3p3c model
+SET_TYPE_PROP(ThreePThreeC, NewtonController, ThreePThreeCNewtonController<TypeTag>);
+
+//! the Model property
+SET_TYPE_PROP(ThreePThreeC, Model, ThreePThreeCModel<TypeTag>);
+
+//! the VolumeVariables property
+SET_TYPE_PROP(ThreePThreeC, VolumeVariables, ThreePThreeCVolumeVariables<TypeTag>);
+
+//! the FluxVariables property
+SET_TYPE_PROP(ThreePThreeC, FluxVariables, ThreePThreeCFluxVariables<TypeTag>);
+
+//! define the base flux variables to realize Darcy flow
+SET_TYPE_PROP(ThreePThreeC, BaseFluxVariables, ImplicitDarcyFluxVariables<TypeTag>);
+
+//! the upwind factor for the mobility.
+SET_SCALAR_PROP(ThreePThreeC, ImplicitMassUpwindWeight, 1.0);
+
+//! set default mobility upwind weight to 1.0, i.e. fully upwind
+SET_SCALAR_PROP(ThreePThreeC, ImplicitMobilityUpwindWeight, 1.0);
+
+//! Determines whether a constraint solver should be used explicitly
+SET_BOOL_PROP(ThreePThreeC, UseConstraintSolver, false);
+
+//! The indices required by the isothermal 3p3c model
+SET_TYPE_PROP(ThreePThreeC, Indices, ThreePThreeCIndices<TypeTag, /*PVOffset=*/0>);
+
+//! The spatial parameters to be employed.
+//! Use ImplicitSpatialParams by default.
+SET_TYPE_PROP(ThreePThreeC, SpatialParams, ImplicitSpatialParams<TypeTag>);
+
+//! The model after Millington (1961) is used for the effective diffusivity
+SET_PROP(ThreePThreeC, EffectiveDiffusivityModel)
+{ private :
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+ public:
+    typedef DiffusivityMillingtonQuirk<Scalar> type;
+};
+
+// disable velocity output by default
+SET_BOOL_PROP(ThreePThreeC, VtkAddVelocity, false);
+
+// enable gravity by default
+SET_BOOL_PROP(ThreePThreeC, ProblemEnableGravity, true);
+
+//! default value for the forchheimer coefficient
+// Source: Ward, J.C. 1964 Turbulent flow in porous media. ASCE J. Hydraul. Div 90.
+//        Actually the Forchheimer coefficient is also a function of the dimensions of the
+//        porous medium. Taking it as a constant is only a first approximation
+//        (Nield, Bejan, Convection in porous media, 2006, p. 10)
+SET_SCALAR_PROP(BoxModel, SpatialParamsForchCoeff, 0.55);
+
+//! Somerton is used as default model to compute the effective thermal heat conductivity
+SET_PROP(ThreePThreeCNI, ThermalConductivityModel)
+{
+private:
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+public:
+    typedef ThermalConductivitySomerton<Scalar, Indices> type;
+};
+
+//! temperature is already written by the isothermal model
+SET_BOOL_PROP(ThreePThreeCNI, NiOutputLevel, 0);
+
+//////////////////////////////////////////////////////////////////
+// Property values for isothermal model required for the general non-isothermal model
+//////////////////////////////////////////////////////////////////
+
+// set isothermal Model
+SET_TYPE_PROP(ThreePThreeCNI, IsothermalModel, ThreePThreeCModel<TypeTag>);
+
+// set isothermal FluxVariables
+SET_TYPE_PROP(ThreePThreeCNI, IsothermalFluxVariables, ThreePThreeCFluxVariables<TypeTag>);
+
+//set isothermal VolumeVariables
+SET_TYPE_PROP(ThreePThreeCNI, IsothermalVolumeVariables, ThreePThreeCVolumeVariables<TypeTag>);
+
+//set isothermal LocalResidual
+SET_TYPE_PROP(ThreePThreeCNI, IsothermalLocalResidual, ThreePThreeCLocalResidual<TypeTag>);
+
+//set isothermal Indices
+SET_PROP(ThreePThreeCNI, IsothermalIndices)
+{
+
+public:
+    typedef ThreePThreeCIndices<TypeTag, /*PVOffset=*/0> type;
+};
+
+//set isothermal NumEq
+SET_INT_PROP(ThreePThreeCNI, IsothermalNumEq, 3);
+
+}
+
+}
+
+#endif
diff --git a/dumux/porousmediumflow/3p3c/implicit/volumevariables.hh b/dumux/porousmediumflow/3p3c/implicit/volumevariables.hh
new file mode 100644
index 0000000000..4a940147a9
--- /dev/null
+++ b/dumux/porousmediumflow/3p3c/implicit/volumevariables.hh
@@ -0,0 +1,750 @@
+// -*- 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/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ *
+ * \brief Contains the quantities which are constant within a
+ *        finite volume in the three-phase three-component model.
+ */
+#ifndef DUMUX_3P3C_VOLUME_VARIABLES_HH
+#define DUMUX_3P3C_VOLUME_VARIABLES_HH
+
+#include <dumux/implicit/model.hh>
+#include <dumux/material/constants.hh>
+#include <dumux/material/fluidstates/compositionalfluidstate.hh>
+#include <dumux/material/constraintsolvers/computefromreferencephase.hh>
+#include <dumux/material/constraintsolvers/misciblemultiphasecomposition.hh>
+#include "properties.hh"
+
+namespace Dumux
+{
+
+/*!
+ * \ingroup ThreePThreeCModel
+ * \ingroup ImplicitVolumeVariables
+ * \brief Contains the quantities which are are constant within a
+ *        finite volume in the three-phase three-component model.
+ */
+template <class TypeTag>
+class ThreePThreeCVolumeVariables : public ImplicitVolumeVariables<TypeTag>
+{
+    typedef ImplicitVolumeVariables<TypeTag> ParentType;
+    typedef typename GET_PROP_TYPE(TypeTag, VolumeVariables) Implementation;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
+    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
+    typedef typename GET_PROP_TYPE(TypeTag, FVElementGeometry) FVElementGeometry;
+    typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
+    typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
+    typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw;
+    typedef typename GET_PROP_TYPE(TypeTag, MaterialLawParams) MaterialLawParams;
+
+    // constraint solvers
+    typedef Dumux::MiscibleMultiPhaseComposition<Scalar, FluidSystem> MiscibleMultiPhaseComposition;
+    typedef Dumux::ComputeFromReferencePhase<Scalar, FluidSystem> ComputeFromReferencePhase;
+
+    typedef typename GET_PROP_TYPE(TypeTag, Indices) Indices;
+    enum {
+        dim = GridView::dimension,
+
+        numPhases = GET_PROP_VALUE(TypeTag, NumPhases),
+        numComponents = GET_PROP_VALUE(TypeTag, NumComponents),
+
+        wCompIdx = Indices::wCompIdx,
+        gCompIdx = Indices::gCompIdx,
+        nCompIdx = Indices::nCompIdx,
+
+        wPhaseIdx = Indices::wPhaseIdx,
+        gPhaseIdx = Indices::gPhaseIdx,
+        nPhaseIdx = Indices::nPhaseIdx,
+
+        switch1Idx = Indices::switch1Idx,
+        switch2Idx = Indices::switch2Idx,
+        pressureIdx = Indices::pressureIdx
+    };
+
+    // present phases
+    enum {
+        threePhases = Indices::threePhases,
+        wPhaseOnly  = Indices::wPhaseOnly,
+        gnPhaseOnly = Indices::gnPhaseOnly,
+        wnPhaseOnly = Indices::wnPhaseOnly,
+        gPhaseOnly  = Indices::gPhaseOnly,
+        wgPhaseOnly = Indices::wgPhaseOnly
+    };
+
+    typedef typename GridView::template Codim<0>::Entity Element;
+
+    static const Scalar R; // universial gas constant
+
+    enum { isBox = GET_PROP_VALUE(TypeTag, ImplicitIsBox) };
+    enum { dofCodim = isBox ? dim : 0 };
+
+public:
+
+   typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState;
+
+    /*!
+     * \copydoc ImplicitVolumeVariables::update
+     */
+    void update(const PrimaryVariables &priVars,
+                const Problem &problem,
+                const Element &element,
+                const FVElementGeometry &fvGeometry,
+                const int scvIdx,
+                bool isOldSol)
+    {
+        ParentType::update(priVars,
+                           problem,
+                           element,
+                           fvGeometry,
+                           scvIdx,
+                           isOldSol);
+
+        bool useConstraintSolver = GET_PROP_VALUE(TypeTag, UseConstraintSolver);
+
+        // capillary pressure parameters
+        const MaterialLawParams &materialParams =
+            problem.spatialParams().materialLawParams(element, fvGeometry, scvIdx);
+
+        int dofIdxGlobal = problem.model().dofMapper().subIndex(element, scvIdx, dofCodim);
+        int phasePresence = problem.model().phasePresence(dofIdxGlobal, isOldSol);
+
+        Scalar temp = Implementation::temperature_(priVars, problem, element, fvGeometry, scvIdx);
+        fluidState_.setTemperature(temp);
+
+        /* first the saturations */
+        if (phasePresence == threePhases)
+        {
+            sw_ = priVars[switch1Idx];
+            sn_ = priVars[switch2Idx];
+            sg_ = 1. - sw_ - sn_;
+        }
+        else if (phasePresence == wPhaseOnly)
+        {
+            sw_ = 1.;
+            sn_ = 0.;
+            sg_ = 0.;
+        }
+        else if (phasePresence == gnPhaseOnly)
+        {
+            sw_ = 0.;
+            sn_ = priVars[switch2Idx];
+            sg_ = 1. - sn_;
+        }
+        else if (phasePresence == wnPhaseOnly)
+        {
+            sn_ = priVars[switch2Idx];
+            sw_ = 1. - sn_;
+            sg_ = 0.;
+        }
+        else if (phasePresence == gPhaseOnly)
+        {
+            sw_ = 0.;
+            sn_ = 0.;
+            sg_ = 1.;
+        }
+        else if (phasePresence == wgPhaseOnly)
+        {
+            sw_ = priVars[switch1Idx];
+            sn_ = 0.;
+            sg_ = 1. - sw_;
+        }
+        else DUNE_THROW(Dune::InvalidStateException, "phasePresence: " << phasePresence << " is invalid.");
+        Valgrind::CheckDefined(sg_);
+
+        fluidState_.setSaturation(wPhaseIdx, sw_);
+        fluidState_.setSaturation(gPhaseIdx, sg_);
+        fluidState_.setSaturation(nPhaseIdx, sn_);
+
+        /* now the pressures */
+        pg_ = priVars[pressureIdx];
+
+        // calculate capillary pressures
+        Scalar pcgw = MaterialLaw::pcgw(materialParams, sw_);
+        Scalar pcnw = MaterialLaw::pcnw(materialParams, sw_);
+        Scalar pcgn = MaterialLaw::pcgn(materialParams, sw_ + sn_);
+
+        Scalar pcAlpha = MaterialLaw::pcAlpha(materialParams, sn_);
+        Scalar pcNW1 = 0.0; // TODO: this should be possible to assign in the problem file
+
+        pn_ = pg_- pcAlpha * pcgn - (1.-pcAlpha)*(pcgw - pcNW1);
+        pw_ = pn_ - pcAlpha * pcnw - (1.-pcAlpha)*pcNW1;
+
+        fluidState_.setPressure(wPhaseIdx, pw_);
+        fluidState_.setPressure(gPhaseIdx, pg_);
+        fluidState_.setPressure(nPhaseIdx, pn_);
+
+        // calculate and set all fugacity coefficients. this is
+        // possible because we require all phases to be an ideal
+        // mixture, i.e. fugacity coefficients are not supposed to
+        // depend on composition!
+        typename FluidSystem::ParameterCache paramCache;
+        // assert(FluidSystem::isIdealGas(gPhaseIdx));
+        for (int phaseIdx = 0; phaseIdx < numPhases; ++ phaseIdx) {
+            assert(FluidSystem::isIdealMixture(phaseIdx));
+
+            for (int compIdx = 0; compIdx < numComponents; ++ compIdx) {
+                Scalar phi = FluidSystem::fugacityCoefficient(fluidState_, paramCache, phaseIdx, compIdx);
+                fluidState_.setFugacityCoefficient(phaseIdx, compIdx, phi);
+            }
+        }
+
+        // now comes the tricky part: calculate phase composition
+        if (phasePresence == threePhases) {
+            // all phases are present, phase compositions are a
+            // result of the the gas <-> liquid equilibrium. This is
+            // the job of the "MiscibleMultiPhaseComposition"
+            // constraint solver ...
+            if (useConstraintSolver) {
+                MiscibleMultiPhaseComposition::solve(fluidState_,
+                                                     paramCache,
+                                                     /*setViscosity=*/true,
+                                                     /*setInternalEnergy=*/false);
+            }
+            // ... or calculated explicitly this way ...
+            else {
+                Scalar partPressH2O = FluidSystem::fugacityCoefficient(fluidState_,
+                                                                      wPhaseIdx,
+                                                                      wCompIdx) * pw_;
+                Scalar partPressNAPL = FluidSystem::fugacityCoefficient(fluidState_,
+                                                                       nPhaseIdx,
+                                                                       nCompIdx) * pn_;
+                Scalar partPressAir = pg_ - partPressH2O - partPressNAPL;
+
+                Scalar xgn = partPressNAPL/pg_;
+                Scalar xgw = partPressH2O/pg_;
+                Scalar xgg = partPressAir/pg_;
+
+                // actually, it's nothing else than Henry coefficient
+                Scalar xwn = partPressNAPL
+                             / (FluidSystem::fugacityCoefficient(fluidState_,
+                                                                 wPhaseIdx,nCompIdx)
+                                * pw_);
+                Scalar xwg = partPressAir
+                             / (FluidSystem::fugacityCoefficient(fluidState_,
+                                                                 wPhaseIdx,gCompIdx)
+                                * pw_);
+                Scalar xww = 1.-xwg-xwn;
+
+                Scalar xnn = 1.-2.e-10;
+                Scalar xna = 1.e-10;
+                Scalar xnw = 1.e-10;
+
+                fluidState_.setMoleFraction(wPhaseIdx, wCompIdx, xww);
+                fluidState_.setMoleFraction(wPhaseIdx, gCompIdx, xwg);
+                fluidState_.setMoleFraction(wPhaseIdx, nCompIdx, xwn);
+                fluidState_.setMoleFraction(gPhaseIdx, wCompIdx, xgw);
+                fluidState_.setMoleFraction(gPhaseIdx, gCompIdx, xgg);
+                fluidState_.setMoleFraction(gPhaseIdx, nCompIdx, xgn);
+                fluidState_.setMoleFraction(nPhaseIdx, wCompIdx, xnw);
+                fluidState_.setMoleFraction(nPhaseIdx, gCompIdx, xna);
+                fluidState_.setMoleFraction(nPhaseIdx, nCompIdx, xnn);
+
+                Scalar rhoW = FluidSystem::density(fluidState_, wPhaseIdx);
+                Scalar rhoG = FluidSystem::density(fluidState_, gPhaseIdx);
+                Scalar rhoN = FluidSystem::density(fluidState_, nPhaseIdx);
+
+                fluidState_.setDensity(wPhaseIdx, rhoW);
+                fluidState_.setDensity(gPhaseIdx, rhoG);
+                fluidState_.setDensity(nPhaseIdx, rhoN);
+            }
+        }
+        else if (phasePresence == wPhaseOnly) {
+            // only the water phase is present, water phase composition is
+            // stored explicitly.
+
+            // extract mole fractions in the water phase
+            Scalar xwg = priVars[switch1Idx];
+            Scalar xwn = priVars[switch2Idx];
+            Scalar xww = 1 - xwg - xwn;
+
+            // write water mole fractions in the fluid state
+            fluidState_.setMoleFraction(wPhaseIdx, wCompIdx, xww);
+            fluidState_.setMoleFraction(wPhaseIdx, gCompIdx, xwg);
+            fluidState_.setMoleFraction(wPhaseIdx, nCompIdx, xwn);
+
+            // calculate the composition of the remaining phases (as
+            // well as the densities of all phases). this is the job
+            // of the "ComputeFromReferencePhase" constraint solver ...
+            if (useConstraintSolver)
+            {
+                ComputeFromReferencePhase::solve(fluidState_,
+                                                 paramCache,
+                                                 wPhaseIdx,
+                                                 /*setViscosity=*/true,
+                                                 /*setInternalEnergy=*/false);
+            }
+            // ... or calculated explicitly this way ...
+            else {
+                // note that the gas phase is actually not existing!
+                // thus, this is used as phase switch criterion
+                Scalar xgg = xwg * FluidSystem::fugacityCoefficient(fluidState_,
+                                                                    wPhaseIdx,gCompIdx)
+                                   * pw_ / pg_;
+                Scalar xgn = xwn * FluidSystem::fugacityCoefficient(fluidState_,
+                                                                    wPhaseIdx,nCompIdx)
+                                   * pw_ / pg_;
+                Scalar xgw = FluidSystem::fugacityCoefficient(fluidState_,
+                                                              wPhaseIdx,wCompIdx)
+                                   * pw_ / pg_;
+
+
+                // note that the gas phase is actually not existing!
+                // thus, this is used as phase switch criterion
+                Scalar xnn = xwn * FluidSystem::fugacityCoefficient(fluidState_,
+                                                                    wPhaseIdx,nCompIdx)
+                                   * pw_;
+                Scalar xna = 1.e-10;
+                Scalar xnw = 1.e-10;
+
+                fluidState_.setMoleFraction(gPhaseIdx, wCompIdx, xgw);
+                fluidState_.setMoleFraction(gPhaseIdx, gCompIdx, xgg);
+                fluidState_.setMoleFraction(gPhaseIdx, nCompIdx, xgn);
+                fluidState_.setMoleFraction(nPhaseIdx, wCompIdx, xnw);
+                fluidState_.setMoleFraction(nPhaseIdx, gCompIdx, xna);
+                fluidState_.setMoleFraction(nPhaseIdx, nCompIdx, xnn);
+
+                Scalar rhoW = FluidSystem::density(fluidState_, wPhaseIdx);
+                Scalar rhoG = FluidSystem::density(fluidState_, gPhaseIdx);
+                Scalar rhoN = FluidSystem::density(fluidState_, nPhaseIdx);
+
+                fluidState_.setDensity(wPhaseIdx, rhoW);
+                fluidState_.setDensity(gPhaseIdx, rhoG);
+                fluidState_.setDensity(nPhaseIdx, rhoN);
+            }
+        }
+        else if (phasePresence == gnPhaseOnly) {
+            // only gas and NAPL phases are present
+            // we have all (partly hypothetical) phase pressures
+            // and temperature and the mole fraction of water in
+            // the gas phase
+
+            // we have all (partly hypothetical) phase pressures
+            // and temperature and the mole fraction of water in
+            // the gas phase
+            Scalar partPressNAPL = fluidState_.fugacityCoefficient(nPhaseIdx, nCompIdx)*pn_;
+
+            Scalar xgw = priVars[switch1Idx];
+            Scalar xgn = partPressNAPL/pg_;
+            Scalar xgg = 1.-xgw-xgn;
+
+            // write mole fractions in the fluid state
+            fluidState_.setMoleFraction(gPhaseIdx, wCompIdx, xgw);
+            fluidState_.setMoleFraction(gPhaseIdx, gCompIdx, xgg);
+            fluidState_.setMoleFraction(gPhaseIdx, nCompIdx, xgn);
+
+            // calculate the composition of the remaining phases (as
+            // well as the densities of all phases). this is the job
+            // of the "ComputeFromReferencePhase" constraint solver
+            ComputeFromReferencePhase::solve(fluidState_,
+                                             paramCache,
+                                             gPhaseIdx,
+                                             /*setViscosity=*/true,
+                                             /*setInternalEnergy=*/false);
+        }
+        else if (phasePresence == wnPhaseOnly) {
+            // only water and NAPL phases are present
+            Scalar pPartialC = fluidState_.fugacityCoefficient(nPhaseIdx,nCompIdx)*pn_;
+            Scalar henryC = fluidState_.fugacityCoefficient(wPhaseIdx,nCompIdx)*pw_;
+
+            Scalar xwg = priVars[switch1Idx];
+            Scalar xwn = pPartialC/henryC;
+            Scalar xww = 1.-xwg-xwn;
+
+            // write mole fractions in the fluid state
+            fluidState_.setMoleFraction(wPhaseIdx, wCompIdx, xww);
+            fluidState_.setMoleFraction(wPhaseIdx, gCompIdx, xwg);
+            fluidState_.setMoleFraction(wPhaseIdx, nCompIdx, xwn);
+
+            // calculate the composition of the remaining phases (as
+            // well as the densities of all phases). this is the job
+            // of the "ComputeFromReferencePhase" constraint solver
+            ComputeFromReferencePhase::solve(fluidState_,
+                                             paramCache,
+                                             wPhaseIdx,
+                                             /*setViscosity=*/true,
+                                             /*setInternalEnergy=*/false);
+        }
+        else if (phasePresence == gPhaseOnly) {
+            // only the gas phase is present, gas phase composition is
+            // stored explicitly here below.
+
+            const Scalar xgw = priVars[switch1Idx];
+            const Scalar xgn = priVars[switch2Idx];
+            Scalar xgg = 1 - xgw - xgn;
+
+            // write mole fractions in the fluid state
+            fluidState_.setMoleFraction(gPhaseIdx, wCompIdx, xgw);
+            fluidState_.setMoleFraction(gPhaseIdx, gCompIdx, xgg);
+            fluidState_.setMoleFraction(gPhaseIdx, nCompIdx, xgn);
+
+            // calculate the composition of the remaining phases (as
+            // well as the densities of all phases). this is the job
+            // of the "ComputeFromReferencePhase" constraint solver ...
+            if (useConstraintSolver)
+            {
+                ComputeFromReferencePhase::solve(fluidState_,
+                                                 paramCache,
+                                                 gPhaseIdx,
+                                                 /*setViscosity=*/true,
+                                                 /*setInternalEnergy=*/false);
+            }
+            // ... or calculated explicitly this way ...
+            else {
+
+                // note that the water phase is actually not existing!
+                // thus, this is used as phase switch criterion
+                Scalar xww = xgw * pg_
+                             / (FluidSystem::fugacityCoefficient(fluidState_,
+                                                                 wPhaseIdx,wCompIdx)
+                                * pw_);
+                Scalar xwn = 1.e-10;
+                Scalar xwg = 1.e-10;
+
+                // note that the NAPL phase is actually not existing!
+                // thus, this is used as phase switch criterion
+                Scalar xnn = xgn * pg_
+                             / (FluidSystem::fugacityCoefficient(fluidState_,
+                                                                 nPhaseIdx,nCompIdx)
+                                * pn_);
+                Scalar xna = 1.e-10;
+                Scalar xnw = 1.e-10;
+
+                fluidState_.setMoleFraction(wPhaseIdx, wCompIdx, xww);
+                fluidState_.setMoleFraction(wPhaseIdx, gCompIdx, xwg);
+                fluidState_.setMoleFraction(wPhaseIdx, nCompIdx, xwn);
+                fluidState_.setMoleFraction(nPhaseIdx, wCompIdx, xnw);
+                fluidState_.setMoleFraction(nPhaseIdx, gCompIdx, xna);
+                fluidState_.setMoleFraction(nPhaseIdx, nCompIdx, xnn);
+
+                Scalar rhoW = FluidSystem::density(fluidState_, wPhaseIdx);
+                Scalar rhoG = FluidSystem::density(fluidState_, gPhaseIdx);
+                Scalar rhoN = FluidSystem::density(fluidState_, nPhaseIdx);
+
+                fluidState_.setDensity(wPhaseIdx, rhoW);
+                fluidState_.setDensity(gPhaseIdx, rhoG);
+                fluidState_.setDensity(nPhaseIdx, rhoN);
+            }
+        }
+        else if (phasePresence == wgPhaseOnly) {
+            // only water and gas phases are present
+            Scalar xgn = priVars[switch2Idx];
+            Scalar partPressH2O = fluidState_.fugacityCoefficient(wPhaseIdx, wCompIdx)*pw_;
+
+            Scalar xgw = partPressH2O/pg_;
+            Scalar xgg = 1.-xgn-xgw;
+
+            // write mole fractions in the fluid state
+            fluidState_.setMoleFraction(gPhaseIdx, wCompIdx, xgw);
+            fluidState_.setMoleFraction(gPhaseIdx, gCompIdx, xgg);
+            fluidState_.setMoleFraction(gPhaseIdx, nCompIdx, xgn);
+
+            // calculate the composition of the remaining phases (as
+            // well as the densities of all phases). this is the job
+            // of the "ComputeFromReferencePhase" constraint solver ...
+            if (useConstraintSolver)
+            {
+                ComputeFromReferencePhase::solve(fluidState_,
+                                                 paramCache,
+                                                 gPhaseIdx,
+                                                 /*setViscosity=*/true,
+                                                 /*setInternalEnergy=*/false);
+            }
+            // ... or calculated explicitly this way ...
+            else {
+                // actually, it's nothing else than Henry coefficient
+                Scalar xwn = xgn * pg_
+                             / (FluidSystem::fugacityCoefficient(fluidState_,
+                                                                 wPhaseIdx,nCompIdx)
+                                * pw_);
+                Scalar xwg = xgg * pg_
+                             / (FluidSystem::fugacityCoefficient(fluidState_,
+                                                                 wPhaseIdx,gCompIdx)
+                                * pw_);
+                Scalar xww = 1.-xwg-xwn;
+
+                // note that the NAPL phase is actually not existing!
+                // thus, this is used as phase switch criterion
+                Scalar xnn = xgn * pg_
+                             / (FluidSystem::fugacityCoefficient(fluidState_,
+                                                                 nPhaseIdx,nCompIdx)
+                                * pn_);
+                Scalar xna = 1.e-10;
+                Scalar xnw = 1.e-10;
+
+                fluidState_.setMoleFraction(wPhaseIdx, wCompIdx, xww);
+                fluidState_.setMoleFraction(wPhaseIdx, gCompIdx, xwg);
+                fluidState_.setMoleFraction(wPhaseIdx, nCompIdx, xwn);
+                fluidState_.setMoleFraction(nPhaseIdx, wCompIdx, xnw);
+                fluidState_.setMoleFraction(nPhaseIdx, gCompIdx, xna);
+                fluidState_.setMoleFraction(nPhaseIdx, nCompIdx, xnn);
+
+                Scalar rhoW = FluidSystem::density(fluidState_, wPhaseIdx);
+                Scalar rhoG = FluidSystem::density(fluidState_, gPhaseIdx);
+                Scalar rhoN = FluidSystem::density(fluidState_, nPhaseIdx);
+
+                fluidState_.setDensity(wPhaseIdx, rhoW);
+                fluidState_.setDensity(gPhaseIdx, rhoG);
+                fluidState_.setDensity(nPhaseIdx, rhoN);
+            }
+        }
+        else
+            assert(false); // unhandled phase state
+
+        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
+            // Mobilities
+            const Scalar mu =
+                FluidSystem::viscosity(fluidState_,
+                                       paramCache,
+                                       phaseIdx);
+            fluidState_.setViscosity(phaseIdx,mu);
+
+            Scalar kr;
+            kr = MaterialLaw::kr(materialParams, phaseIdx,
+                                 fluidState_.saturation(wPhaseIdx),
+                                 fluidState_.saturation(nPhaseIdx),
+                                 fluidState_.saturation(gPhaseIdx));
+            mobility_[phaseIdx] = kr / mu;
+            Valgrind::CheckDefined(mobility_[phaseIdx]);
+        }
+
+        // material dependent parameters for NAPL adsorption
+        bulkDensTimesAdsorpCoeff_ =
+            MaterialLaw::bulkDensTimesAdsorpCoeff(materialParams);
+
+        /* ATTENTION: The conversion to effective diffusion parameters
+         *            for the porous media happens at another place!
+         */
+
+        // diffusivity coefficents
+        diffusionCoefficient_[gPhaseIdx][wCompIdx] =
+            FluidSystem::diffusionCoefficient(fluidState_,
+                                              paramCache,
+                                              gPhaseIdx,
+                                              wCompIdx);
+        diffusionCoefficient_[gPhaseIdx][nCompIdx] =
+            FluidSystem::diffusionCoefficient(fluidState_,
+                                              paramCache,
+                                              gPhaseIdx,
+                                              nCompIdx);
+        diffusionCoefficient_[gPhaseIdx][gCompIdx] = 0.0; // dummy, should not be used !
+
+        diffusionCoefficient_[wPhaseIdx][gCompIdx] =
+            FluidSystem::diffusionCoefficient(fluidState_,
+                                              paramCache,
+                                              wPhaseIdx,
+                                              gCompIdx);
+        diffusionCoefficient_[wPhaseIdx][nCompIdx] =
+            FluidSystem::diffusionCoefficient(fluidState_,
+                                              paramCache,
+                                              wPhaseIdx,
+                                              nCompIdx);
+        diffusionCoefficient_[wPhaseIdx][wCompIdx] = 0.0; // dummy, should not be used !
+
+        /* no diffusion in NAPL phase considered  at the moment */
+        diffusionCoefficient_[nPhaseIdx][nCompIdx] = 0.0;
+        diffusionCoefficient_[nPhaseIdx][wCompIdx] = 0.0;
+        diffusionCoefficient_[nPhaseIdx][gCompIdx] = 0.0;
+
+        Valgrind::CheckDefined(diffusionCoefficient_);
+
+        // porosity
+        porosity_ = problem.spatialParams().porosity(element,
+                                                         fvGeometry,
+                                                         scvIdx);
+        Valgrind::CheckDefined(porosity_);
+
+        // energy related quantities not contained in the fluid state
+        asImp_().updateEnergy_(priVars, problem, element, fvGeometry, scvIdx, isOldSol);
+        // compute and set the enthalpy
+        for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
+        {
+            Scalar h = Implementation::enthalpy_(fluidState_, paramCache, phaseIdx);
+            fluidState_.setEnthalpy(phaseIdx, h);
+        }
+    }
+
+    /*!
+     * \brief Returns the phase state for the control volume.
+     */
+    const FluidState &fluidState() const
+    { return fluidState_; }
+
+    /*!
+     * \brief Returns the effective saturation of a given phase within
+     *        the control volume.
+     *
+     * \param phaseIdx The phase index
+     */
+    Scalar saturation(const int phaseIdx) const
+    { return fluidState_.saturation(phaseIdx); }
+
+    /*!
+     * \brief Returns the mass fraction of a given component in a
+     *        given phase within the control volume in \f$[-]\f$.
+     *
+     * \param phaseIdx The phase index
+     * \param compIdx The component index
+     */
+    Scalar massFraction(const int phaseIdx, const int compIdx) const
+    { return fluidState_.massFraction(phaseIdx, compIdx); }
+
+    /*!
+     * \brief Returns the mole fraction of a given component in a
+     *        given phase within the control volume in \f$[-]\f$.
+     *
+     * \param phaseIdx The phase index
+     * \param compIdx The component index
+     */
+    Scalar moleFraction(const int phaseIdx, const int compIdx) const
+    { return fluidState_.moleFraction(phaseIdx, compIdx); }
+
+    /*!
+     * \brief Returns the mass density of a given phase within the
+     *        control volume.
+     *
+     * \param phaseIdx The phase index
+     */
+    Scalar density(const int phaseIdx) const
+    { return fluidState_.density(phaseIdx); }
+
+    /*!
+     * \brief Returns the molar density of a given phase within the
+     *        control volume.
+     *
+     * \param phaseIdx The phase index
+     */
+    Scalar molarDensity(const int phaseIdx) const
+    { return fluidState_.density(phaseIdx) / fluidState_.averageMolarMass(phaseIdx); }
+
+    /*!
+     * \brief Returns the effective pressure of a given phase within
+     *        the control volume.
+     *
+     * \param phaseIdx The phase index
+     */
+    Scalar pressure(const int phaseIdx) const
+    { return fluidState_.pressure(phaseIdx); }
+
+    /*!
+     * \brief Returns temperature inside the sub-control volume.
+     *
+     * Note that we assume thermodynamic equilibrium, i.e. the
+     * temperatures of the rock matrix and of all fluid phases are
+     * identical.
+     */
+    Scalar temperature() const
+    { return fluidState_.temperature(/*phaseIdx=*/0); }
+
+    /*!
+     * \brief Returns the effective mobility of a given phase within
+     *        the control volume.
+     *
+     * \param phaseIdx The phase index
+     */
+    Scalar mobility(const int phaseIdx) const
+    {
+        return mobility_[phaseIdx];
+    }
+
+    /*!
+     * \brief Returns the effective capillary pressure within the control volume.
+     */
+    Scalar capillaryPressure() const
+    { return fluidState_.capillaryPressure(); }
+
+    /*!
+     * \brief Returns the average porosity within the control volume.
+     */
+    Scalar porosity() const
+    { return porosity_; }
+
+    /*!
+     * \brief Returns the diffusivity coefficient matrix.
+     */
+    Dune::FieldMatrix<Scalar, numPhases, numComponents> diffusionCoefficient() const
+    { return diffusionCoefficient_; }
+
+    /*!
+     * \brief Returns the adsorption information.
+     */
+    Scalar bulkDensTimesAdsorpCoeff() const
+    { return bulkDensTimesAdsorpCoeff_; }
+
+
+protected:
+
+    static Scalar temperature_(const PrimaryVariables &priVars,
+                               const Problem &problem,
+                               const Element &element,
+                               const FVElementGeometry &fvGeometry,
+                               const int scvIdx)
+    {
+        return problem.temperatureAtPos(fvGeometry.subContVol[scvIdx].global);
+    }
+
+    /*!
+     * \brief Called by update() to compute the energy related quantities
+     */
+    void updateEnergy_(const PrimaryVariables &priVars,
+                       const Problem &problem,
+                       const Element &element,
+                       const FVElementGeometry &fvGeometry,
+                       const int scvIdx,
+                       bool isOldSol)
+    { }
+
+    template<class ParameterCache>
+    static Scalar enthalpy_(const FluidState& fluidState,
+                            const ParameterCache& paramCache,
+                            const int phaseIdx)
+    {
+        return 0;
+    }
+
+    Scalar sw_, sg_, sn_, pg_, pw_, pn_;
+
+    Scalar moleFrac_[numPhases][numComponents];
+    Scalar massFrac_[numPhases][numComponents];
+
+    Scalar porosity_;        //!< Effective porosity within the control volume
+    Scalar mobility_[numPhases];  //!< Effective mobility within the control volume
+    Scalar bulkDensTimesAdsorpCoeff_; //!< the basis for calculating adsorbed NAPL
+    /* We need a tensor here !! */
+    //!< Binary diffusion coefficients of the 3 components in the phases
+    Dune::FieldMatrix<Scalar, numPhases, numComponents> diffusionCoefficient_;
+    FluidState fluidState_;
+
+private:
+    Implementation &asImp_()
+    { return *static_cast<Implementation*>(this); }
+
+    const Implementation &asImp_() const
+    { return *static_cast<const Implementation*>(this); }
+};
+
+template <class TypeTag>
+const typename ThreePThreeCVolumeVariables<TypeTag>::Scalar ThreePThreeCVolumeVariables<TypeTag>::R
+                 = Constants<typename GET_PROP_TYPE(TypeTag, Scalar)>::R;
+
+} // end namespace
+
+#endif
diff --git a/test/material/fluidmatrixinteractions/2p/thermalconductivityjohansenproblem.hh b/test/material/fluidmatrixinteractions/2p/thermalconductivityjohansenproblem.hh
index bf4a1ced20..dd84bc4751 100644
--- a/test/material/fluidmatrixinteractions/2p/thermalconductivityjohansenproblem.hh
+++ b/test/material/fluidmatrixinteractions/2p/thermalconductivityjohansenproblem.hh
@@ -28,7 +28,7 @@
 
 #include <dumux/material/fluidsystems/h2on2fluidsystem.hh>
 
-#include <dumux/implicit/2p2c/2p2cmodel.hh>
+#include <dumux/porousmediumflow/2p2c/implicit/model.hh>
 #include <dumux/porousmediumflow/implicit/problem.hh>
 #include <dumux/material/fluidmatrixinteractions/2p/thermalconductivityjohansen.hh>
 
diff --git a/test/material/fluidmatrixinteractions/2p/thermalconductivitysomertonproblem.hh b/test/material/fluidmatrixinteractions/2p/thermalconductivitysomertonproblem.hh
index 965ac84f8a..48d65dbdd9 100644
--- a/test/material/fluidmatrixinteractions/2p/thermalconductivitysomertonproblem.hh
+++ b/test/material/fluidmatrixinteractions/2p/thermalconductivitysomertonproblem.hh
@@ -28,7 +28,7 @@
 
 #include <dumux/material/fluidsystems/h2on2fluidsystem.hh>
 
-#include <dumux/implicit/2p2c/2p2cmodel.hh>
+#include <dumux/porousmediumflow/2p2c/implicit/model.hh>
 #include <dumux/porousmediumflow/implicit/problem.hh>
 #include <dumux/material/fluidmatrixinteractions/2p/thermalconductivitysomerton.hh>
 
diff --git a/test/material/fluidmatrixinteractions/2p/thermalconductivityspatialparams.hh b/test/material/fluidmatrixinteractions/2p/thermalconductivityspatialparams.hh
index 6d193a258e..c33dc54687 100644
--- a/test/material/fluidmatrixinteractions/2p/thermalconductivityspatialparams.hh
+++ b/test/material/fluidmatrixinteractions/2p/thermalconductivityspatialparams.hh
@@ -29,7 +29,7 @@
 #include <dumux/material/fluidmatrixinteractions/2p/regularizedbrookscorey.hh>
 #include <dumux/material/fluidmatrixinteractions/2p/efftoabslaw.hh>
 
-#include <dumux/implicit/2p2c/2p2cmodel.hh>
+#include <dumux/porousmediumflow/2p2c/implicit/model.hh>
 
 namespace Dumux
 {
diff --git a/test/material/fluidmatrixinteractions/effectivediffusivityconstanttauproblem.hh b/test/material/fluidmatrixinteractions/effectivediffusivityconstanttauproblem.hh
index 5bc8aa394a..64e0963b96 100644
--- a/test/material/fluidmatrixinteractions/effectivediffusivityconstanttauproblem.hh
+++ b/test/material/fluidmatrixinteractions/effectivediffusivityconstanttauproblem.hh
@@ -28,7 +28,7 @@
 
 #include <dumux/material/fluidsystems/h2on2fluidsystem.hh>
 
-#include <dumux/implicit/2p2c/2p2cmodel.hh>
+#include <dumux/porousmediumflow/2p2c/implicit/model.hh>
 #include <dumux/porousmediumflow/implicit/problem.hh>
 #include <dumux/material/fluidmatrixinteractions/diffusivityconstanttau.hh>
 
diff --git a/test/material/fluidmatrixinteractions/effectivediffusivitymillingtonquirkproblem.hh b/test/material/fluidmatrixinteractions/effectivediffusivitymillingtonquirkproblem.hh
index 40dcb8d30a..1cb0d2d979 100644
--- a/test/material/fluidmatrixinteractions/effectivediffusivitymillingtonquirkproblem.hh
+++ b/test/material/fluidmatrixinteractions/effectivediffusivitymillingtonquirkproblem.hh
@@ -28,7 +28,7 @@
 
 #include <dumux/material/fluidsystems/h2on2fluidsystem.hh>
 
-#include <dumux/implicit/2p2c/2p2cmodel.hh>
+#include <dumux/porousmediumflow/2p2c/implicit/model.hh>
 #include <dumux/porousmediumflow/implicit/problem.hh>
 #include <dumux/material/fluidmatrixinteractions/diffusivitymillingtonquirk.hh>
 
diff --git a/test/material/fluidmatrixinteractions/effectivediffusivityspatialparams.hh b/test/material/fluidmatrixinteractions/effectivediffusivityspatialparams.hh
index e778697e64..eebfbfa931 100644
--- a/test/material/fluidmatrixinteractions/effectivediffusivityspatialparams.hh
+++ b/test/material/fluidmatrixinteractions/effectivediffusivityspatialparams.hh
@@ -29,7 +29,7 @@
 #include <dumux/material/fluidmatrixinteractions/2p/regularizedbrookscorey.hh>
 #include <dumux/material/fluidmatrixinteractions/2p/efftoabslaw.hh>
 
-#include <dumux/implicit/2p2c/2p2cmodel.hh>
+#include <dumux/porousmediumflow/2p2c/implicit/model.hh>
 
 namespace Dumux
 {
diff --git a/test/multidomain/2cnistokes2p2cni/2p2cnisubproblem.hh b/test/multidomain/2cnistokes2p2cni/2p2cnisubproblem.hh
index 23d36df3ac..20688c0c7b 100644
--- a/test/multidomain/2cnistokes2p2cni/2p2cnisubproblem.hh
+++ b/test/multidomain/2cnistokes2p2cni/2p2cnisubproblem.hh
@@ -27,7 +27,7 @@
 #include <dune/common/float_cmp.hh>
 
 #include <dumux/porousmediumflow/implicit/problem.hh>
-#include <dumux/implicit/2p2c/2p2cmodel.hh>
+#include <dumux/porousmediumflow/2p2c/implicit/model.hh>
 #include <dumux/io/gnuplotinterface.hh>
 #include <dumux/multidomain/2cnistokes2p2cni/2p2cnicouplinglocalresidual.hh>
 #include <dumux/multidomain/common/subdomainpropertydefaults.hh>
diff --git a/test/multidomain/2cnizeroeq2p2cni/2p2cnisubproblem.hh b/test/multidomain/2cnizeroeq2p2cni/2p2cnisubproblem.hh
index 5866f3a692..45504fe96b 100644
--- a/test/multidomain/2cnizeroeq2p2cni/2p2cnisubproblem.hh
+++ b/test/multidomain/2cnizeroeq2p2cni/2p2cnisubproblem.hh
@@ -24,7 +24,7 @@
 #ifndef DUMUX_2P2CNISUB_PROBLEM_HH
 #define DUMUX_2P2CNISUB_PROBLEM_HH
 
-#include <dumux/implicit/2p2c/2p2cindices.hh>
+#include <dumux/porousmediumflow/2p2c/implicit/indices.hh>
 #include <dumux/porousmediumflow/implicit/problem.hh>
 #include <dumux/material/fluidmatrixinteractions/2p/thermalconductivityjohansen.hh>
 #include <dumux/material/fluidmatrixinteractions/2p/thermalconductivitysomerton.hh>
diff --git a/test/multidomain/2cstokes2p2c/2p2csubproblem.hh b/test/multidomain/2cstokes2p2c/2p2csubproblem.hh
index d1eb5f75b8..edfb76caf2 100644
--- a/test/multidomain/2cstokes2p2c/2p2csubproblem.hh
+++ b/test/multidomain/2cstokes2p2c/2p2csubproblem.hh
@@ -26,7 +26,7 @@
 
 #include <dune/common/float_cmp.hh>
 
-#include <dumux/implicit/2p2c/2p2cindices.hh>
+#include <dumux/porousmediumflow/2p2c/implicit/indices.hh>
 #include <dumux/porousmediumflow/implicit/problem.hh>
 #include <dumux/multidomain/2cstokes2p2c/2p2ccouplinglocalresidual.hh>
 #include <dumux/multidomain/common/subdomainpropertydefaults.hh>
diff --git a/test/multidomain/2czeroeq2p2c/2p2csubproblem.hh b/test/multidomain/2czeroeq2p2c/2p2csubproblem.hh
index 706e50daa6..f7a26669f0 100644
--- a/test/multidomain/2czeroeq2p2c/2p2csubproblem.hh
+++ b/test/multidomain/2czeroeq2p2c/2p2csubproblem.hh
@@ -25,7 +25,7 @@
 #ifndef DUMUX_TWOPTWOC_SUBPROBLEM_HH
 #define DUMUX_TWOPTWOC_SUBPROBLEM_HH
 
-#include <dumux/implicit/2p2c/2p2cindices.hh>
+#include <dumux/porousmediumflow/2p2c/implicit/indices.hh>
 #include <dumux/porousmediumflow/implicit/problem.hh>
 #include <dumux/multidomain/common/subdomainpropertydefaults.hh>
 #include <dumux/multidomain/common/multidomainlocaloperator.hh>
diff --git a/test/porousmediumflow/1p2c/implicit/1p2cniconductionproblem.hh b/test/porousmediumflow/1p2c/implicit/1p2cniconductionproblem.hh
index 30fe8390ae..533e9a3789 100644
--- a/test/porousmediumflow/1p2c/implicit/1p2cniconductionproblem.hh
+++ b/test/porousmediumflow/1p2c/implicit/1p2cniconductionproblem.hh
@@ -27,7 +27,7 @@
 
 #include <dune/grid/io/file/dgfparser/dgfyasp.hh>
 
-#include <dumux/implicit/1p2c/1p2cmodel.hh>
+#include <dumux/porousmediumflow/1p2c/implicit/model.hh>
 #include <dumux/porousmediumflow/implicit/problem.hh>
 
 #include <dumux/material/fluidsystems/h2on2liquidphasefluidsystem.hh>
diff --git a/test/porousmediumflow/1p2c/implicit/1p2cniconvectionproblem.hh b/test/porousmediumflow/1p2c/implicit/1p2cniconvectionproblem.hh
index 33c23231f3..df86cd7e4c 100644
--- a/test/porousmediumflow/1p2c/implicit/1p2cniconvectionproblem.hh
+++ b/test/porousmediumflow/1p2c/implicit/1p2cniconvectionproblem.hh
@@ -28,7 +28,7 @@
 
 #include <dune/grid/io/file/dgfparser/dgfyasp.hh>
 
-#include <dumux/implicit/1p2c/1p2cmodel.hh>
+#include <dumux/porousmediumflow/1p2c/implicit/model.hh>
 #include <dumux/porousmediumflow/implicit/problem.hh>
 #include <dumux/material/components/h2o.hh>
 #include <dumux/material/fluidsystems/h2on2liquidphasefluidsystem.hh>
diff --git a/test/porousmediumflow/1p2c/implicit/1p2coutflowproblem.hh b/test/porousmediumflow/1p2c/implicit/1p2coutflowproblem.hh
index 86479bb40d..7e1f814c1d 100644
--- a/test/porousmediumflow/1p2c/implicit/1p2coutflowproblem.hh
+++ b/test/porousmediumflow/1p2c/implicit/1p2coutflowproblem.hh
@@ -29,7 +29,7 @@
 #endif
 #include <dune/grid/io/file/dgfparser/dgfyasp.hh>
 
-#include <dumux/implicit/1p2c/1p2cmodel.hh>
+#include <dumux/porousmediumflow/1p2c/implicit/model.hh>
 #include <dumux/porousmediumflow/implicit/problem.hh>
 
 #include <dumux/material/fluidsystems/h2on2liquidphasefluidsystem.hh>
diff --git a/test/porousmediumflow/2p2c/implicit/injectionproblem.hh b/test/porousmediumflow/2p2c/implicit/injectionproblem.hh
index 6a4c19181c..eea1ceaeff 100644
--- a/test/porousmediumflow/2p2c/implicit/injectionproblem.hh
+++ b/test/porousmediumflow/2p2c/implicit/injectionproblem.hh
@@ -26,7 +26,7 @@
 
 #include <dune/grid/io/file/dgfparser/dgfyasp.hh>
 
-#include <dumux/implicit/2p2c/2p2cmodel.hh>
+#include <dumux/porousmediumflow/2p2c/implicit/model.hh>
 #include <dumux/porousmediumflow/implicit/problem.hh>
 #include <dumux/material/fluidsystems/h2on2fluidsystem.hh>
 
diff --git a/test/porousmediumflow/2p2c/implicit/injectionspatialparams.hh b/test/porousmediumflow/2p2c/implicit/injectionspatialparams.hh
index 029140c28e..3b9181bf70 100644
--- a/test/porousmediumflow/2p2c/implicit/injectionspatialparams.hh
+++ b/test/porousmediumflow/2p2c/implicit/injectionspatialparams.hh
@@ -31,7 +31,7 @@
 #include <dumux/material/fluidmatrixinteractions/2p/regularizedbrookscorey.hh>
 #include <dumux/material/fluidmatrixinteractions/2p/efftoabslaw.hh>
 
-#include <dumux/implicit/2p2c/2p2cproperties.hh>
+#include <dumux/porousmediumflow/2p2c/implicit/properties.hh>
 
 namespace Dumux
 {
diff --git a/test/porousmediumflow/2p2c/implicit/waterairproblem.hh b/test/porousmediumflow/2p2c/implicit/waterairproblem.hh
index fd01cefbc8..ba6b25f33e 100644
--- a/test/porousmediumflow/2p2c/implicit/waterairproblem.hh
+++ b/test/porousmediumflow/2p2c/implicit/waterairproblem.hh
@@ -29,7 +29,7 @@
 
 #include <dumux/material/fluidsystems/h2on2fluidsystem.hh>
 
-#include <dumux/implicit/2p2c/2p2cmodel.hh>
+#include <dumux/porousmediumflow/2p2c/implicit/model.hh>
 #include <dumux/porousmediumflow/implicit/problem.hh>
 
 #include "waterairspatialparams.hh"
diff --git a/test/porousmediumflow/2p2c/implicit/waterairspatialparams.hh b/test/porousmediumflow/2p2c/implicit/waterairspatialparams.hh
index b3b071d942..a8f534877e 100644
--- a/test/porousmediumflow/2p2c/implicit/waterairspatialparams.hh
+++ b/test/porousmediumflow/2p2c/implicit/waterairspatialparams.hh
@@ -31,7 +31,7 @@
 #include <dumux/material/fluidmatrixinteractions/2p/regularizedbrookscorey.hh>
 #include <dumux/material/fluidmatrixinteractions/2p/efftoabslaw.hh>
 
-#include <dumux/implicit/2p2c/2p2cmodel.hh>
+#include <dumux/porousmediumflow/2p2c/implicit/model.hh>
 
 namespace Dumux
 {
diff --git a/test/porousmediumflow/2pnc/implicit/fuelcellproblem.hh b/test/porousmediumflow/2pnc/implicit/fuelcellproblem.hh
index 19d547f1ab..fe77d0fd46 100644
--- a/test/porousmediumflow/2pnc/implicit/fuelcellproblem.hh
+++ b/test/porousmediumflow/2pnc/implicit/fuelcellproblem.hh
@@ -25,7 +25,7 @@
 #define DUMUX_FUELCELL_PROBLEM_HH
 
 #include <dumux/io/cubegridcreator.hh>
-#include <dumux/implicit/2pnc/2pncmodel.hh>
+#include <dumux/porousmediumflow/2pnc/implicit/model.hh>
 #include <dumux/porousmediumflow/implicit/problem.hh>
 #include <dumux/material/fluidsystems/h2on2o2fluidsystem.hh>
 #include <dumux/material/constants.hh>
diff --git a/test/porousmediumflow/2pnc/implicit/fuelcellspatialparams.hh b/test/porousmediumflow/2pnc/implicit/fuelcellspatialparams.hh
index 9ee7aed63e..a194f5667b 100644
--- a/test/porousmediumflow/2pnc/implicit/fuelcellspatialparams.hh
+++ b/test/porousmediumflow/2pnc/implicit/fuelcellspatialparams.hh
@@ -31,7 +31,7 @@
 #include <dumux/material/fluidmatrixinteractions/2p/regularizedbrookscorey.hh>
 #include <dumux/material/fluidmatrixinteractions/2p/regularizedvangenuchten.hh>
 #include <dumux/material/fluidmatrixinteractions/2p/philtophoblaw.hh>
-#include <dumux/implicit/2pnc/2pncmodel.hh>
+#include <dumux/porousmediumflow/2pnc/implicit/model.hh>
 
 namespace Dumux
 {
diff --git a/test/porousmediumflow/2pncmin/implicit/dissolutionproblem.hh b/test/porousmediumflow/2pncmin/implicit/dissolutionproblem.hh
index 73644c5552..6027ac1a96 100644
--- a/test/porousmediumflow/2pncmin/implicit/dissolutionproblem.hh
+++ b/test/porousmediumflow/2pncmin/implicit/dissolutionproblem.hh
@@ -24,7 +24,7 @@
 #ifndef DUMUX_DISSOLUTION_PROBLEM_HH
 #define DUMUX_DISSOLUTION_PROBLEM_HH
 
-#include <dumux/implicit/2pncmin/2pncminmodel.hh>
+#include <dumux/porousmediumflow/2pncmin/implicit/model.hh>
 #include <dumux/porousmediumflow/implicit/problem.hh>
 #include<dumux/material/fluidsystems/brineairfluidsystem.hh>
 
diff --git a/test/porousmediumflow/2pncmin/implicit/dissolutionspatialparams.hh b/test/porousmediumflow/2pncmin/implicit/dissolutionspatialparams.hh
index dc40d8de56..6a79121406 100644
--- a/test/porousmediumflow/2pncmin/implicit/dissolutionspatialparams.hh
+++ b/test/porousmediumflow/2pncmin/implicit/dissolutionspatialparams.hh
@@ -19,7 +19,7 @@
 #ifndef DUMUX_INJECTION_SPATIAL_PARAMETERS_HH
 #define DUMUX_INJECTION_SPATIAL_PARAMETERS_HH
 
-#include <dumux/implicit/2pncmin/2pncminindices.hh>
+#include <dumux/porousmediumflow/2pncmin/implicit/indices.hh>
 #include <dumux/material/spatialparams/implicitspatialparams.hh>
 #include <dumux/material/fluidmatrixinteractions/2p/linearmaterial.hh>
 #include <dumux/material/fluidmatrixinteractions/2p/regularizedbrookscorey.hh>
diff --git a/test/porousmediumflow/3p/implicit/3pnispatialparams.hh b/test/porousmediumflow/3p/implicit/3pnispatialparams.hh
index 441231520f..a83292de10 100644
--- a/test/porousmediumflow/3p/implicit/3pnispatialparams.hh
+++ b/test/porousmediumflow/3p/implicit/3pnispatialparams.hh
@@ -24,7 +24,7 @@
 #ifndef DUMUX_THREEPNI_SPATIAL_PARAMS_HH
 #define DUMUX_THREEPNI_SPATIAL_PARAMS_HH
 
-#include <dumux/implicit/3p3c/3p3cindices.hh>
+#include <dumux/porousmediumflow/3p3c/implicit/indices.hh>
 #include <dumux/material/spatialparams/implicitspatialparams.hh>
 #include <dumux/material/fluidmatrixinteractions/3p/regularizedparkervangen3p.hh>
 #include <dumux/material/fluidmatrixinteractions/3p/regularizedparkervangen3pparams.hh>
diff --git a/test/porousmediumflow/3p/implicit/infiltration3pspatialparams.hh b/test/porousmediumflow/3p/implicit/infiltration3pspatialparams.hh
index bcf6547a55..92db70a4d6 100644
--- a/test/porousmediumflow/3p/implicit/infiltration3pspatialparams.hh
+++ b/test/porousmediumflow/3p/implicit/infiltration3pspatialparams.hh
@@ -25,7 +25,7 @@
 #ifndef DUMUX_INFILTRATION_THREEP_SPATIAL_PARAMS_HH
 #define DUMUX_INFILTRATION_THREEP_SPATIAL_PARAMS_HH
 
-#include <dumux/implicit/3p3c/3p3cindices.hh>
+#include <dumux/porousmediumflow/3p3c/implicit/indices.hh>
 #include <dumux/material/spatialparams/implicitspatialparams.hh>
 #include <dumux/material/fluidmatrixinteractions/3p/regularizedparkervangen3p.hh>
 #include <dumux/material/fluidmatrixinteractions/3p/regularizedparkervangen3pparams.hh>
diff --git a/test/porousmediumflow/3p3c/implicit/columnxylolproblem.hh b/test/porousmediumflow/3p3c/implicit/columnxylolproblem.hh
index 2f10cd732d..28b2566923 100644
--- a/test/porousmediumflow/3p3c/implicit/columnxylolproblem.hh
+++ b/test/porousmediumflow/3p3c/implicit/columnxylolproblem.hh
@@ -29,7 +29,7 @@
 
 #include <dumux/material/fluidsystems/h2oairxylenefluidsystem.hh>
 
-#include <dumux/implicit/3p3c/3p3cmodel.hh>
+#include <dumux/porousmediumflow/3p3c/implicit/model.hh>
 #include <dumux/porousmediumflow/implicit/problem.hh>
 
 #include "columnxylolspatialparams.hh"
diff --git a/test/porousmediumflow/3p3c/implicit/columnxylolspatialparams.hh b/test/porousmediumflow/3p3c/implicit/columnxylolspatialparams.hh
index 436f3a033d..c4bd4ac7c3 100644
--- a/test/porousmediumflow/3p3c/implicit/columnxylolspatialparams.hh
+++ b/test/porousmediumflow/3p3c/implicit/columnxylolspatialparams.hh
@@ -24,7 +24,7 @@
 #ifndef DUMUX_COLUMNXYLOL_SPATIAL_PARAMS_HH
 #define DUMUX_COLUMNXYLOL_SPATIAL_PARAMS_HH
 
-#include <dumux/implicit/3p3c/3p3cindices.hh>
+#include <dumux/porousmediumflow/3p3c/implicit/indices.hh>
 #include <dumux/material/spatialparams/implicitspatialparams.hh>
 #include <dumux/material/fluidmatrixinteractions/3p/regularizedparkervangen3p.hh>
 #include <dumux/material/fluidmatrixinteractions/3p/regularizedparkervangen3pparams.hh>
diff --git a/test/porousmediumflow/3p3c/implicit/infiltrationproblem.hh b/test/porousmediumflow/3p3c/implicit/infiltrationproblem.hh
index 8eaf28c0ed..5a3129a3ec 100644
--- a/test/porousmediumflow/3p3c/implicit/infiltrationproblem.hh
+++ b/test/porousmediumflow/3p3c/implicit/infiltrationproblem.hh
@@ -29,7 +29,7 @@
 
 #include <dumux/material/fluidsystems/h2oairmesitylenefluidsystem.hh>
 
-#include <dumux/implicit/3p3c/3p3cmodel.hh>
+#include <dumux/porousmediumflow/3p3c/implicit/model.hh>
 #include <dumux/porousmediumflow/implicit/problem.hh>
 
 #include "infiltrationspatialparameters.hh"
diff --git a/test/porousmediumflow/3p3c/implicit/infiltrationspatialparameters.hh b/test/porousmediumflow/3p3c/implicit/infiltrationspatialparameters.hh
index e5b22b8677..024e32bffd 100644
--- a/test/porousmediumflow/3p3c/implicit/infiltrationspatialparameters.hh
+++ b/test/porousmediumflow/3p3c/implicit/infiltrationspatialparameters.hh
@@ -26,7 +26,7 @@
 #ifndef DUMUX_INFILTRATION_SPATIAL_PARAMETERS_HH
 #define DUMUX_INFILTRATION_SPATIAL_PARAMETERS_HH
 
-#include <dumux/implicit/3p3c/3p3cindices.hh>
+#include <dumux/porousmediumflow/3p3c/implicit/indices.hh>
 #include <dumux/material/spatialparams/implicitspatialparams.hh>
 #include <dumux/material/fluidmatrixinteractions/3p/regularizedparkervangen3p.hh>
 #include <dumux/material/fluidmatrixinteractions/3p/regularizedparkervangen3pparams.hh>
diff --git a/test/porousmediumflow/3p3c/implicit/kuevetteproblem.hh b/test/porousmediumflow/3p3c/implicit/kuevetteproblem.hh
index 0b5dba8358..2f07ac940f 100644
--- a/test/porousmediumflow/3p3c/implicit/kuevetteproblem.hh
+++ b/test/porousmediumflow/3p3c/implicit/kuevetteproblem.hh
@@ -31,7 +31,7 @@
 
 #include <dumux/material/fluidsystems/h2oairmesitylenefluidsystem.hh>
 
-#include <dumux/implicit/3p3c/3p3cmodel.hh>
+#include <dumux/porousmediumflow/3p3c/implicit/model.hh>
 #include <dumux/porousmediumflow/implicit/problem.hh>
 
 #include "kuevettespatialparams.hh"
diff --git a/test/porousmediumflow/3p3c/implicit/kuevettespatialparams.hh b/test/porousmediumflow/3p3c/implicit/kuevettespatialparams.hh
index 1bd6bbec7f..39f1e2fc1d 100644
--- a/test/porousmediumflow/3p3c/implicit/kuevettespatialparams.hh
+++ b/test/porousmediumflow/3p3c/implicit/kuevettespatialparams.hh
@@ -26,7 +26,7 @@
 
 #include <dune/common/float_cmp.hh>
 
-#include <dumux/implicit/3p3c/3p3cindices.hh>
+#include <dumux/porousmediumflow/3p3c/implicit/indices.hh>
 #include <dumux/material/spatialparams/implicitspatialparams.hh>
 #include <dumux/material/fluidmatrixinteractions/3p/regularizedparkervangen3p.hh>
 #include <dumux/material/fluidmatrixinteractions/3p/regularizedparkervangen3pparams.hh>
-- 
GitLab