diff --git a/dune/solvers/common/CMakeLists.txt b/dune/solvers/common/CMakeLists.txt
index fe07b0653a20251391683b3447160ab768495428..3fe13a08429c6315c08aa7007fe8a8fe72e77d0e 100644
--- a/dune/solvers/common/CMakeLists.txt
+++ b/dune/solvers/common/CMakeLists.txt
@@ -3,6 +3,7 @@ install(FILES
     arithmetic.hh
     boxconstraint.hh
     canignore.hh
+    copyorreference.hh
     defaultbitvector.hh
     genericvectortools.hh
     interval.hh
diff --git a/dune/solvers/common/copyorreference.hh b/dune/solvers/common/copyorreference.hh
new file mode 100644
index 0000000000000000000000000000000000000000..c130c567a4ece184bc2335efedf3ea7e0ac6147f
--- /dev/null
+++ b/dune/solvers/common/copyorreference.hh
@@ -0,0 +1,122 @@
+// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+// vi: set et ts=4 sw=2 sts=2:
+#ifndef DUNE_SOLVERS_COMMON_COPYORREFERENCE_HH
+#define DUNE_SOLVERS_COMMON_COPYORREFERENCE_HH
+
+#include <dune/common/indices.hh>
+#include <dune/common/concept.hh>
+
+#include <dune/solvers/common/defaultbitvector.hh>
+
+
+
+namespace Dune {
+namespace Solvers {
+
+
+/**
+ * \brief A wrapper storing either a copy or reference
+ *
+ * \tparam T Type to be refered to
+ *
+ * If T is of reference type, the wrapper stores a reference
+ * to the passed object. Otherwise it stores a copy.
+ */
+template<class T>
+class CopyOrReference
+{
+public:
+  using Type = std::decay_t<T>;
+
+  constexpr CopyOrReference(const Type& other) :
+    t_(other)
+  {}
+
+  constexpr CopyOrReference(Type&& other) :
+    t_(std::move(other))
+  {}
+
+  constexpr const Type& get() const
+  {
+    return t_;
+  }
+
+  constexpr Type& get()
+  {
+    return t_;
+  }
+
+  constexpr std::true_type hasCopy() const
+  {
+    return {};
+  }
+
+private:
+  Type t_;
+};
+
+
+
+template<class T>
+class CopyOrReference<T&>
+{
+public:
+  using Type = std::decay_t<T>;
+
+  constexpr CopyOrReference(Type& other) :
+    t_(&other)
+  {}
+
+  constexpr const Type& get() const
+  {
+    return *t_;
+  }
+
+  constexpr Type& get()
+  {
+    return *t_;
+  }
+
+  constexpr std::false_type hasCopy() const
+  {
+    return {};
+  }
+
+private:
+  Type* t_;
+};
+
+
+
+template<class T>
+class CopyOrReference<const T&>
+{
+public:
+  using Type = std::decay_t<T>;
+
+  constexpr CopyOrReference(const Type& other) :
+    t_(&other)
+  {}
+
+  constexpr const Type& get() const
+  {
+    return *t_;
+  }
+
+  constexpr std::false_type hasCopy() const
+  {
+    return {};
+  }
+
+private:
+  const Type* t_;
+};
+
+
+
+} // end namespace Solvers
+} // end namespace Dune
+
+
+
+#endif // DUNE_SOLVERS_COMMON_COPYORREFERENCE_HH