diff --git a/dumux/decoupled/2p2c/2p2cproperties.hh b/dumux/decoupled/2p2c/2p2cproperties.hh
index ff40676991d13524bb966e9a5565ae0f937e7124..851ed2018e0d23d74f83b89e12abe5f014269f17 100644
--- a/dumux/decoupled/2p2c/2p2cproperties.hh
+++ b/dumux/decoupled/2p2c/2p2cproperties.hh
@@ -75,7 +75,7 @@ NEW_PROP_TAG( VelocityFormulation); //!< The formulation of the model
 NEW_PROP_TAG( EnableCompressibility);// ! Returns whether compressibility is allowed
 NEW_PROP_TAG( EnableCapillarity); //!< Returns whether capillarity is regarded
 NEW_PROP_TAG( BoundaryMobility );
-NEW_PROP_TAG( NumDensityTransport );
+NEW_PROP_TAG( RestrictFluxInTransport ); //!< Restrict flux if direction reverses after pressure equation
 NEW_PROP_TAG( ErrorTermFactor );
 NEW_PROP_TAG( ErrorTermLowerBound );
 NEW_PROP_TAG( ErrorTermUpperBound );
@@ -149,8 +149,8 @@ SET_BOOL_PROP(DecoupledTwoPTwoC, EnableCompressibility, true);
 //! Faces are regarded from both sides
 SET_BOOL_PROP(DecoupledTwoPTwoC, VisitFacesOnlyOnce, false);
 SET_BOOL_PROP(DecoupledTwoPTwoC, EnableCapillarity, false);
-//! Disable transport of numerical density (e.g. inclusion of error in transport)
-SET_BOOL_PROP(DecoupledTwoPTwoC, NumDensityTransport, false);
+//!< Restrict (no upwind) flux in transport step if direction reverses after pressure equation
+SET_BOOL_PROP(DecoupledTwoPTwoC, RestrictFluxInTransport, true);
 
 SET_PROP(DecoupledTwoPTwoC, BoundaryMobility)
 {
diff --git a/dumux/decoupled/2p2c/cellData2p2c.hh b/dumux/decoupled/2p2c/cellData2p2c.hh
index 2e069cb336910ed35084c8439919a4486519a580..f9f721dce19153abd7f3a403287b022d5a5ebaf6 100644
--- a/dumux/decoupled/2p2c/cellData2p2c.hh
+++ b/dumux/decoupled/2p2c/cellData2p2c.hh
@@ -24,7 +24,7 @@
 
 #include "2p2cproperties.hh"
 #include <dumux/decoupled/2p2c/dec2p2cfluidstate.hh>
-//#include "fluxData2p2c.hh"
+#include "fluxData2p2c.hh"
 
 /**
  * @file
@@ -51,7 +51,7 @@ class CellData2P2C
 private:
     typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
     typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
-//    typedef FluxData2P2C<TypeTag> FluxData;
+    typedef FluxData2P2C<TypeTag> FluxData;
     typedef typename GET_PROP_TYPE(TypeTag, FluidState) FluidState;
 
     enum
@@ -76,7 +76,6 @@ protected:
     Scalar mobility_[numPhases];
 
     //numerical quantities
-    Scalar numericalDensity_[numPhases];
     Scalar volumeError_;
     Scalar errorCorrection_;
     Scalar dv_dp_;
@@ -87,7 +86,7 @@ protected:
     Scalar perimeter_;
 
     FluidState* fluidState_;
-//    FluxData fluxData_;
+    FluxData fluxData_;
 public:
 
     //! Constructor for a local CellData object
@@ -96,8 +95,6 @@ public:
     {
         for (int i = 0; i < numPhases;i++)
         {
-            mobility_[i] = 0.0;
-            numericalDensity_[i] = 0.0;
             mobility_[i] = 0.0;
             dv_[i] = 0.0;
         }
@@ -109,15 +106,15 @@ public:
         perimeter_ = 0.;
     }
 
-//    FluxData& setFluxData()
-//    {
-//        return fluxData_;
-//    }
-//
-//    const FluxData& fluxData() const
-//    {
-//        return fluxData_;
-//    }
+    FluxData& fluxData()
+    {
+        return fluxData_;
+    }
+
+    const FluxData& fluxData() const
+    {
+        return fluxData_;
+    }
 
 
     /*! \name Acess to primary variables */
@@ -189,22 +186,6 @@ public:
         mobility_[phaseIdx]=value;
     }
 
-    //! Return numerical density \f$\mathrm{[kg/m^3]}\f$.
-    /** Returns the real fluid density if the whole pore volume
-     * was filled. This quantity equals the real density scaled with
-     * the volume error.
-     * @param phaseIdx index of the Phase
-     */
-    Scalar& numericalDensity(int phaseIdx)
-    {
-        return numericalDensity_[phaseIdx];
-    }
-    //! Return numerical density
-    const Scalar& numericalDensity(int phaseIdx) const
-    {
-        return numericalDensity_[phaseIdx];
-    }
-
     //! Return the volume error [-].
     /** This quantity stands for the deviation of real fluid volume
      * to available pore space.
@@ -377,6 +358,23 @@ public:
         volumeDerivativesAvailable_ = false;
     }
 
+    //! Indicates if current cell is the upwind cell for a given interface
+    /* @param indexInInside Local face index seen from current cell
+     * @param phaseIdx The index of the phase
+     */
+    const bool& isUpwindCell(int indexInInside, int phaseIdx) const
+    {
+        return fluxData_.isUpwindCell(indexInInside, phaseIdx);
+    }
+    //! Specifies if current cell is the upwind cell for a given interface
+    /* @param indexInInside Local face index seen from current cell
+     * @param phaseIdx The index of the phase
+     * @param value Value: true (->outflow) or false (-> inflow)
+     */
+    void setUpwindCell(int indexInInside, int phaseIdx, bool value)
+    {
+        fluxData_.setUpwindCell(indexInInside, phaseIdx, value);
+    }
 
 };
 }
diff --git a/dumux/decoupled/2p2c/fluxData2p2c.hh b/dumux/decoupled/2p2c/fluxData2p2c.hh
new file mode 100644
index 0000000000000000000000000000000000000000..f2b893d4d04484f9c9d4d359145c4a0a8e30a9bf
--- /dev/null
+++ b/dumux/decoupled/2p2c/fluxData2p2c.hh
@@ -0,0 +1,149 @@
+// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+// vi: set et ts=4 sw=4 sts=4:
+/*****************************************************************************
+ *   Copyright (C) 2011 by Markus Wolff                                      *
+ *   Institute for Modelling Hydraulic and Environmental Systems             *
+ *   University of Stuttgart, Germany                                        *
+ *   email: <givenname>.<name>@iws.uni-stuttgart.de                          *
+ *                                                                           *
+ *   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_FLUXDATA2P2C_HH
+#define DUMUX_FLUXDATA2P2C_HH
+
+/**
+ * @file
+ * @brief  Class including the variables and data of discretized data of the constitutive relations
+ * @author Markus Wolff
+ */
+
+namespace Dumux
+{
+/*!
+ * \ingroup IMPES
+ */
+//! Class including the variables and data of discretized data of the constitutive relations.
+/*! The variables of two-phase flow, which are one pressure and one saturation are stored in this class.
+ * Additionally, a velocity needed in the transport part of the decoupled two-phase flow is stored, as well as discretized data of constitutive relationships like
+ * mobilities, fractional flow functions and capillary pressure. Thus, they have to be callculated just once in every time step or every iteration step.
+ *
+ * @tparam TypeTag The Type Tag
+ 1*/
+template<class TypeTag>
+class FluxData2P2C
+{
+private:
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(Scalar)) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(GridView)) GridView;
+    typedef typename GridView::IntersectionIterator IntersectionIterator;
+    typedef typename GridView::Traits::template Codim<0>::Entity Element;
+
+    enum
+    {
+        dim = GridView::dimension, dimWorld = GridView::dimensionworld
+    };
+
+    typedef typename GET_PROP_TYPE(TypeTag, PTAG(Indices)) Indices;
+
+    enum
+    {
+        wPhaseIdx = Indices::wPhaseIdx, nPhaseIdx = Indices::nPhaseIdx
+    };
+
+    enum
+    {
+        numEquations = GET_PROP_VALUE(TypeTag, PTAG(NumEq))
+    };
+
+    typename Dune::BlockVector<typename Dune::FieldVector<bool, numEquations>> isUpwindCell_;
+
+public:
+
+    //! Constructs a VariableClass object
+    /**
+     *  @param gridView a DUNE gridview object corresponding to diffusion and transport equation
+     */
+
+    FluxData2P2C()
+    {
+        isUpwindCell_.resize(2 * dim);
+        for (int i = 0; i<2*dim; i++)
+        {
+            isUpwindCell_[i] = false;
+        }
+    }
+    void resize(int size)
+    {
+        isUpwindCell_.resize(size);
+    }
+    /** functions returning upwind information **/
+    const bool& isUpwindCell(int indexInInside, int equationIdx) const
+    {
+        return isUpwindCell_[indexInInside][equationIdx];
+    }
+
+    void setUpwindCell(int indexInInside, int equationIdx, bool value)
+    {
+        isUpwindCell_[indexInInside][equationIdx] = value;
+    }
+
+};
+}
+#endif
+
+
+/*** in transport module:
+ *     // upwind mobility
+    double lambdaW, lambdaNW;
+    if (potentialW >= 0.)
+    {
+        lambdaW = cellDataI.mobility(wPhaseIdx);
+        cellDataI.setUpwindCell(intersection.indexInInside(), contiWEqIdx, true);
+        cellDataJ.setUpwindCell(intersection.indexInOutside(), contiWEqIdx, false);
+    }
+    else
+    {
+        lambdaW = cellDataJ.mobility(wPhaseIdx);
+        cellDataJ.setUpwindCell(intersection.indexInOutside(), contiWEqIdx, true);
+        cellDataI.setUpwindCell(intersection.indexInInside(), contiWEqIdx, false);
+    }
+
+    if (potentialNW >= 0.)
+    {
+        lambdaNW = cellDataI.mobility(nPhaseIdx);
+        cellDataI.setUpwindCell(intersection.indexInInside(), contiNEqIdx, true);
+        cellDataJ.setUpwindCell(intersection.indexInOutside(), contiNEqIdx, false);
+    }
+    else
+    {
+        lambdaW = cellDataJ.mobility(nPhaseIdx);
+        cellDataJ.setUpwindCell(intersection.indexInOutside(), contiNEqIdx, true);
+        cellDataI.setUpwindCell(intersection.indexInInside(), contiNEqIdx, false);
+    }
+
+
+    in cellData:
+
+    //! Acess to flux data
+    bool& isUpwindCell(int indexInInside, int equationIdx) const
+    {
+        return fluxData_.isUpwindCell(indexInInside, equationIdx);
+    }
+
+    void setUpwindCell(int indexInInside, int equationIdx, bool value)
+    {
+        fluxData_.setUpwindCell(indexInInside, equationIdx, value);
+    }
+ */
+
diff --git a/dumux/decoupled/2p2c/fvpressure2p2c.hh b/dumux/decoupled/2p2c/fvpressure2p2c.hh
index 06adf310c2faed323e39dd928d2e0a8c64f8e930..da0330756c9498627d66d4a2906834bfce15948e 100644
--- a/dumux/decoupled/2p2c/fvpressure2p2c.hh
+++ b/dumux/decoupled/2p2c/fvpressure2p2c.hh
@@ -71,6 +71,8 @@ namespace Dumux
 template<class TypeTag> class FVPressure2P2C
 : public FVPressureCompositional<TypeTag>
 {
+    //the model implementation
+    typedef typename GET_PROP_TYPE(TypeTag, PressureModel) Implementation;
     typedef FVPressure<TypeTag> BaseType;
 
     typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
@@ -188,6 +190,14 @@ protected:
     Scalar ErrorTermLowerBound_; //!< Handling of error term: lower bound for error dampening
     Scalar ErrorTermUpperBound_; //!< Handling of error term: upper bound for error dampening
     static constexpr int pressureType = GET_PROP_VALUE(TypeTag, PressureFormulation); //!< gives kind of pressure used (\f$ 0 = p_w \f$, \f$ 1 = p_n \f$, \f$ 2 = p_{global} \f$)
+private:
+    //! Returns the implementation of the problem (i.e. static polymorphism)
+    Implementation &asImp_()
+    {   return *static_cast<Implementation *>(this);}
+
+    //! \copydoc Dumux::IMPETProblem::asImp_()
+    const Implementation &asImp_() const
+    {   return *static_cast<const Implementation *>(this);}
 };
 
 
@@ -313,6 +323,8 @@ void FVPressure2P2C<TypeTag>::getStorage(Dune::FieldVector<Scalar, 2>& storageEn
                             fac * (1 + x_mi - hifac*x_mi/(1-x_mi) + (hifac/(1-x_mi)-1)*erri/maxError)
                                 * cellDataI.volumeError() * volume;
     }
+    else
+        problem().variables().cellData(globalIdxI).errorCorrection() = 0.;
 
     return;
 }
@@ -442,7 +454,6 @@ void FVPressure2P2C<TypeTag>::getFlux(Dune::FieldVector<Scalar, 2>& entries,
         Scalar graddv_dC2 = (cellDataJ.dv(nPhaseIdx)
                                 - cellDataI.dv(nPhaseIdx)) / dist;
 
-
 //                    potentialW = problem().variables().potentialWetting(globalIdxI, isIndex);
 //                    potentialNW = problem().variables().potentialNonwetting(globalIdxI, isIndex);
 //
@@ -455,8 +466,8 @@ void FVPressure2P2C<TypeTag>::getFlux(Dune::FieldVector<Scalar, 2>& entries,
         Scalar densityW = rhoMeanW;
         Scalar densityNW = rhoMeanNW;
 
-        potentialW = (unitOuterNormal * unitDistVec) *(cellDataI.pressure(wPhaseIdx) - cellDataJ.pressure(wPhaseIdx))/dist;
-        potentialNW = (unitOuterNormal * unitDistVec) *(cellDataI.pressure(nPhaseIdx) - cellDataJ.pressure(nPhaseIdx))/dist;
+        potentialW = (cellDataI.pressure(wPhaseIdx) - cellDataJ.pressure(wPhaseIdx))/dist;
+        potentialNW = (cellDataI.pressure(nPhaseIdx) - cellDataJ.pressure(nPhaseIdx))/dist;
 
         potentialW += densityW * (unitDistVec * gravity_);
         potentialNW += densityNW * (unitDistVec * gravity_);
@@ -510,10 +521,10 @@ void FVPressure2P2C<TypeTag>::getFlux(Dune::FieldVector<Scalar, 2>& entries,
         }
 
         //calculate current matrix entry
-        entries[0] = faceArea * (lambdaW * dV_w + lambdaN * dV_n);
+        entries[matrix] = faceArea * (lambdaW * dV_w + lambdaN * dV_n)* (unitOuterNormal * unitDistVec);
         if(enableVolumeIntegral)
-            entries[0] -= volume * faceArea / perimeter * (lambdaW * gV_w + lambdaN * gV_n);     // = boundary integral - area integral
-        entries[0] *= fabs((permeability*unitOuterNormal)/(dist));
+            entries[matrix] -= volume * faceArea / perimeter * (lambdaW * gV_w + lambdaN * gV_n);     // = boundary integral - area integral
+        entries[matrix] *= fabs((permeability*unitDistVec)/(dist));
 
         //calculate right hand side
         entries[rhs] = faceArea  * (unitOuterNormal * unitDistVec) * (densityW * lambdaW * dV_w + densityNW * lambdaN * dV_n);
@@ -531,7 +542,7 @@ void FVPressure2P2C<TypeTag>::getFlux(Dune::FieldVector<Scalar, 2>& entries,
         case pw:
         {
             //add capillary pressure term to right hand side
-            entries[rhs] += lambdaN * dV_n * (permeability * pCGradient) * faceArea;
+            entries[rhs] += lambdaN * dV_n * (permeability * pCGradient) * faceArea* (unitOuterNormal * unitDistVec);
             if(enableVolumeIntegral)
                 entries[rhs]-= lambdaN * gV_n * (permeability * pCGradient) * volume * faceArea / perimeter;
             break;
@@ -539,7 +550,7 @@ void FVPressure2P2C<TypeTag>::getFlux(Dune::FieldVector<Scalar, 2>& entries,
         case pn:
         {
             //add capillary pressure term to right hand side
-            entries[rhs] -= lambdaW * dV_w * (permeability * pCGradient) * faceArea;
+            entries[rhs] -= lambdaW * dV_w * (permeability * pCGradient) * faceArea* (unitOuterNormal * unitDistVec);
             if(enableVolumeIntegral)
                 entries[rhs]+= lambdaW * gV_w * (permeability * pCGradient) * volume * faceArea / perimeter;
             break;
@@ -826,7 +837,7 @@ void FVPressure2P2C<TypeTag>::updateMaterialLaws()
 
         CellData& cellData = problem().variables().cellData(globalIdx);
 
-        this->updateMaterialLawsInElement(*eIt);
+        asImp_().updateMaterialLawsInElement(*eIt);
 
         maxError = std::max(maxError, fabs(cellData.volumeError()));
     }
@@ -973,8 +984,8 @@ void FVPressure2P2C<TypeTag>::updateMaterialLawsInElement(const Element& element
     // determine volume mismatch between actual fluid volume and pore volume
     Scalar sumConc = (cellData.totalConcentration(wCompIdx)
             + cellData.totalConcentration(nCompIdx));
-    Scalar massw = cellData.numericalDensity(wPhaseIdx) = sumConc * fluidState.phaseMassFraction(wPhaseIdx);
-    Scalar massn = cellData.numericalDensity(nPhaseIdx) = sumConc * fluidState.phaseMassFraction(nPhaseIdx);
+    Scalar massw = sumConc * fluidState.phaseMassFraction(wPhaseIdx);
+    Scalar massn = sumConc * fluidState.phaseMassFraction(nPhaseIdx);
 
     if ((cellData.density(wPhaseIdx)*cellData.density(nPhaseIdx)) == 0)
         DUNE_THROW(Dune::MathError, "Decoupled2p2c::postProcessUpdate: try to divide by 0 density");
diff --git a/dumux/decoupled/2p2c/fvtransport2p2c.hh b/dumux/decoupled/2p2c/fvtransport2p2c.hh
index a36c9de80428076da92369000b3282d2749f62e0..e74bf048b9b5eba3c42813f54fd9f57c6dc02b80 100644
--- a/dumux/decoupled/2p2c/fvtransport2p2c.hh
+++ b/dumux/decoupled/2p2c/fvtransport2p2c.hh
@@ -109,9 +109,11 @@ public:
 
     void updateTransportedQuantity(TransportSolutionType& updateVector);
 
+    // Function which calculates the flux update
     void getFlux(Dune::FieldVector<Scalar, 2>&, Dune::FieldVector<Scalar, 2>&,
-            const Intersection&, const CellData&);
+            const Intersection&, CellData&);
 
+    // Function which calculates the boundary flux update
     void getFluxOnBoundary(Dune::FieldVector<Scalar, 2>&, Dune::FieldVector<Scalar, 2>&,
                             const Intersection&, const CellData&);
 
@@ -192,6 +194,7 @@ public:
         totalConcentration_[wCompIdx].resize(problem.gridView().size(0));
         totalConcentration_[nCompIdx].resize(problem.gridView().size(0));
 
+        restrictFluxInTransport_ = GET_PARAM(TypeTag,bool, RestrictFluxInTransport);
     }
 
     virtual ~FVTransport2P2C()
@@ -201,8 +204,10 @@ public:
 protected:
     TransportSolutionType totalConcentration_;
     Problem& problem_;
+    bool impet_;
 
     static const int pressureType = GET_PROP_VALUE(TypeTag, PressureFormulation); //!< gives kind of pressure used (\f$ 0 = p_w \f$, \f$ 1 = p_n \f$, \f$ 2 = p_{global} \f$)
+    bool restrictFluxInTransport_;
     bool switchNormals;
 };
 
@@ -230,6 +235,8 @@ void FVTransport2P2C<TypeTag>::update(const Scalar t, Scalar& dt,
 {
     // initialize dt very large
     dt = 1E100;
+    // store if we do update Estimate for flux functions
+    impet_ = impet;
 
     // resize update vector and set to zero
     updateVec.resize(GET_PROP_VALUE(TypeTag, NumComponents));
@@ -325,7 +332,8 @@ void FVTransport2P2C<TypeTag>::updateTransportedQuantity(TransportSolutionType&
       \sum_{\alpha} \varrho_{\alpha} \lambda_{\alpha} \sum_{\kappa} X^{\kappa}_{\alpha}
     \left( \frac{p_{\alpha,j}^t - p^{t}_{\alpha,i}}{\Delta x} + \varrho_{\alpha} \mathbf{g}\right) \f]
  * Here, \f$ \mathbf{u} \f$ is the normalized vector connecting the cell centers, and \f$ \mathbf{n}_{\gamma_{ij}} \f$
- * represents the normal of the face \f$ \gamma{ij} \f$.
+ * represents the normal of the face \f$ \gamma{ij} \f$. Due to the nature of the Primay Variable, the (volume-)specific
+ * total mass concentration, this represents a mass flux per cell volume.
  * \param fluxEntries The flux entries, mass influx from cell \f$j\f$ to \f$i\f$.
  * \param timestepFlux flow velocities for timestep estimation
  * \param intersection The intersection
@@ -335,8 +343,10 @@ template<class TypeTag>
 void FVTransport2P2C<TypeTag>::getFlux(Dune::FieldVector<Scalar, 2>& fluxEntries,
                                         Dune::FieldVector<Scalar, 2>& timestepFlux,
                                         const Intersection& intersection,
-                                        const CellData& cellDataI)
+                                        CellData& cellDataI)
 {
+    fluxEntries = 0.;
+    timestepFlux = 0.;
     // cell information
     ElementPointer elementI= intersection.inside();
     int globalIdxI = problem().variables().index(*elementI);
@@ -360,17 +370,9 @@ void FVTransport2P2C<TypeTag>::getFlux(Dune::FieldVector<Scalar, 2>& fluxEntries
                             , 1e-2);
 
     Scalar densityWI (0.), densityNWI(0.);
-    if (GET_PROP_VALUE(TypeTag, NumDensityTransport))
-    {
-        densityWI= cellDataI.numericalDensity(wPhaseIdx);
-        densityNWI = cellDataI.numericalDensity(nPhaseIdx);
+    densityWI= cellDataI.density(wPhaseIdx);
+    densityNWI = cellDataI.density(nPhaseIdx);
 
-    }
-    else
-    {
-        densityWI= cellDataI.density(wPhaseIdx);
-        densityNWI = cellDataI.density(nPhaseIdx);
-    }
     // face properties
     GlobalPosition unitOuterNormal = intersection.centerUnitOuterNormal();
     if (switchNormals)
@@ -401,16 +403,8 @@ void FVTransport2P2C<TypeTag>::getFlux(Dune::FieldVector<Scalar, 2>& fluxEntries
 
     // phase densities in neighbor
     Scalar densityWJ (0.), densityNWJ(0.);
-    if (GET_PROP_VALUE(TypeTag, NumDensityTransport))
-    {
-        densityWJ = cellDataJ.numericalDensity(wPhaseIdx);
-        densityNWJ = cellDataJ.numericalDensity(nPhaseIdx);
-    }
-    else
-    {
-        densityWJ = cellDataJ.density(wPhaseIdx);
-        densityNWJ = cellDataJ.density(nPhaseIdx);
-    }
+    densityWJ = cellDataJ.density(wPhaseIdx);
+    densityNWJ = cellDataJ.density(nPhaseIdx);
 
     // average phase densities with central weighting
     double densityW_mean = (densityWI + densityWJ) * 0.5;
@@ -440,7 +434,7 @@ void FVTransport2P2C<TypeTag>::getFlux(Dune::FieldVector<Scalar, 2>& fluxEntries
     {
         potentialW = (K * unitOuterNormal) * (pressI - pressJ - pcI + pcJ) / (dist);
         potentialNW = (K * unitOuterNormal) * (pressI - pressJ) / (dist);
-break;
+        break;
     }
     }
     // add gravity term
@@ -448,16 +442,110 @@ break;
     potentialW +=  (K * gravity_)  * (unitOuterNormal * unitDistVec) * densityW_mean;
 
     // upwind mobility
-    double lambdaW, lambdaNW;
-    if (potentialW >= 0.)
-        lambdaW = cellDataI.mobility(wPhaseIdx);
-    else
-        lambdaW = cellDataJ.mobility(wPhaseIdx);
+    double lambdaW(0.), lambdaNW(0.);
+    if(!impet_ or !restrictFluxInTransport_) // perform a simple uwpind scheme
+    {
+        if (potentialW >= 0.)
+        {
+            lambdaW = cellDataI.mobility(wPhaseIdx);
+            cellDataI.setUpwindCell(intersection.indexInInside(), contiWEqIdx, true);
 
-    if (potentialNW >= 0.)
-        lambdaNW = cellDataI.mobility(nPhaseIdx);
-    else
-        lambdaNW = cellDataJ.mobility(nPhaseIdx);
+        }
+        else
+        {
+            lambdaW = cellDataJ.mobility(wPhaseIdx);
+            cellDataI.setUpwindCell(intersection.indexInInside(), contiWEqIdx, false);
+        }
+
+        if (potentialNW >= 0.)
+        {
+            lambdaNW = cellDataI.mobility(nPhaseIdx);
+            cellDataI.setUpwindCell(intersection.indexInInside(), contiNEqIdx, true);
+        }
+        else
+        {
+            lambdaNW = cellDataJ.mobility(nPhaseIdx);
+            cellDataI.setUpwindCell(intersection.indexInInside(), contiNEqIdx, false);
+        }
+    }
+    else // if new potentials indicate same flow direction as in P.E., perform upwind
+    {
+        if (potentialW >= 0. && cellDataI.isUpwindCell(intersection.indexInInside(), contiWEqIdx))
+            lambdaW = cellDataI.mobility(wPhaseIdx);
+        else if (potentialW < 0. && !cellDataI.isUpwindCell(intersection.indexInInside(), contiWEqIdx))
+            lambdaW = cellDataJ.mobility(wPhaseIdx);
+        else    // potential of w-phase does not coincide with that of P.E.
+        {
+            bool isUpwindCell = cellDataI.isUpwindCell(intersection.indexInInside(), contiWEqIdx);
+            //check if harmonic weithing is necessary
+            if (!isUpwindCell && !(cellDataI.mobility(wPhaseIdx) != 0. && cellDataJ.mobility(wPhaseIdx) == 0.)) // check if outflow induce neglected phase flux
+                lambdaW = cellDataI.mobility(wPhaseIdx);
+            else if (isUpwindCell && !(cellDataJ.mobility(wPhaseIdx) != 0. && cellDataI.mobility(wPhaseIdx) == 0.)) // check if inflow induce neglected phase flux
+                lambdaW = cellDataJ.mobility(wPhaseIdx);
+            else
+            {
+                //a) perform harmonic averageing
+                fluxEntries[wCompIdx] -= potentialW * faceArea / volume
+                        * harmonicMean(cellDataI.massFraction(wPhaseIdx, wCompIdx) * cellDataI.mobility(wPhaseIdx) * cellDataI.density(wPhaseIdx),
+                                cellDataJ.massFraction(wPhaseIdx, wCompIdx) * cellDataJ.mobility(wPhaseIdx) * cellDataJ.density(wPhaseIdx));
+                fluxEntries[nCompIdx] -= potentialW * faceArea / volume
+                        * harmonicMean(cellDataI.massFraction(wPhaseIdx, nCompIdx) * cellDataI.mobility(wPhaseIdx) * cellDataI.density(wPhaseIdx),
+                                cellDataJ.massFraction(wPhaseIdx, nCompIdx) * cellDataJ.mobility(wPhaseIdx) * cellDataJ.density(wPhaseIdx));
+                // b) timestep control
+                // for timestep control : influx
+                timestepFlux[0] += std::max(0.,
+                        - potentialW * faceArea / volume * harmonicMean(cellDataI.density(wPhaseIdx),cellDataJ.density(wPhaseIdx)));
+                // outflux
+                timestepFlux[1] += std::max(0.,
+                        potentialW * faceArea / volume * harmonicMean(cellDataI.density(wPhaseIdx),cellDataJ.density(wPhaseIdx)));
+
+                //c) stop further standard calculations
+                potentialW = 0;
+
+                //d) output (only for one side)
+                if(potentialW >= 0.)
+                    Dune::dinfo << "harmonicMean flux of phase w used from cell" << globalIdxI<< " into " << globalIdxJ <<"\n";
+            }
+        }
+
+        if (potentialNW >= 0. && cellDataI.isUpwindCell(intersection.indexInInside(), contiNEqIdx))
+            lambdaNW = cellDataI.mobility(nPhaseIdx);
+        else if (potentialNW < 0. && !cellDataI.isUpwindCell(intersection.indexInInside(), contiNEqIdx))
+            lambdaNW = cellDataJ.mobility(nPhaseIdx);
+        else    // potential of n-phase does not coincide with that of P.E.
+        {
+            bool isUpwindCell = cellDataI.isUpwindCell(intersection.indexInInside(), contiNEqIdx);
+            //check if harmonic weithing is necessary
+            if (!isUpwindCell && !(cellDataI.mobility(nPhaseIdx) != 0. && cellDataJ.mobility(nPhaseIdx) == 0.)) // check if outflow induce neglected phase flux
+                lambdaNW = cellDataI.mobility(nPhaseIdx);
+            else if (isUpwindCell && !(cellDataJ.mobility(nPhaseIdx) != 0. && cellDataI.mobility(nPhaseIdx) == 0.)) // check if inflow induce neglected phase flux
+                lambdaNW = cellDataJ.mobility(nPhaseIdx);
+            else
+            {
+                //a) perform harmonic averageing
+                fluxEntries[wCompIdx] -= potentialNW * faceArea / volume
+                        * harmonicMean(cellDataI.massFraction(nPhaseIdx, wCompIdx) * cellDataI.mobility(nPhaseIdx) * cellDataI.density(nPhaseIdx),
+                                cellDataJ.massFraction(nPhaseIdx, wCompIdx) * cellDataJ.mobility(nPhaseIdx) * cellDataJ.density(nPhaseIdx));
+                fluxEntries[nCompIdx] -= potentialNW * faceArea / volume
+                        * harmonicMean(cellDataI.massFraction(nPhaseIdx, nCompIdx) * cellDataI.mobility(nPhaseIdx) * cellDataI.density(nPhaseIdx),
+                                cellDataJ.massFraction(nPhaseIdx, nCompIdx) * cellDataJ.mobility(nPhaseIdx) * cellDataJ.density(nPhaseIdx));
+                // b) timestep control
+                // for timestep control : influx
+                timestepFlux[0] += std::max(0.,
+                        - potentialNW * faceArea / volume * harmonicMean(cellDataI.density(nPhaseIdx),cellDataJ.density(nPhaseIdx)));
+                // outflux
+                timestepFlux[1] += std::max(0.,
+                        potentialNW * faceArea / volume * harmonicMean(cellDataI.density(nPhaseIdx),cellDataJ.density(nPhaseIdx)));
+
+                //c) stop further standard calculations
+                potentialNW = 0;
+
+                //d) output (only for one side)
+                if(potentialNW >= 0.)
+                    Dune::dinfo << "harmonicMean flux of phase n used from cell" << globalIdxI<< " into " << globalIdxJ <<"\n";
+            }
+        }
+    }
 
     // calculate and standardized velocity
     double velocityJIw = std::max((-lambdaW * potentialW) * faceArea / volume, 0.0);
@@ -465,25 +553,26 @@ break;
     double velocityJIn = std::max((-lambdaNW * potentialNW) * faceArea / volume, 0.0);
     double velocityIJn = std::max(( lambdaNW * potentialNW) * faceArea / volume, 0.0);
 
-    // for timestep control
-    timestepFlux[0] = velocityJIw + velocityJIn;
+    // for timestep control : influx
+    timestepFlux[0] += velocityJIw + velocityJIn;
 
     double foutw = velocityIJw/SwmobI;
     double foutn = velocityIJn/SnmobI;
     if (std::isnan(foutw) || std::isinf(foutw) || foutw < 0) foutw = 0;
     if (std::isnan(foutn) || std::isinf(foutn) || foutn < 0) foutn = 0;
-    timestepFlux[1] = foutw + foutn;
+    timestepFlux[1] += foutw + foutn;
 
-    fluxEntries[wCompIdx] =
+    fluxEntries[wCompIdx] +=
         velocityJIw * cellDataJ.massFraction(wPhaseIdx, wCompIdx) * densityWJ
         - velocityIJw * cellDataI.massFraction(wPhaseIdx, wCompIdx) * densityWI
         + velocityJIn * cellDataJ.massFraction(nPhaseIdx, wCompIdx) * densityNWJ
         - velocityIJn * cellDataI.massFraction(nPhaseIdx, wCompIdx) * densityNWI;
-    fluxEntries[nCompIdx] =
+    fluxEntries[nCompIdx] +=
         velocityJIw * cellDataJ.massFraction(wPhaseIdx, nCompIdx) * densityWJ
         - velocityIJw * cellDataI.massFraction(wPhaseIdx, nCompIdx) * densityWI
         + velocityJIn * cellDataJ.massFraction(nPhaseIdx, nCompIdx) * densityNWJ
         - velocityIJn * cellDataI.massFraction(nPhaseIdx, nCompIdx) * densityNWI;
+
     return;
 }
 //! Get flux on Boundary
@@ -528,17 +617,8 @@ void FVTransport2P2C<TypeTag>::getFluxOnBoundary(Dune::FieldVector<Scalar, 2>& f
                             , 1e-2);
 
     Scalar densityWI (0.), densityNWI(0.);
-    if (GET_PROP_VALUE(TypeTag, NumDensityTransport))
-    {
-        densityWI= cellDataI.numericalDensity(wPhaseIdx);
-        densityNWI = cellDataI.numericalDensity(nPhaseIdx);
-
-    }
-    else
-    {
-        densityWI= cellDataI.density(wPhaseIdx);
-        densityNWI = cellDataI.density(nPhaseIdx);
-    }
+    densityWI= cellDataI.density(wPhaseIdx);
+    densityNWI = cellDataI.density(nPhaseIdx);
 
     // face properties
     GlobalPosition unitOuterNormal = intersection.centerUnitOuterNormal();