diff --git a/dumux/boxmodels/2p/2pfluidstate.hh b/dumux/boxmodels/2p/2pfluidstate.hh
index 33332ce5cb356b273e4378b074ba9726ad8977d1..96b3f4068da603b1127875a7904b2e729b1ba79e 100644
--- a/dumux/boxmodels/2p/2pfluidstate.hh
+++ b/dumux/boxmodels/2p/2pfluidstate.hh
@@ -30,6 +30,7 @@
 
 #include "2pproperties.hh"
 
+
 namespace Dumux
 {
 /*!
diff --git a/dumux/boxmodels/2p/2pmodel.hh b/dumux/boxmodels/2p/2pmodel.hh
index df2c189069e7a5359b70f43eb7ac4ca2eb286792..390272931f703effc40881459942be425f72d3b1 100644
--- a/dumux/boxmodels/2p/2pmodel.hh
+++ b/dumux/boxmodels/2p/2pmodel.hh
@@ -94,6 +94,14 @@ class TwoPModel : public BoxModel<TypeTag>
 
         nPhaseIdx = Indices::nPhaseIdx,
         wPhaseIdx = Indices::wPhaseIdx,
+
+        formulation = GET_PROP_VALUE(TypeTag, PTAG(Formulation)),
+
+        pwSn = Indices::pwSn,
+        pnSw = Indices::pnSw,
+
+        pressureIdx = Indices::pressureIdx,
+        saturationIdx = Indices::saturationIdx,
     };
     typedef Dune::FieldVector<Scalar, numPhases> PhasesVector;
     typedef Dune::FieldVector<Scalar, dim> LocalPosition;
@@ -117,6 +125,47 @@ public:
         return 1;
     }
 
+    template <class PrimaryVariables, class MaterialParams, class FluidState>
+    static void completeFluidState(const PrimaryVariables& primaryVariables,
+                                   const MaterialParams& materialParams,
+                                   FluidState& fluidState)
+    {
+        typedef typename GET_PROP_TYPE(TypeTag, PTAG(MaterialLaw)) MaterialLaw;
+
+        if (int(formulation) == pwSn) {
+            Scalar Sn = primaryVariables[saturationIdx];
+            fluidState.setSaturation(nPhaseIdx, Sn);
+            fluidState.setSaturation(wPhaseIdx, 1 - Sn);
+
+            Scalar pW = primaryVariables[pressureIdx];
+            fluidState.setPressure(wPhaseIdx, pW);
+            fluidState.setPressure(nPhaseIdx,
+                                   pW + MaterialLaw::pC(materialParams, 1 - Sn));
+        }
+        else if (int(formulation) == pnSw) {
+            Scalar Sw = primaryVariables[saturationIdx];
+            fluidState.setSaturation(wPhaseIdx, Sw);
+            fluidState.setSaturation(nPhaseIdx, 1 - Sw);
+
+            Scalar pN = primaryVariables[pressureIdx];
+            fluidState.setPressure(nPhaseIdx, pN);
+            fluidState.setPressure(wPhaseIdx,
+                                   pN - MaterialLaw::pC(materialParams, Sw));
+        }
+
+        typedef typename GET_PROP_TYPE(TypeTag, PTAG(FluidSystem)) FluidSystem;
+        typename FluidSystem::ParameterCache paramCache;
+        fluidState.setViscosity(wPhaseIdx,
+                FluidSystem::viscosity(fluidState, paramCache, wPhaseIdx));
+        fluidState.setViscosity(nPhaseIdx,
+                FluidSystem::viscosity(fluidState, paramCache, nPhaseIdx));
+
+        fluidState.setDensity(wPhaseIdx,
+                FluidSystem::density(fluidState, paramCache, wPhaseIdx));
+        fluidState.setDensity(nPhaseIdx,
+                FluidSystem::density(fluidState, paramCache, nPhaseIdx));
+    }
+
     /*!
      * \brief Append all quantities of interest which can be derived
      *        from the solution of the current time step to the VTK
diff --git a/dumux/boxmodels/2p/2ppropertydefaults.hh b/dumux/boxmodels/2p/2ppropertydefaults.hh
index c19ba5cfe2324f4099a013181c0d2ffdd1cd3ebd..394e5a4f140a61616094bd3a063b18afeead7cd3 100644
--- a/dumux/boxmodels/2p/2ppropertydefaults.hh
+++ b/dumux/boxmodels/2p/2ppropertydefaults.hh
@@ -35,7 +35,6 @@
 #include "2pindices.hh"
 #include "2pfluxvariables.hh"
 #include "2pvolumevariables.hh"
-#include "2pfluidstate.hh"
 #include "2pproperties.hh"
 
 #include <dumux/material/fluidsystems/gasphase.hh>
@@ -43,6 +42,7 @@
 #include <dumux/material/components/nullcomponent.hh>
 
 #include <dumux/material/MpNcfluidsystems/2pimmisciblefluidsystem.hh>
+#include <dumux/material/MpNcfluidstates/immisciblefluidstate.hh>
 
 namespace Dumux
 {
@@ -115,7 +115,14 @@ public:
                                              NonWettingPhase> type;
 };
 
-SET_TYPE_PROP(BoxTwoP, FluidState, TwoPFluidState<TypeTag>);
+SET_PROP(BoxTwoP, FluidState)
+{
+private:
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(Scalar)) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(FluidSystem)) FluidSystem;
+public:
+    typedef ImmiscibleFluidState<Scalar, FluidSystem> type;
+};
 
 // enable jacobian matrix recycling by default
 SET_BOOL_PROP(BoxTwoP, EnableJacobianRecycling, true);
diff --git a/dumux/boxmodels/2p/2pvolumevariables.hh b/dumux/boxmodels/2p/2pvolumevariables.hh
index ee693aecca1c7f2e27e41d044e522954d570c01c..0df5c2f0eb8285a747563faeef0df3b1788c5b56 100644
--- a/dumux/boxmodels/2p/2pvolumevariables.hh
+++ b/dumux/boxmodels/2p/2pvolumevariables.hh
@@ -28,7 +28,6 @@
 #define DUMUX_2P_VOLUME_VARIABLES_HH
 
 #include "2pproperties.hh"
-#include "2pfluidstate.hh"
 
 #include <dumux/boxmodels/common/boxvolumevariables.hh>
 
@@ -53,11 +52,13 @@ class TwoPVolumeVariables : public BoxVolumeVariables<TypeTag>
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(GridView)) GridView;
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(Problem)) Problem;
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(FluidSystem)) FluidSystem;
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(FluidState)) FluidState;
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(MaterialLaw)) MaterialLaw;
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(MaterialLawParams)) MaterialLawParams;
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(FVElementGeometry)) FVElementGeometry;
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(PrimaryVariables)) PrimaryVariables;
     typedef typename GET_PROP_TYPE(TypeTag, PTAG(TwoPIndices)) Indices;
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(Model)) Model;
 
     enum {
         numEq = GET_PROP_VALUE(TypeTag, PTAG(NumEq)),
@@ -76,7 +77,6 @@ class TwoPVolumeVariables : public BoxVolumeVariables<TypeTag>
     };
 
     typedef typename GridView::template Codim<0>::Entity Element;
-    typedef TwoPFluidState<TypeTag> FluidState;
 
 public:
     /*!
@@ -108,40 +108,25 @@ public:
                                    elemGeom,
                                    scvIdx,
                                    problem);
+        fluidState_.setTemperature(temperature_);
 
         // material law parameters
         const MaterialLawParams &materialParams =
             problem.spatialParameters().materialLawParams(element, elemGeom, scvIdx);
 
-        Scalar p[numPhases];
-        Scalar Sn;
-        if (int(formulation) == pwSn) {
-            Sn = priVars[saturationIdx];
-            p[wPhaseIdx] = priVars[pressureIdx];
-            p[nPhaseIdx] =
-                p[wPhaseIdx] +
-                MaterialLaw::pC(materialParams, 1 - Sn);
-        }
-        else if (int(formulation) == pnSw) {
-            Sn = 1 - priVars[saturationIdx];
-            p[nPhaseIdx] = priVars[pressureIdx];
-            p[wPhaseIdx] =
-                p[nPhaseIdx] -
-                MaterialLaw::pC(materialParams, 1 - Sn);
-        }
-
-        typename FluidSystem::ParameterCache paramCache;
-        fluidState_.update(paramCache, Sn, p[wPhaseIdx], p[nPhaseIdx], temperature_);
+        Model::completeFluidState(priVars, materialParams, fluidState_);
+
+        capillaryPressure_ = fluidState_.pressure(nPhaseIdx) - fluidState_.pressure(wPhaseIdx);
 
         mobility_[wPhaseIdx] =
-            MaterialLaw::krw(materialParams, 1 - Sn)
+            MaterialLaw::krw(materialParams, fluidState_.saturation(wPhaseIdx))
             /
-            FluidSystem::viscosity(fluidState_, paramCache, wPhaseIdx);
+            fluidState_.viscosity(wPhaseIdx);
 
         mobility_[nPhaseIdx] =
-            MaterialLaw::krn(materialParams, 1 - Sn)
+            MaterialLaw::krn(materialParams, fluidState_.saturation(wPhaseIdx))
             /
-            FluidSystem::viscosity(fluidState_, paramCache, wPhaseIdx);
+            fluidState_.viscosity(nPhaseIdx);
 
         // porosity
         porosity_ = problem.spatialParameters().porosity(element,
@@ -205,7 +190,7 @@ public:
      * \brief Returns the effective capillary pressure within the control volume.
      */
     Scalar capillaryPressure() const
-    { return fluidState_.capillaryPressure(); }
+    { return capillaryPressure_; }
 
     /*!
      * \brief Returns the average porosity within the control volume.
@@ -227,6 +212,7 @@ protected:
     Scalar porosity_;
     Scalar temperature_;
 
+    Scalar capillaryPressure_;
     Scalar mobility_[numPhases];
 
 private:
diff --git a/dumux/material/MpNcfluidstates/immisciblefluidstate.hh b/dumux/material/MpNcfluidstates/immisciblefluidstate.hh
index 57f6ba51941a6b7b1dbbed14c1d1186cf2476e44..69836d04a53cdd07f70ff77e68962e0e8a31d97e 100644
--- a/dumux/material/MpNcfluidstates/immisciblefluidstate.hh
+++ b/dumux/material/MpNcfluidstates/immisciblefluidstate.hh
@@ -35,12 +35,12 @@ namespace Dumux
  *        multi-phase fluid system assuming immiscibility and
  *        thermodynamic equilibrium.
  */
-template <class Scalar, class StaticParameters>
+template <class Scalar, class FluidSystem>
 class ImmiscibleFluidState
 {
 public:
-    enum { numComponents = StaticParameters::numComponents };
-    enum { numPhases = StaticParameters::numPhases };
+    static constexpr int numComponents = FluidSystem::numComponents;
+    static constexpr int numPhases = FluidSystem::numPhases;
     static_assert(numPhases == numComponents,
                   "The number of phases must be equal to the number of "
                   "components if immiscibility is assumed!");
@@ -94,7 +94,7 @@ public:
      * \brief The average molar mass of a fluid phase [kg/mol]
      */
     Scalar averageMolarMass(int phaseIdx) const
-    { return StaticParameters::molarMass(/*compIdx=*/phaseIdx); }
+    { return FluidSystem::molarMass(/*compIdx=*/phaseIdx); }
 
     /*!
      * \brief The concentration of a component in a phase [mol/m^3]