diff --git a/dune/stuff/functions.hh b/dune/stuff/functions.hh
index 2a75266c433f88c34746e0fa7a09fab1ce656ddc..528477d8e5417d71799d2fe9de3cc7faa49dbb74 100644
--- a/dune/stuff/functions.hh
+++ b/dune/stuff/functions.hh
@@ -16,165 +16,202 @@
 #include "functions/interfaces.hh"
 #include "functions/checkerboard.hh"
 #include "functions/constant.hh"
-#include "functions/ESV2007.hh"
 #include "functions/expression.hh"
+#include "functions/flattop.hh"
+#include "functions/ESV2007.hh"
+#include "playground/functions/indicator.hh"
 #include "functions/spe10.hh"
 
 namespace Dune {
 namespace Stuff {
-namespace internal {
 
 
 /**
- *  \brief  Base class containing functions that are available for all dimension.
+ * \note If you want to add a new function FooBar, do the following: provide a definition that is available for all
+ *       template arguments, like:
+\code
+template< class E, class D, int d, class R, int r, int rC = 1 >
+class FooBar
+  : public LocalizableFunctionInterface< E, D, d, R, r, rC >
+{
+  FooBar() { static_assert(AlwaysFalse< E >::value, "Not available for these dimensions!"); }
+};
+\endcode
+ *       Every specialization that can be provided by the provider then has to define:
+\code
+static const bool available = true;
+\endcode
+ *       This is all you have to do when implementing the function. In addition you have to add the appropriate include
+ *       in this file (of course) and the appropriate type below (just like the rest, should be obvious).
  */
 template <class E, class D, int d, class R, int r, int rC = 1>
-class FunctionsProviderBase
+class FunctionsProvider
 {
 public:
   typedef LocalizableFunctionInterface<E, D, d, R, r, rC> InterfaceType;
 
-protected:
-  template <class FunctionType>
-  static std::unique_ptr<InterfaceType> call_create(const Common::Configuration& config)
+private:
+  template <class FunctionType, bool available = false>
+  struct Call
   {
-    if (config.empty())
-      return FunctionType::create();
-    else
-      return FunctionType::create(config);
-  } // ... call_create(...)
+    static std::vector<std::string> append(std::vector<std::string> in)
+    {
+      return in;
+    }
+
+    static bool compare(const std::string& /*type*/)
+    {
+      return false;
+    }
+
+    static Common::Configuration default_config(const std::string /*sub_name*/)
+    {
+      DUNE_THROW(Stuff::Exceptions::internal_error, "This should not happen!");
+      return Common::Configuration(0);
+    }
+
+    static std::unique_ptr<FunctionType> create(const Common::Configuration& /*cfg*/)
+    {
+      DUNE_THROW(Stuff::Exceptions::internal_error, "This should not happen!");
+      return std::unique_ptr<FunctionType>(nullptr);
+    }
+  }; // struct Call
 
-public:
-  static std::vector<std::string> available()
+  template <class FunctionType>
+  struct Call<FunctionType, true>
   {
-    return {Functions::Constant<E, D, d, R, r, rC>::static_id()};
-  } // ... available(...)
-
-  static Common::Configuration default_config(const std::string type = available()[0], const std::string sub_name = "")
+    static std::vector<std::string> append(std::vector<std::string> in)
+    {
+      in.push_back(FunctionType::static_id());
+      return in;
+    }
+
+    static bool compare(const std::string& type)
+    {
+      return type == FunctionType::static_id();
+    }
+
+    static Common::Configuration default_config(const std::string sub_name)
+    {
+      return FunctionType::default_config(sub_name);
+    }
+
+    static std::unique_ptr<FunctionType> create(const Common::Configuration& cfg)
+    {
+      if (cfg.empty())
+        return FunctionType::create();
+      else
+        return FunctionType::create(cfg);
+    }
+  }; // struct Call< ..., true >
+
+  template <class F>
+  static std::vector<std::string> call_append(std::vector<std::string> in)
   {
-    if (type == Functions::Constant<E, D, d, R, r, rC>::static_id())
-      return Functions::Constant<E, D, d, R, r, rC>::default_config(sub_name);
-    else
-      DUNE_THROW(Exceptions::wrong_input_given,
-                 "Requested type '" << type << "' is not a valid " << InterfaceType::static_id() << "!");
-  } // ... default_config(...)
+    return Call<F, F::available>::append(in);
+  }
 
-  static std::unique_ptr<InterfaceType> create(const std::string type = available()[0],
-                                               const Common::Configuration config = Common::Configuration())
+  template <class F>
+  static bool call_compare(const std::string& type)
   {
-    if (type == Functions::Constant<E, D, d, R, r, rC>::static_id())
-      return call_create<Functions::Constant<E, D, d, R, r, rC>>(config);
-    else
-      DUNE_THROW(Exceptions::wrong_input_given,
-                 "Requested type '" << type << "' is not a valid " << InterfaceType::static_id() << "!");
-  } // ... create(...)
-}; // class FunctionsProviderBase
-
-
-} // namespace internal
+    return Call<F, F::available>::compare(type);
+  }
 
-
-template <class E, class D, int d, class R, int r, int rC = 1>
-class FunctionsProvider : public internal::FunctionsProviderBase<E, D, d, R, r, rC>
-{
-};
-
-
-template <class E, class D, int d, class R, int r>
-class FunctionsProvider<E, D, d, R, r, 1> : public internal::FunctionsProviderBase<E, D, d, R, r, 1>
-{
-  static const unsigned int rC = 1;
-  typedef internal::FunctionsProviderBase<E, D, d, R, r, rC> BaseType;
-
-public:
-  using typename BaseType::InterfaceType;
-
-  static std::vector<std::string> available()
+  template <class F>
+  static Common::Configuration call_default_config(const std::string sub_name)
   {
-    auto base = BaseType::available();
-    base.push_back(Functions::Expression<E, D, d, R, r, rC>::static_id());
-    base.push_back(Functions::Checkerboard<E, D, d, R, r, rC>::static_id());
-    return base;
-  } // ... available(...)
+    return Call<F, F::available>::default_config(sub_name);
+  }
 
-  static Common::Configuration default_config(const std::string type = available()[0], const std::string sub_name = "")
+  template <class F>
+  static std::unique_ptr<F> call_create(const Common::Configuration& cfg)
   {
-    if (type == Functions::Expression<E, D, d, R, r, rC>::static_id())
-      return Functions::Expression<E, D, d, R, r, rC>::default_config(sub_name);
-    else if (type == Functions::Checkerboard<E, D, d, R, r, rC>::static_id())
-      return Functions::Checkerboard<E, D, d, R, r, rC>::default_config(sub_name);
-    else
-      return BaseType::default_config(type, sub_name);
-  } // ... default_config(...)
+    return Call<F, F::available>::create(cfg);
+  }
 
-  static std::unique_ptr<InterfaceType> create(const std::string type = available()[0],
-                                               const Common::Configuration config = Common::Configuration())
+  static std::string available_as_str()
   {
-    if (type == Functions::Expression<E, D, d, R, r, rC>::static_id())
-      return BaseType::template call_create<Functions::Expression<E, D, d, R, r, rC>>(config);
-    else if (type == Functions::Checkerboard<E, D, d, R, r, rC>::static_id())
-      return BaseType::template call_create<Functions::Checkerboard<E, D, d, R, r, rC>>(config);
-    else
-      return BaseType::create(type, config);
-  } // ... create(...)
-}; // class FunctionsProvider< ..., 1 >
-
-
-template <class E, class D, class R>
-class FunctionsProvider<E, D, 2, R, 1, 1> : public internal::FunctionsProviderBase<E, D, 2, R, 1, 1>
-{
-  static const unsigned int d  = 2;
-  static const unsigned int r  = 1;
-  static const unsigned int rC = 1;
-  typedef internal::FunctionsProviderBase<E, D, d, R, r, rC> BaseType;
+    std::string ret = "";
+    const auto vals = available();
+    if (vals.size() > 0) {
+      ret += vals[0];
+      for (size_t ii = 1; ii < vals.size(); ++ii)
+        ret += ", " + vals[ii];
+    }
+    return ret;
+  } // ... available_as_str(...)
+
+  typedef Functions::Checkerboard<E, D, d, R, r, rC> CheckerboardType;
+  typedef Functions::Constant<E, D, d, R, r, rC> ConstantType;
+  typedef Functions::Expression<E, D, d, R, r, rC> ExpressionType;
+  typedef Functions::FlatTop<E, D, d, R, r, rC> FlattopType;
+  typedef Functions::ESV2007::Testcase1Force<E, D, d, R, r, rC> ESV2007Testcase1ForceType;
+  typedef Functions::ESV2007::Testcase1ExactSolution<E, D, d, R, r, rC> ESV2007Testcase1ExactSolutionType;
+  typedef Functions::Indicator<E, D, d, R, r, rC> IndicatorType;
+  typedef Functions::Spe10::Model1<E, D, d, R, r, rC> Spe10Model1Type;
 
 public:
-  using typename BaseType::InterfaceType;
-
   static std::vector<std::string> available()
   {
-    auto base = BaseType::available();
-    base.push_back(Functions::Expression<E, D, d, R, r, rC>::static_id());
-    base.push_back(Functions::Checkerboard<E, D, d, R, r, rC>::static_id());
-    base.push_back(Functions::ESV2007::Testcase1Force<E, D, d, R, r, rC>::static_id());
-    base.push_back(Functions::ESV2007::Testcase1ExactSolution<E, D, d, R, r, rC>::static_id());
-    base.push_back(Functions::Spe10::Model1<E, D, d, R, r, rC>::static_id());
-    return base;
+    std::vector<std::string> ret;
+    ret = call_append<CheckerboardType>(ret);
+    ret = call_append<ConstantType>(ret);
+    ret = call_append<ExpressionType>(ret);
+    ret = call_append<FlattopType>(ret);
+    ret = call_append<ESV2007Testcase1ForceType>(ret);
+    ret = call_append<ESV2007Testcase1ExactSolutionType>(ret);
+    ret = call_append<IndicatorType>(ret);
+    ret = call_append<Spe10Model1Type>(ret);
+    return ret;
   } // ... available(...)
 
-  static Common::Configuration default_config(const std::string type = available()[0], const std::string sub_name = "")
+  static Common::Configuration default_config(const std::string type, const std::string sub_name = "")
   {
-    if (type == Functions::Expression<E, D, d, R, r, rC>::static_id())
-      return Functions::Expression<E, D, d, R, r, rC>::default_config(sub_name);
-    else if (type == Functions::Checkerboard<E, D, d, R, r, rC>::static_id())
-      return Functions::Checkerboard<E, D, d, R, r, rC>::default_config(sub_name);
-    else if (type == Functions::ESV2007::Testcase1Force<E, D, d, R, r, rC>::static_id())
-      return Functions::ESV2007::Testcase1Force<E, D, d, R, r, rC>::default_config(sub_name);
-    else if (type == Functions::ESV2007::Testcase1ExactSolution<E, D, d, R, r, rC>::static_id())
-      return Functions::ESV2007::Testcase1ExactSolution<E, D, d, R, r, rC>::default_config(sub_name);
-    else if (type == Functions::Spe10::Model1<E, D, d, R, r, rC>::static_id())
-      return Functions::Spe10::Model1<E, D, d, R, r, rC>::default_config(sub_name);
+    if (call_compare<CheckerboardType>(type))
+      return call_default_config<CheckerboardType>(sub_name);
+    else if (call_compare<ConstantType>(type))
+      return call_default_config<ConstantType>(sub_name);
+    else if (call_compare<ExpressionType>(type))
+      return call_default_config<ExpressionType>(sub_name);
+    else if (call_compare<FlattopType>(type))
+      return call_default_config<FlattopType>(sub_name);
+    else if (call_compare<ESV2007Testcase1ForceType>(type))
+      return call_default_config<ESV2007Testcase1ForceType>(sub_name);
+    else if (call_compare<ESV2007Testcase1ExactSolutionType>(type))
+      return call_default_config<ESV2007Testcase1ExactSolutionType>(sub_name);
+    else if (call_compare<IndicatorType>(type))
+      return call_default_config<IndicatorType>(sub_name);
+    else if (call_compare<Spe10Model1Type>(type))
+      return call_default_config<Spe10Model1Type>(sub_name);
     else
-      return BaseType::default_config(type, sub_name);
+      DUNE_THROW(Exceptions::wrong_input_given,
+                 "Requested type '" << type << "' is not one of:\n  " << available_as_str());
   } // ... default_config(...)
 
   static std::unique_ptr<InterfaceType> create(const std::string type = available()[0],
-                                               const Common::Configuration config = Common::Configuration())
+                                               const Common::Configuration cfg = Common::Configuration())
   {
-    if (type == Functions::Expression<E, D, d, R, r, rC>::static_id())
-      return BaseType::template call_create<Functions::Expression<E, D, d, R, r, rC>>(config);
-    else if (type == Functions::Checkerboard<E, D, d, R, r, rC>::static_id())
-      return BaseType::template call_create<Functions::Checkerboard<E, D, d, R, r, rC>>(config);
-    else if (type == Functions::ESV2007::Testcase1Force<E, D, d, R, r, rC>::static_id())
-      return BaseType::template call_create<Functions::ESV2007::Testcase1Force<E, D, d, R, r, rC>>(config);
-    else if (type == Functions::ESV2007::Testcase1ExactSolution<E, D, d, R, r, rC>::static_id())
-      return BaseType::template call_create<Functions::ESV2007::Testcase1ExactSolution<E, D, d, R, r, rC>>(config);
-    else if (type == Functions::Spe10::Model1<E, D, d, R, r, rC>::static_id())
-      return BaseType::template call_create<Functions::Spe10::Model1<E, D, d, R, r, rC>>(config);
+    if (call_compare<CheckerboardType>(type))
+      return call_create<CheckerboardType>(cfg);
+    else if (call_compare<ConstantType>(type))
+      return call_create<ConstantType>(cfg);
+    else if (call_compare<ExpressionType>(type))
+      return call_create<ExpressionType>(cfg);
+    else if (call_compare<FlattopType>(type))
+      return call_create<FlattopType>(cfg);
+    else if (call_compare<ESV2007Testcase1ForceType>(type))
+      return call_create<ESV2007Testcase1ForceType>(cfg);
+    else if (call_compare<ESV2007Testcase1ExactSolutionType>(type))
+      return call_create<ESV2007Testcase1ExactSolutionType>(cfg);
+    else if (call_compare<IndicatorType>(type))
+      return call_create<IndicatorType>(cfg);
+    else if (call_compare<Spe10Model1Type>(type))
+      return call_create<Spe10Model1Type>(cfg);
     else
-      return BaseType::create(type, config);
+      DUNE_THROW(Exceptions::wrong_input_given,
+                 "Requested type '" << type << "' is not one of:\n  " << available_as_str());
   } // ... create(...)
-}; // class FunctionsProvider< ..., 2, 1, 1 >
+}; // class FunctionsProvider
 
 
 } // namespace Stuff
diff --git a/dune/stuff/functions/ESV2007.hh b/dune/stuff/functions/ESV2007.hh
index a6ab2caf26442dacfb1124e95d5fe3c1ebe98738..d9c3ccaf266d1398be6a9f4e53909824d8bb74bc 100644
--- a/dune/stuff/functions/ESV2007.hh
+++ b/dune/stuff/functions/ESV2007.hh
@@ -187,10 +187,13 @@ private:
 namespace ESV2007 {
 
 
-template <class EntityImp, class DomainFieldImp, int domainDim, class RangeFieldImp, int rangeDim, int rangeDimCols = 1>
-class Testcase1Force
+template <class E, class D, int d, class R, int r, int rC = 1>
+class Testcase1Force : public LocalizableFunctionInterface<E, D, d, R, r, rC>
 {
-  static_assert(AlwaysFalse<EntityImp>::value, "Not available for these dimensions!");
+  Testcase1Force()
+  {
+    static_assert(AlwaysFalse<E>::value, "Not available for these dimensions!");
+  }
 };
 
 
@@ -207,6 +210,8 @@ public:
   using typename BaseType::RangeType;
   using typename BaseType::JacobianRangeType;
 
+  static const bool available = true;
+
   static std::string static_id()
   {
     return BaseType::static_id() + ".ESV2007.testcase1.force";
@@ -295,10 +300,13 @@ private:
 }; // class Testcase1Force
 
 
-template <class EntityImp, class DomainFieldImp, int domainDim, class RangeFieldImp, int rangeDim, int rangeDimCols = 1>
-class Testcase1ExactSolution
+template <class E, class D, int d, class R, int r, int rC = 1>
+class Testcase1ExactSolution : public LocalizableFunctionInterface<E, D, d, R, r, rC>
 {
-  static_assert(AlwaysFalse<EntityImp>::value, "Not available for these dimensions!");
+  Testcase1ExactSolution()
+  {
+    static_assert(AlwaysFalse<E>::value, "Not available for these dimensions!");
+  }
 };
 
 
@@ -315,6 +323,8 @@ public:
   using typename BaseType::RangeType;
   using typename BaseType::JacobianRangeType;
 
+  static const bool available = true;
+
   static std::string static_id()
   {
     return BaseType::static_id() + ".ESV2007.testcase1.exactsolution";
diff --git a/dune/stuff/functions/checkerboard.hh b/dune/stuff/functions/checkerboard.hh
index f23a2621bdcea1ce3ea0a8f1049df12d99df1bda..b3bbe4f9ccb16e682468a612ef2fe1508a14b952 100644
--- a/dune/stuff/functions/checkerboard.hh
+++ b/dune/stuff/functions/checkerboard.hh
@@ -97,6 +97,8 @@ public:
 
   typedef typename BaseType::JacobianRangeType JacobianRangeType;
 
+  static const bool available = true;
+
   static std::string static_id()
   {
     return BaseType::static_id() + ".checkerboard";
diff --git a/dune/stuff/functions/constant.hh b/dune/stuff/functions/constant.hh
index 22233dfeca9c3db3de388d9b26bdc11187e28e79..ef95c3c99af4f26a1085650e327457f88506f4d5 100644
--- a/dune/stuff/functions/constant.hh
+++ b/dune/stuff/functions/constant.hh
@@ -91,6 +91,8 @@ public:
 
   using typename BaseType::LocalfunctionType;
 
+  static const bool available = true;
+
   static std::string static_id()
   {
     return BaseType::static_id() + ".constant";
diff --git a/dune/stuff/functions/expression.hh b/dune/stuff/functions/expression.hh
index 57907bd1008b644b4825f85639f13548a4dd9f55..1b608488da1a8ff990d9d41d52d6a19bfe445d3a 100644
--- a/dune/stuff/functions/expression.hh
+++ b/dune/stuff/functions/expression.hh
@@ -201,6 +201,8 @@ public:
 
   typedef typename BaseType::JacobianRangeType JacobianRangeType;
 
+  static const bool available = true;
+
   static std::string static_id()
   {
     return BaseType::static_id() + ".expression";
diff --git a/dune/stuff/functions/flattop.hh b/dune/stuff/functions/flattop.hh
index aded8d7dfa3c6b229f167c4f68e4849d1f1a889c..22688d91ba32010d8bf3ed4d7efe7e1a7c1879f7 100644
--- a/dune/stuff/functions/flattop.hh
+++ b/dune/stuff/functions/flattop.hh
@@ -25,9 +25,12 @@ namespace Functions {
  *           Subsection 2.1.1
  */
 template <class E, class D, int d, class R, int r, int rC = 1>
-class FlatTop
+class FlatTop : public LocalizableFunctionInterface<E, D, d, R, r, rC>
 {
-  static_assert(AlwaysFalse<E>::value, "Not available for these dimensions!");
+  FlatTop()
+  {
+    static_assert(AlwaysFalse<E>::value, "Not available for these dimensions!");
+  }
 };
 
 
@@ -45,6 +48,8 @@ public:
   typedef typename BaseType::RangeType RangeType;
   typedef typename BaseType::RangeFieldType RangeFieldType;
 
+  static const bool available = true;
+
   static std::string static_id()
   {
     return BaseType::static_id() + ".flattop";
diff --git a/dune/stuff/functions/interfaces.hh b/dune/stuff/functions/interfaces.hh
index e9560777a670d086830a00793d58b0765c988994..8e97ff10f674bbf5db7e3c65be46cff08e833216 100644
--- a/dune/stuff/functions/interfaces.hh
+++ b/dune/stuff/functions/interfaces.hh
@@ -323,6 +323,8 @@ public:
   typedef typename LocalfunctionType::RangeType RangeType;
   typedef typename LocalfunctionType::JacobianRangeType JacobianRangeType;
 
+  static const bool available = false;
+
   typedef Functions::Difference<ThisType, ThisType> DifferenceType;
   typedef Functions::Sum<ThisType, ThisType> SumType;
 
diff --git a/dune/stuff/functions/spe10.hh b/dune/stuff/functions/spe10.hh
index e0b25609a9fda1e38ddaff02ccf1965fe07dc673..a39819bee8d2d8d2614fb91713ebfaf1f62b9c44 100644
--- a/dune/stuff/functions/spe10.hh
+++ b/dune/stuff/functions/spe10.hh
@@ -63,6 +63,8 @@ public:
   static const int dimRange = BaseType::dimRange;
   typedef typename BaseType::RangeType RangeType;
 
+  static const bool available = true;
+
   static std::string static_id()
   {
     return LocalizableFunctionInterface<EntityImp, DomainFieldImp, 2, RangeFieldImp, 1, 1>::static_id()
@@ -151,10 +153,13 @@ public:
 
 
 // default, to allow for specialization
-template <class EntityImp, class DomainFieldImp, int domainDim, class RangeFieldImp, int rangeDim, int rangeDimCols = 1>
-class Model1
+template <class E, class D, int d, class R, int r, int rC = 1>
+class Model1 : public LocalizableFunctionInterface<E, D, d, R, r, rC>
 {
-  static_assert(AlwaysFalse<EntityImp>::value, "Not available for these dimensions!");
+  Model1()
+  {
+    static_assert(AlwaysFalse<E>::value, "Not available for these dimensions!");
+  }
 };