diff --git a/dune/gdt/local/integrands/elliptic-ipdg.hh b/dune/gdt/local/integrands/elliptic-ipdg.hh
index b79d79fd9266a945dda5b558192eeeb5acfb4459..ed4dcc57f7452406fe1bcb78ea8aa9f3b3d00702 100644
--- a/dune/gdt/local/integrands/elliptic-ipdg.hh
+++ b/dune/gdt/local/integrands/elliptic-ipdg.hh
@@ -13,13 +13,323 @@
 #ifndef DUNE_GDT_LOCAL_INTEGRANDS_ELLIPTIC_IPDG_HH
 #define DUNE_GDT_LOCAL_INTEGRANDS_ELLIPTIC_IPDG_HH
 
+#include <dune/xt/common/deprecated.hh>
+#include <dune/xt/functions/base/function-or-gridfunction.hh>
 #include <dune/xt/functions/interfaces/grid-function.hh>
 
 #include "interfaces.hh"
+#include "ipdg.hh"
 
 namespace Dune {
 namespace GDT {
 
+/**
+ * \brief To replace the ones in LocalEllipticIpdgIntegrands at some point.
+ */
+namespace LocalEllipticIPDGIntegrands {
+
+
+/**
+ * \note The role of symmetry_prefactor:
+ *       * -1 => NIPDG
+ *       *  0 => IIPDG
+ *       *  1 => SIPDG
+ * \note The role of the weight:
+ *       * symmetry_prefactor = 1 && weight_function = 1 => SIPDG
+ *       * symmetry_prefactor = 1 && weight_function = diffusion => SWIPDG
+ */
+template <class I>
+class InnerCoupling : public LocalQuaternaryIntersectionIntegrandInterface<I>
+{
+  using BaseType = LocalQuaternaryIntersectionIntegrandInterface<I>;
+  using ThisType = InnerCoupling<I>;
+
+public:
+  using BaseType::d;
+  using typename BaseType::DomainType;
+  using typename BaseType::E;
+  using typename BaseType::F;
+  using typename BaseType::IntersectionType;
+  using typename BaseType::LocalAnsatzBasisType;
+  using typename BaseType::LocalTestBasisType;
+
+  InnerCoupling(const double& symmetry_prefactor,
+                XT::Functions::FunctionOrGridFunction<E, d, d> diffusion,
+                XT::Functions::FunctionOrGridFunction<E, d, d> weight_function = {1.})
+    : BaseType(diffusion.parameter_type() + weight_function.parameter_type())
+    , symmetry_prefactor_(symmetry_prefactor)
+    , diffusion_(diffusion)
+    , weight_(weight_function)
+    , local_diffusion_in_(diffusion_.local_function())
+    , local_diffusion_out_(diffusion_.local_function())
+    , local_weight_in_(weight_.local_function())
+    , local_weight_out_(weight_.local_function())
+  {}
+
+  InnerCoupling(const ThisType& other)
+    : BaseType(other.parameter_type())
+    , symmetry_prefactor_(other.symmetry_prefactor_)
+    , diffusion_(other.diffusion_)
+    , weight_(other.weight_)
+    , local_diffusion_in_(diffusion_.local_function())
+    , local_diffusion_out_(diffusion_.local_function())
+    , local_weight_in_(weight_.local_function())
+    , local_weight_out_(weight_.local_function())
+  {}
+
+  InnerCoupling(ThisType&& source) = default;
+
+  std::unique_ptr<BaseType> copy() const override final
+  {
+    return std::make_unique<ThisType>(*this);
+  }
+
+protected:
+  void post_bind(const IntersectionType& intersection) override final
+  {
+    DUNE_THROW_IF(!intersection.neighbor(),
+                  Exceptions::integrand_error,
+                  "This integrand cannot be used on a boundary intersection!");
+    const auto inside_element = intersection.inside();
+    const auto outside_element = intersection.outside();
+    local_diffusion_in_->bind(inside_element);
+    local_weight_in_->bind(inside_element);
+    local_diffusion_out_->bind(outside_element);
+    local_weight_out_->bind(outside_element);
+  } // ... post_bind(...)
+
+public:
+  int order(const LocalTestBasisType& test_basis_inside,
+            const LocalAnsatzBasisType& ansatz_basis_inside,
+            const LocalTestBasisType& test_basis_outside,
+            const LocalAnsatzBasisType& ansatz_basis_outside,
+            const XT::Common::Parameter& param = {}) const override final
+  {
+    return std::max(local_diffusion_in_->order(param), local_diffusion_out_->order(param))
+           + std::max(local_weight_in_->order(), local_weight_out_->order(param))
+           + std::max(test_basis_inside.order(param), test_basis_outside.order(param))
+           + std::max(ansatz_basis_inside.order(param), ansatz_basis_outside.order(param));
+  }
+
+  void evaluate(const LocalTestBasisType& test_basis_inside,
+                const LocalAnsatzBasisType& ansatz_basis_inside,
+                const LocalTestBasisType& test_basis_outside,
+                const LocalAnsatzBasisType& ansatz_basis_outside,
+                const DomainType& point_in_reference_intersection,
+                DynamicMatrix<F>& result_in_in,
+                DynamicMatrix<F>& result_in_out,
+                DynamicMatrix<F>& result_out_in,
+                DynamicMatrix<F>& result_out_out,
+                const XT::Common::Parameter& param = {}) const override final
+  {
+    // Prepare sotrage, ...
+    this->ensure_size_and_clear_results(test_basis_inside,
+                                        ansatz_basis_inside,
+                                        test_basis_outside,
+                                        ansatz_basis_outside,
+                                        result_in_in,
+                                        result_in_out,
+                                        result_out_in,
+                                        result_out_out,
+                                        param);
+    // evaluate ...
+    const auto point_in_inside_reference_element =
+        this->intersection().geometryInInside().global(point_in_reference_intersection);
+    const auto point_in_outside_reference_element =
+        this->intersection().geometryInOutside().global(point_in_reference_intersection);
+    const auto normal = this->intersection().unitOuterNormal(point_in_reference_intersection);
+    // ... basis functions and ...
+    test_basis_inside.evaluate(point_in_inside_reference_element, test_basis_in_values_, param);
+    test_basis_inside.jacobians(point_in_inside_reference_element, test_basis_in_grads_, param);
+    test_basis_outside.evaluate(point_in_outside_reference_element, test_basis_out_values_, param);
+    test_basis_outside.jacobians(point_in_outside_reference_element, test_basis_out_grads_, param);
+    ansatz_basis_inside.evaluate(point_in_inside_reference_element, ansatz_basis_in_values_, param);
+    ansatz_basis_inside.jacobians(point_in_inside_reference_element, ansatz_basis_in_grads_, param);
+    ansatz_basis_outside.evaluate(point_in_outside_reference_element, ansatz_basis_out_values_, param);
+    ansatz_basis_outside.jacobians(point_in_outside_reference_element, ansatz_basis_out_grads_, param);
+    // ... data functions, ...
+    const auto diffusion_in = local_diffusion_in_->evaluate(point_in_inside_reference_element, param);
+    const auto diffusion_out = local_diffusion_out_->evaluate(point_in_outside_reference_element, param);
+    const auto weight_in = local_weight_in_->evaluate(point_in_inside_reference_element, param);
+    const auto weight_out = local_weight_out_->evaluate(point_in_outside_reference_element, param);
+    // compute the weighted mean ...
+    const auto delta_plus = normal * (weight_out * normal);
+    const auto delta_minus = normal * (weight_in * normal);
+    const auto weight_minus = delta_plus / (delta_plus + delta_minus);
+    const auto weight_plus = delta_minus / (delta_plus + delta_minus);
+    // ... and finally compute the integrand.
+    const size_t rows_in = test_basis_inside.size(param);
+    const size_t rows_out = test_basis_outside.size(param);
+    const size_t cols_in = ansatz_basis_inside.size(param);
+    const size_t cols_out = ansatz_basis_outside.size(param);
+    for (size_t ii = 0; ii < rows_in; ++ii) {
+      for (size_t jj = 0; jj < cols_in; ++jj) {
+        result_in_in[ii][jj] +=
+            -1.0 * weight_minus * ((diffusion_in * ansatz_basis_in_grads_[jj][0]) * normal) * test_basis_in_values_[ii];
+        result_in_in[ii][jj] += -1.0 * symmetry_prefactor_ * weight_minus * ansatz_basis_in_values_[jj]
+                                * ((diffusion_in * test_basis_in_grads_[ii][0]) * normal);
+      }
+      for (size_t jj = 0; jj < cols_out; ++jj) {
+        result_in_out[ii][jj] += -1.0 * weight_plus * ((diffusion_out * ansatz_basis_out_grads_[jj][0]) * normal)
+                                 * test_basis_in_values_[ii];
+        result_in_out[ii][jj] += symmetry_prefactor_ * weight_minus * ansatz_basis_out_values_[jj]
+                                 * ((diffusion_in * test_basis_in_grads_[ii][0]) * normal);
+      }
+    }
+    for (size_t ii = 0; ii < rows_out; ++ii) {
+      for (size_t jj = 0; jj < cols_in; ++jj) {
+        result_out_in[ii][jj] +=
+            weight_minus * ((diffusion_in * ansatz_basis_in_grads_[jj][0]) * normal) * test_basis_out_values_[ii];
+        result_out_in[ii][jj] += -1.0 * symmetry_prefactor_ * weight_plus * ansatz_basis_in_values_[jj]
+                                 * ((diffusion_out * test_basis_out_grads_[ii][0]) * normal);
+      }
+      for (size_t jj = 0; jj < cols_out; ++jj) {
+        result_out_out[ii][jj] +=
+            weight_plus * ((diffusion_out * ansatz_basis_out_grads_[jj][0]) * normal) * test_basis_out_values_[ii];
+        result_out_out[ii][jj] += symmetry_prefactor_ * weight_plus * ansatz_basis_out_values_[jj]
+                                  * ((diffusion_out * test_basis_out_grads_[ii][0]) * normal);
+      }
+    }
+  } // ... evaluate(...)
+
+private:
+  const double symmetry_prefactor_;
+  XT::Functions::FunctionOrGridFunction<E, d, d> diffusion_;
+  XT::Functions::FunctionOrGridFunction<E, d, d> weight_;
+  std::unique_ptr<typename XT::Functions::GridFunctionInterface<E, d, d>::LocalFunctionType> local_diffusion_in_;
+  std::unique_ptr<typename XT::Functions::GridFunctionInterface<E, d, d>::LocalFunctionType> local_diffusion_out_;
+  std::unique_ptr<typename XT::Functions::GridFunctionInterface<E, d, d>::LocalFunctionType> local_weight_in_;
+  std::unique_ptr<typename XT::Functions::GridFunctionInterface<E, d, d>::LocalFunctionType> local_weight_out_;
+  mutable std::vector<typename LocalTestBasisType::RangeType> test_basis_in_values_;
+  mutable std::vector<typename LocalTestBasisType::DerivativeRangeType> test_basis_in_grads_;
+  mutable std::vector<typename LocalTestBasisType::RangeType> test_basis_out_values_;
+  mutable std::vector<typename LocalTestBasisType::DerivativeRangeType> test_basis_out_grads_;
+  mutable std::vector<typename LocalAnsatzBasisType::RangeType> ansatz_basis_in_values_;
+  mutable std::vector<typename LocalAnsatzBasisType::DerivativeRangeType> ansatz_basis_in_grads_;
+  mutable std::vector<typename LocalAnsatzBasisType::RangeType> ansatz_basis_out_values_;
+  mutable std::vector<typename LocalAnsatzBasisType::DerivativeRangeType> ansatz_basis_out_grads_;
+}; // InnerCoupling
+
+
+/**
+ * \note The role of symmetry_prefactor:
+ *       * -1 => NIPDG
+ *       *  0 => IIPDG
+ *       *  1 => SIPDG
+ * \note The role of the weight:
+ *       * symmetry_prefactor = 1 && weight_function = 1 => SIPDG
+ *       * symmetry_prefactor = 1 && weight_function = diffusion => SWIPDG
+ */
+template <class I>
+class DirichletCoupling : public LocalQuaternaryIntersectionIntegrandInterface<I>
+{
+  using BaseType = LocalQuaternaryIntersectionIntegrandInterface<I>;
+  using ThisType = DirichletCoupling<I>;
+
+public:
+  using BaseType::d;
+  using typename BaseType::DomainType;
+  using typename BaseType::E;
+  using typename BaseType::F;
+  using typename BaseType::IntersectionType;
+  using typename BaseType::LocalAnsatzBasisType;
+  using typename BaseType::LocalTestBasisType;
+
+  DirichletCoupling(const double& symmetry_prefactor, XT::Functions::FunctionOrGridFunction<E, d, d> diffusion)
+    : BaseType(diffusion.parameter_type())
+    , symmetry_prefactor_(symmetry_prefactor)
+    , diffusion_(diffusion)
+    , local_diffusion_(diffusion_.local_function())
+  {}
+
+  DirichletCoupling(const ThisType& other)
+    : BaseType(other.parameter_type())
+    , symmetry_prefactor_(other.symmetry_prefactor_)
+    , diffusion_(other.diffusion_)
+    , local_diffusion_(diffusion_.local_function())
+  {}
+
+  DirichletCoupling(ThisType&& source) = default;
+
+  std::unique_ptr<BaseType> copy() const override final
+  {
+    return std::make_unique<ThisType>(*this);
+  }
+
+protected:
+  void post_bind(const IntersectionType& intersection) override final
+  {
+    const auto inside_element = intersection.inside();
+    local_diffusion_->bind(inside_element);
+  }
+
+public:
+  int order(const LocalTestBasisType& test_basis_inside,
+            const LocalAnsatzBasisType& ansatz_basis_inside,
+            const LocalTestBasisType& /*test_basis_outside*/,
+            const LocalAnsatzBasisType& /*ansatz_basis_outside*/,
+            const XT::Common::Parameter& param = {}) const override final
+  {
+    return local_diffusion_->order(param) + test_basis_inside.order(param) + ansatz_basis_inside.order(param);
+  }
+
+  void evaluate(const LocalTestBasisType& test_basis_inside,
+                const LocalAnsatzBasisType& ansatz_basis_inside,
+                const LocalTestBasisType& test_basis_outside,
+                const LocalAnsatzBasisType& ansatz_basis_outside,
+                const DomainType& point_in_reference_intersection,
+                DynamicMatrix<F>& result_in_in,
+                DynamicMatrix<F>& result_in_out,
+                DynamicMatrix<F>& result_out_in,
+                DynamicMatrix<F>& result_out_out,
+                const XT::Common::Parameter& param = {}) const override final
+  {
+    // Prepare sotrage, ...
+    this->ensure_size_and_clear_results(test_basis_inside,
+                                        ansatz_basis_inside,
+                                        test_basis_outside,
+                                        ansatz_basis_outside,
+                                        result_in_in,
+                                        result_in_out,
+                                        result_out_in,
+                                        result_out_out,
+                                        param);
+    // evaluate ...
+    const auto point_in_inside_reference_element =
+        this->intersection().geometryInInside().global(point_in_reference_intersection);
+    const auto normal = this->intersection().unitOuterNormal(point_in_reference_intersection);
+    // ... basis functions and ...
+    test_basis_inside.evaluate(point_in_inside_reference_element, test_basis_values_, param);
+    test_basis_inside.jacobians(point_in_inside_reference_element, test_basis_grads_, param);
+    ansatz_basis_inside.evaluate(point_in_inside_reference_element, ansatz_basis_values_, param);
+    ansatz_basis_inside.jacobians(point_in_inside_reference_element, ansatz_basis_grads_, param);
+    // ... data functions, ...
+    const auto diffusion = local_diffusion_->evaluate(point_in_inside_reference_element, param);
+    // ... and finally compute the integrand.
+    const size_t rows = test_basis_inside.size(param);
+    const size_t cols = ansatz_basis_inside.size(param);
+    for (size_t ii = 0; ii < rows; ++ii)
+      for (size_t jj = 0; jj < cols; ++jj) {
+        result_in_in[ii][jj] += -1.0 * ((diffusion * ansatz_basis_grads_[jj][0]) * normal) * test_basis_values_[ii];
+        result_in_in[ii][jj] +=
+            -1.0 * symmetry_prefactor_ * ansatz_basis_values_[jj] * ((diffusion * test_basis_grads_[ii][0]) * normal);
+      }
+  } // ... evaluate(...)
+
+private:
+  const double symmetry_prefactor_;
+  XT::Functions::FunctionOrGridFunction<E, d, d> diffusion_;
+  std::unique_ptr<typename XT::Functions::GridFunctionInterface<E, d, d>::LocalFunctionType> local_diffusion_;
+  mutable std::vector<typename LocalTestBasisType::RangeType> test_basis_values_;
+  mutable std::vector<typename LocalTestBasisType::DerivativeRangeType> test_basis_grads_;
+  mutable std::vector<typename LocalAnsatzBasisType::RangeType> ansatz_basis_values_;
+  mutable std::vector<typename LocalAnsatzBasisType::DerivativeRangeType> ansatz_basis_grads_;
+}; // DirichletCoupling
+
+
+} // namespace LocalEllipticIPDGIntegrands
+
+
 /**
  *  \brief      Contains local integrands for the family of interior penalty discontinuous Galerkin (IPDG)
  *              discretization schemes.
@@ -1130,7 +1440,8 @@ public:
  * \sa [Epshteyn, Riviere, 2007] for the meaning of beta
  */
 template <class I, class F = double, Method method = default_method>
-class InnerOnlyPenalty : public LocalQuaternaryIntersectionIntegrandInterface<I, 1, 1, F, F, 1, 1, F>
+class DXT_DEPRECATED_MSG("Use LocalIPDGIntegrands::InnerPenalty instead (05.08.2019)!") InnerOnlyPenalty
+  : public LocalQuaternaryIntersectionIntegrandInterface<I, 1, 1, F, F, 1, 1, F>
 {
   using BaseType = LocalQuaternaryIntersectionIntegrandInterface<I, 1, 1, F, F, 1, 1, F>;
   using ThisType = InnerOnlyPenalty<I, F, method>;
@@ -1576,11 +1887,13 @@ private:
   mutable std::vector<typename LocalAnsatzBasisType::RangeType> ansatz_basis_out_values_;
 }; //  InnerOnlyPenalty
 
+
 /**
  * \sa [Epshteyn, Riviere, 2007] for the meaning of beta
  */
 template <class I, class F = double, Method method = default_method>
-class DirichletBoundaryLhsOnlyPenalty : public LocalQuaternaryIntersectionIntegrandInterface<I, 1, 1, F, F, 1, 1, F>
+class DXT_DEPRECATED_MSG("Use LocalIPDGIntegrands::BoundaryPenalty instead (05.08.2019)!")
+    DirichletBoundaryLhsOnlyPenalty : public LocalQuaternaryIntersectionIntegrandInterface<I, 1, 1, F, F, 1, 1, F>
 {
   using BaseType = LocalQuaternaryIntersectionIntegrandInterface<I, 1, 1, F, F, 1, 1, F>;
   using ThisType = DirichletBoundaryLhsOnlyPenalty<I, F, method>;
@@ -1764,6 +2077,7 @@ private:
   mutable std::vector<typename LocalAnsatzBasisType::DerivativeRangeType> ansatz_basis_grads_;
 }; // DirichletBoundaryLhsOnlyPenalty
 
+
 } // namespace LocalEllipticIpdgIntegrands
 } // namespace GDT
 } // namespace Dune