diff --git a/dune/stuff/CMakeLists.txt b/dune/stuff/CMakeLists.txt
index 74a57788e163b623f3c79ea12d3579c4c99356a8..618e9b4f4265d41a962ac481e02e96378df5747f 100644
--- a/dune/stuff/CMakeLists.txt
+++ b/dune/stuff/CMakeLists.txt
@@ -6,6 +6,7 @@
 set(lib_dune_stuff_sources common/filesystem.cc 
   common/color.cc
   common/convergence-study.cc
+  common/localization-study.cc
   common/logging.cc
   common/logstreams.cc
   common/profiler.cc
diff --git a/dune/stuff/common/convergence-study.cc b/dune/stuff/common/convergence-study.cc
index 21a5d9f33369d25cd61da415bd0d51133b17b2b8..45701ab8da0b40a4b215d6d933472792c844b13d 100644
--- a/dune/stuff/common/convergence-study.cc
+++ b/dune/stuff/common/convergence-study.cc
@@ -25,12 +25,15 @@ ConvergenceStudy::ConvergenceStudy(const std::vector<std::string> only_these_nor
 
 std::vector<std::string> ConvergenceStudy::used_norms() const
 {
-  std::vector<std::string> used_norms;
-  for (auto norm : provided_norms())
-    if (only_these_norms_.empty()
-        || std::find(only_these_norms_.begin(), only_these_norms_.end(), norm) != only_these_norms_.end())
-      used_norms.push_back(norm);
-  return used_norms;
+  if (only_these_norms_.empty())
+    return provided_norms();
+  else {
+    std::vector<std::string> ret;
+    for (auto norm : provided_norms())
+      if (std::find(only_these_norms_.begin(), only_these_norms_.end(), norm) != only_these_norms_.end())
+        ret.push_back(norm);
+    return ret;
+  }
 } // ... used_norms(...)
 
 std::map<std::string, std::vector<double>> ConvergenceStudy::run(const bool relative, std::ostream& out,
@@ -40,8 +43,7 @@ std::map<std::string, std::vector<double>> ConvergenceStudy::run(const bool rela
     DUNE_THROW(Dune::InvalidStateException, "You have to provide at least one norm!");
   const auto actually_used_norms = used_norms();
   if (actually_used_norms.size() == 0)
-    DUNE_THROW(Dune::InvalidStateException,
-               "There are no common norms in 'provided_norms()' and 'only_use_this_norms'!");
+    DUNE_THROW(Dune::InvalidStateException, "There are no common norms in 'provided_norms()' and 'only_these_norms'!");
 
   std::map<std::string, std::vector<double>> ret;
   for (const auto& norm : actually_used_norms)
diff --git a/dune/stuff/common/localization-study.cc b/dune/stuff/common/localization-study.cc
new file mode 100644
index 0000000000000000000000000000000000000000..49c7a5c92388bd241b5b4d37fc7177680ffff11f
--- /dev/null
+++ b/dune/stuff/common/localization-study.cc
@@ -0,0 +1,123 @@
+// This file is part of the dune-stuff project:
+//   https://github.com/wwu-numerik/dune-stuff
+// Copyright holders: Rene Milk, Felix Schindler
+// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
+
+#include "config.h"
+
+#include <dune/stuff/common/string.hh>
+
+#include "localization-study.hh"
+
+namespace Dune {
+namespace Stuff {
+namespace Common {
+
+
+LocalizationStudy::LocalizationStudy(const std::vector<std::string> only_these_indicators)
+  : only_these_indicators_(only_these_indicators)
+{
+}
+
+LocalizationStudy::~LocalizationStudy()
+{
+}
+
+std::vector<std::string> LocalizationStudy::used_indicators() const
+{
+  if (only_these_indicators_.empty())
+    return provided_indicators();
+  else {
+    std::vector<std::string> ret;
+    for (auto indicator : provided_indicators())
+      if (std::find(only_these_indicators_.begin(), only_these_indicators_.end(), indicator)
+          != only_these_indicators_.end())
+        ret.push_back(indicator);
+    return ret;
+  }
+} // ... used_indicators(...)
+
+void LocalizationStudy::run_localization(std::ostream& out)
+{
+  if (provided_indicators().size() == 0)
+    DUNE_THROW(Dune::InvalidStateException, "You have to provide at least one indicator!");
+  const auto actually_used_indicators = used_indicators();
+  if (actually_used_indicators.size() == 0)
+    DUNE_THROW(Dune::InvalidStateException,
+               "There are no common indicators in 'provided_indicators()' and 'only_these_indicators'!");
+
+  // build table header
+  out << identifier() << std::endl;
+  const size_t total_width = 80;
+  std::string header_line =
+      std::string(" ||") + "   L^2 difference   " + "|" + "   L^oo difference  " + "|" + " standard deviation ";
+  size_t first_column_size = 0;
+  for (auto id : actually_used_indicators)
+    first_column_size          = std::max(first_column_size, id.size());
+  first_column_size            = std::max(first_column_size, total_width - header_line.size() - 1);
+  std::string first_column_str = "";
+  for (size_t ii = 0; ii < first_column_size; ++ii)
+    first_column_str += " ";
+  header_line = std::string(" ") + first_column_str + header_line;
+  // print table header
+  if (identifier().size() > header_line.size())
+    out << Stuff::Common::whitespaceify(identifier(), '=') << "\n";
+  else
+    out << Stuff::Common::whitespaceify(header_line, '=') << "\n";
+  out << header_line << "\n";
+  const std::string thin_delimiter = Stuff::Common::whitespaceify(" " + first_column_str + " ", '-') + "++"
+                                     + Stuff::Common::whitespaceify("   L^2 difference   ", '-') + "+"
+                                     + Stuff::Common::whitespaceify("   L^oo difference  ", '-') + "+"
+                                     + Stuff::Common::whitespaceify(" standard deviation ", '-');
+  const std::string thick_delimiter = Stuff::Common::whitespaceify(" " + first_column_str + " ", '=') + "++"
+                                      + Stuff::Common::whitespaceify("   L^2 difference   ", '=') + "+"
+                                      + Stuff::Common::whitespaceify("   L^oo difference  ", '=') + "+"
+                                      + Stuff::Common::whitespaceify(" standard deviation ", '=');
+  out << thick_delimiter << std::endl;
+  // comput reference indicators
+  const auto reference_indicators = compute_reference_indicators();
+  if (reference_indicators.size() == 0)
+    DUNE_THROW(Exceptions::requirements_not_met, "Given reference indicators must not be empty!");
+  // loop over all indicators
+  for (size_t ind = 0; ind < actually_used_indicators.size(); ++ind) {
+    const std::string indicator_id = actually_used_indicators[ind];
+    // enlarge/cap id to first_column_size chars
+    std::string id_str = indicator_id.empty() ? "???" : indicator_id;
+    if (id_str.size() > first_column_size)
+      id_str = id_str.substr(0, first_column_size);
+    else if (id_str.size() < first_column_size) {
+      const double missing = (double(first_column_size) - id_str.size()) / 2.0;
+      for (size_t ii = 0; ii < missing; ++ii)
+        id_str = " " + id_str + " ";
+      if (id_str.size() == (first_column_size - 1))
+        id_str = " " + id_str;
+    }
+    assert(id_str.size() == first_column_size);
+    // print first column
+    out << " " << id_str << " || " << std::flush;
+    // compute indicators
+    const auto indicators = compute_indicators(indicator_id);
+    if (indicators.size() != reference_indicators.size())
+      DUNE_THROW(Exceptions::requirements_not_met,
+                 "Given indicators of type '" << indicator_id << "' are of wrong length (is " << indicators.size()
+                                              << ", should be "
+                                              << reference_indicators.size()
+                                              << ")!");
+    const auto difference = reference_indicators - indicators;
+    // compute L^2 difference
+    out << std::setw(18) << std::setprecision(2) << std::scientific << difference.l2_norm() << std::flush;
+    // compute L^oo difference
+    out << " | " << std::setw(18) << std::setprecision(2) << std::scientific << difference.sup_norm() << std::flush;
+    // compute standard deviation
+    out << " | " << std::setw(18) << std::setprecision(2) << std::scientific << difference.standard_deviation()
+        << std::flush;
+    if (ind < (actually_used_indicators.size() - 1))
+      out << "\n" << thin_delimiter;
+    out << std::endl;
+  } // loop over all indicators
+} // ... run(...)
+
+
+} // namespace Common
+} // namespace Stuff
+} // namespace Dune
diff --git a/dune/stuff/common/localization-study.hh b/dune/stuff/common/localization-study.hh
new file mode 100644
index 0000000000000000000000000000000000000000..4ef15e8e587fabfe0fb8d4052d127535f18fa1c2
--- /dev/null
+++ b/dune/stuff/common/localization-study.hh
@@ -0,0 +1,50 @@
+// This file is part of the dune-stuff project:
+//   https://github.com/wwu-numerik/dune-stuff
+// Copyright holders: Rene Milk, Felix Schindler
+// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
+
+#ifndef DUNE_STUFF_COMMON_LOCALIZATION_STUDY_HH
+#define DUNE_STUFF_COMMON_LOCALIZATION_STUDY_HH
+
+#include <vector>
+#include <map>
+#include <string>
+#include <iostream>
+
+#include <dune/stuff/common/exceptions.hh>
+#include <dune/stuff/la/container/common.hh>
+
+namespace Dune {
+namespace Stuff {
+namespace Common {
+
+
+class LocalizationStudy
+{
+public:
+  LocalizationStudy(const std::vector<std::string> only_these_indicators = {});
+
+  virtual ~LocalizationStudy();
+
+  virtual std::string identifier() const = 0;
+
+  virtual LA::CommonDenseVector<double> compute_reference_indicators() const = 0;
+
+  virtual std::vector<std::string> provided_indicators() const = 0;
+
+  virtual LA::CommonDenseVector<double> compute_indicators(const std::string type) const = 0;
+
+  std::vector<std::string> used_indicators() const;
+
+  /*std::map< std::string, std::vector< double > >*/ void run_localization(std::ostream& out = std::cout);
+
+private:
+  const std::vector<std::string> only_these_indicators_;
+}; // class LocalizationStudy
+
+
+} // namespace Common
+} // namespace Stuff
+} // namespace Dune
+
+#endif // DUNE_STUFF_COMMON_LOCALIZATION_STUDY_HH
diff --git a/dune/stuff/test/common.cxx b/dune/stuff/test/common.cxx
index a8f336e724e732fe3ed01d09022add5268d928c1..7b24586a9d959e4d45e94ea1caad3c538bb21a6e 100644
--- a/dune/stuff/test/common.cxx
+++ b/dune/stuff/test/common.cxx
@@ -55,8 +55,8 @@ std::pair<size_t, ssize_t> convert_to_scientific(const double number, const size
 } // namespace internal
 
 
-void check_for_success(const Dune::Stuff::Common::ConvergenceStudy& study,
-                       const std::map<std::string, std::vector<double>>& results_map)
+void check_eoc_study_for_success(const Dune::Stuff::Common::ConvergenceStudy& study,
+                                 const std::map<std::string, std::vector<double>>& results_map)
 {
   for (const auto& norm : study.used_norms()) {
     const auto expected_results = study.expected_results(norm);
diff --git a/dune/stuff/test/common.hh b/dune/stuff/test/common.hh
index 1dbc8783f5efc2410dc5a794a8e5ea66d932373e..0e01ece621dfaa98952d65f2f0b7cbe828cf0da8 100644
--- a/dune/stuff/test/common.hh
+++ b/dune/stuff/test/common.hh
@@ -70,8 +70,8 @@ std::pair<size_t, ssize_t> convert_to_scientific(const double number, const size
 } // namespace internal
 
 
-void check_for_success(const Dune::Stuff::Common::ConvergenceStudy& study,
-                       const std::map<std::string, std::vector<double>>& errors_map);
+void check_eoc_study_for_success(const Dune::Stuff::Common::ConvergenceStudy& study,
+                                 const std::map<std::string, std::vector<double>>& errors_map);
 
 
 } // namespace Test
diff --git a/dune/stuff/test/common_fixed_map.cc b/dune/stuff/test/common_fixed_map.cc
index 1d362b65376cd7cc2b3fcedba09565bff7e60f8f..abbf22098560568738d823b679c37b59dff516ed 100644
--- a/dune/stuff/test/common_fixed_map.cc
+++ b/dune/stuff/test/common_fixed_map.cc
@@ -26,15 +26,19 @@ TEST(FixedMapTest, All)
   EXPECT_THROW(too_small["1"], Dune::RangeError);
   for (int i : {0, 1, 2}) {
     EXPECT_EQ(i, too_big[toString(i)]);
+    EXPECT_NE(too_big.find(toString(i)), too_big.end());
   }
   for (int DUNE_UNUSED(i) : {3, 4, 5}) {
     EXPECT_EQ(int(), too_big[std::string()]);
+    EXPECT_EQ(too_big.find(toString(i)), too_big.end());
   }
-  auto size = fits.size();
+  auto size      = fits.size();
+  const auto end = fits.end();
   for (auto& pt : fits) {
-    int value       = pt.second;
-    std::string key = pt.first;
+    const int value       = pt.second;
+    const std::string key = pt.first;
     EXPECT_EQ(key, toString(value));
+    EXPECT_NE(fits.find(key), end);
     size--;
   }
   EXPECT_EQ(0, size);