diff --git a/CMakeLists.txt b/CMakeLists.txt
index 82a2b8115df86cde009929b01d5c9b64230d89e1..c67782af870c5ca65c03664a62d0bbb24ee808a5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -16,12 +16,21 @@ project (
   LANGUAGES CXX
   )
 
+include (FeatureSummary)
+
 # as long as there still are modules using it:
 enable_language (Fortran)
 
 # TEMPORARY: this should be removed, the sanitizers should be always enabled
 option (WITH_CORSIKA_SANITIZERS_ENABLED "temporary way to globally disable sanitizers until the currently failing tests are fixed" OFF)
+add_feature_info (CORSIKA_SANITIZERS_ENABLED WITH_CORSIKA_SANITIZERS_ENABLED "Switch to run c++ sanitzers on CORSIKA objects and code.")
+
 option (WITH_COAST "Flag to switch on/off COAST (reverse) interface" OFF)
+add_feature_info (COAST WITH_COAST "The COAST interface, so that you can write C8 processes to run inside C7.")
+
+# HISTORY option selection
+option (WITH_HISTORY "Flag to switch on/off HISTORY" ON)
+add_feature_info (HISTORY WITH_HISTORY "The Foo feature provides very cool stuffdddd.")
 
 # check for python
 set (Python_ADDITIONAL_VERSIONS 3)
@@ -156,5 +165,4 @@ endif ()
 
 
 # final summary output
-include (FeatureSummary)
 feature_summary (WHAT ALL)
diff --git a/Documentation/Examples/CMakeLists.txt b/Documentation/Examples/CMakeLists.txt
index c1972c894c1f9477f69db73b894b4b3bdee32fa7..17c711669f514a311dbaa9297139ca6d26959f8b 100644
--- a/Documentation/Examples/CMakeLists.txt
+++ b/Documentation/Examples/CMakeLists.txt
@@ -9,12 +9,12 @@ CORSIKA_ADD_EXAMPLE (geometry_example)
 target_link_libraries (geometry_example CORSIKAgeometry CORSIKAunits)
 
 CORSIKA_ADD_EXAMPLE (stack_example)
-target_link_libraries (stack_example SuperStupidStack CORSIKAunits)
+target_link_libraries (stack_example CORSIKAsetup CORSIKAunits)
 
 # address sanitizer is making this example too slow, so we only do "undefined"
 CORSIKA_ADD_EXAMPLE (boundary_example)
 target_link_libraries (boundary_example
-  SuperStupidStack
+  CORSIKAsetup
   CORSIKAunits
   CORSIKAlogging
   CORSIKArandom
@@ -34,7 +34,7 @@ target_link_libraries (boundary_example
 
 CORSIKA_ADD_EXAMPLE (cascade_example)
 target_link_libraries (cascade_example
-  SuperStupidStack
+  CORSIKAsetup
   CORSIKAunits
   CORSIKAlogging
   CORSIKArandom
@@ -59,7 +59,7 @@ target_link_libraries (cascade_example
 if (Pythia8_FOUND)
   CORSIKA_ADD_EXAMPLE (cascade_proton_example)
   target_link_libraries (cascade_proton_example
-    SuperStupidStack
+    CORSIKAsetup
     CORSIKAunits
     CORSIKAlogging
     CORSIKArandom
@@ -87,7 +87,7 @@ if (Pythia8_FOUND)
 
   CORSIKA_ADD_EXAMPLE (vertical_EAS RUN_OPTIONS 4 2 10000.)
   target_link_libraries (vertical_EAS
-    SuperStupidStack
+    CORSIKAsetup
     CORSIKAunits
     CORSIKAlogging
     CORSIKArandom
@@ -121,7 +121,7 @@ endif()
 
 CORSIKA_ADD_EXAMPLE (stopping_power stopping_power)
 target_link_libraries (stopping_power
-  SuperStupidStack
+  CORSIKAsetup
   CORSIKAunits
   ProcessEnergyLoss
   CORSIKAparticles
diff --git a/Documentation/Examples/vertical_EAS.cc b/Documentation/Examples/vertical_EAS.cc
index 2f4bd7dabd90807502147b4e7bf55b99dbea0cf8..cfdc75edde6f52999fb63d8f1688280bfdd7d5b1 100644
--- a/Documentation/Examples/vertical_EAS.cc
+++ b/Documentation/Examples/vertical_EAS.cc
@@ -6,6 +6,12 @@
  * the license.
  */
 
+/* clang-format off */
+// InteractionCounter used boost/histogram, which
+// fails if boost/type_traits have been included before. Thus, we have
+// to include it first...
+#include <corsika/process/interaction_counter/InteractionCounter.hpp>
+/* clang-format on */
 #include <corsika/cascade/Cascade.h>
 #include <corsika/environment/Environment.h>
 #include <corsika/environment/FlatExponential.h>
@@ -36,7 +42,6 @@
 #include <corsika/setup/SetupTrajectory.h>
 #include <corsika/units/PhysicalUnits.h>
 #include <corsika/utl/CorsikaFenv.h>
-#include <corsika/process/interaction_counter/InteractionCounter.hpp>
 
 #include <iomanip>
 #include <iostream>
diff --git a/Framework/Cascade/CMakeLists.txt b/Framework/Cascade/CMakeLists.txt
index 1d1e7e60da4e25e6558683e5ca0183e09e183fe4..9bb6019340dc8578c4f9016091e0cc2c1de0162f 100644
--- a/Framework/Cascade/CMakeLists.txt
+++ b/Framework/Cascade/CMakeLists.txt
@@ -18,6 +18,7 @@ CORSIKA_COPY_HEADERS_TO_NAMESPACE (CORSIKAcascade ${CORSIKAcascade_NAMESPACE} ${
 target_link_libraries(
   CORSIKAcascade
   INTERFACE
+  CORSIKAsetup
   CORSIKArandom
   CORSIKAstackinterface
   CORSIKAparticles
diff --git a/Framework/Cascade/Cascade.h b/Framework/Cascade/Cascade.h
index cef4c2de3a2c11c4f89f02a39ed0cade441df8fe..5e2e0f0d8bf50a22e42b09b511ac84de133580ab 100644
--- a/Framework/Cascade/Cascade.h
+++ b/Framework/Cascade/Cascade.h
@@ -99,6 +99,9 @@ namespace corsika::cascade {
         , fStack(stack)
         , count_(0) {
       C8LOG_INFO(c8_ascii_);
+#ifdef WITH_HISTORY
+      C8LOG_INFO(" - With full cascade HISTORY.");
+#endif
     }
 
     corsika::units::si::HEPEnergyType GetEnergyCut() const { return energy_cut_; }
@@ -344,7 +347,7 @@ namespace corsika::cascade {
       return returnCode;
     }
 
-    void SetEventType(TStackView& view, history::EventType eventType) {
+    void SetEventType(TStackView& view, [[maybe_unused]] history::EventType eventType) {
       if constexpr (TStackView::has_event) {
         for (auto&& sec : view) { sec.GetEvent()->setEventType(eventType); }
       }
diff --git a/Framework/ProcessSequence/CMakeLists.txt b/Framework/ProcessSequence/CMakeLists.txt
index a6c2a1701fccba3090b5376a2856090a97a3ae7e..811e2c3864c4d617043586842c03bcc74db3bb6f 100644
--- a/Framework/ProcessSequence/CMakeLists.txt
+++ b/Framework/ProcessSequence/CMakeLists.txt
@@ -23,6 +23,12 @@ set (
 CORSIKA_COPY_HEADERS_TO_NAMESPACE (CORSIKAprocesssequence ${CORSIKAprocesssequence_NAMESPACE} ${CORSIKAprocesssequence_HEADERS})
 
 #include directive for upstream code
+target_link_libraries (
+  CORSIKAprocesssequence
+  INTERFACE
+  CORSIKAsetup
+  )
+
 target_include_directories (
   CORSIKAprocesssequence
   INTERFACE
@@ -48,7 +54,6 @@ CORSIKA_ADD_TEST (testProcessSequence)
 target_link_libraries (
   testProcessSequence
   ProcessSwitch
-  CORSIKAsetup
   CORSIKAgeometry
   CORSIKAprocesssequence
   CORSIKAtesting
diff --git a/Framework/StackInterface/CMakeLists.txt b/Framework/StackInterface/CMakeLists.txt
index 47c605f748b813b50fd3b2f9afecf000cdd227e1..956f1873b6f8781c426ab4ee52d31fac80c72e6f 100644
--- a/Framework/StackInterface/CMakeLists.txt
+++ b/Framework/StackInterface/CMakeLists.txt
@@ -25,6 +25,7 @@ target_link_libraries (
   CORSIKAstackinterface
   INTERFACE
   CORSIKAlogging
+  CORSIKAsetup  
   )
 
 target_include_directories (
diff --git a/Framework/StackInterface/SecondaryView.h b/Framework/StackInterface/SecondaryView.h
index 57798e84b5ddc348737098a9651938caf8947146..c8212a93ed873baa5bbbf3a7ddb15f4f302c1d75 100644
--- a/Framework/StackInterface/SecondaryView.h
+++ b/Framework/StackInterface/SecondaryView.h
@@ -128,14 +128,25 @@ namespace corsika::stack {
   public:
     /**
        SecondaryView can only be constructed passing it a valid
-       StackIterator to another Stack object
+       StackIterator to another Stack object (here: lvalue)
      **/
     SecondaryView(StackIteratorValue& particle)
         : Stack<StackDataType&, ParticleInterface>(particle.GetStackData())
         , MSecondaryProducer<StackDataType, ParticleInterface>{particle}
         , inner_stack_(particle.GetStack())
         , projectile_index_(particle.GetIndex()) {
-      C8LOG_TRACE("SecondaryView::SecondaryView(particle)");
+      C8LOG_TRACE("SecondaryView::SecondaryView(particle&)");
+    }
+    /**
+       SecondaryView can only be constructed passing it a valid
+       StackIterator to another Stack object (here: rvalue)
+     **/
+    SecondaryView(StackIteratorValue&& particle)
+        : Stack<StackDataType&, ParticleInterface>(particle.GetStackData())
+        , MSecondaryProducer<StackDataType, ParticleInterface>{particle}
+        , inner_stack_(particle.GetStack())
+        , projectile_index_(particle.GetIndex()) {
+      C8LOG_TRACE("SecondaryView::SecondaryView(particle&&)");
     }
     /**
      * Also allow to create a new View from a Projectile (StackIterator on View)
@@ -281,13 +292,27 @@ namespace corsika::stack {
       }
       return ConstStackIterator(*this, getSize() - 1 - i + 1);
     }
-    StackIterator at(unsigned int i) {
-      return StackIterator(*this, i);
+    StackIterator at(unsigned int i) { return StackIterator(*this, i); }
+    ConstStackIterator at(unsigned int i) const { return ConstStackIterator(*this, i); }
+    StackIterator first() { return StackIterator{*this, 0}; }
+    ConstStackIterator cfirst() const { return ConstStackIterator{*this, 0}; }
+    /// @}
+
+    void Swap(StackIterator a, StackIterator b) {
+      C8LOG_TRACE("View::Swap");
+      inner_stack_.Swap(GetIndexFromIterator(a.GetIndex()),
+                        GetIndexFromIterator(b.GetIndex()));
     }
-    ConstStackIterator at(unsigned int i) const {
-      return ConstStackIterator(*this, i);
+    void Copy(StackIterator a, StackIterator b) {
+      C8LOG_TRACE("View::Copy");
+      inner_stack_.Copy(GetIndexFromIterator(a.GetIndex()),
+                        GetIndexFromIterator(b.GetIndex()));
+    }
+    void Copy(ConstStackIterator a, StackIterator b) {
+      C8LOG_TRACE("View::Copy");
+      inner_stack_.Copy(GetIndexFromIterator(a.GetIndex()),
+                        GetIndexFromIterator(b.GetIndex()));
     }
-    /// @}
 
     /**
      * need overwrite Stack::Delete, since we want to call
@@ -381,6 +406,21 @@ namespace corsika::stack {
       InnerStackTypeRef::nDeleted_ = 0;
     }
 
+    std::string as_string() const {
+      std::string str(fmt::format("size {}\n", getSize()));
+      // we make our own begin/end since we want ALL entries
+      std::string new_line = "     ";
+      for (unsigned int iPart = 0; iPart != getSize(); ++iPart) {
+        ConstStackIterator itPart(*this, iPart);
+        str += fmt::format(
+            "{}{}{}", new_line, itPart.as_string(),
+            (inner_stack_.deleted_[GetIndexFromIterator(itPart.GetIndex())] ? " [deleted]"
+                                                                            : ""));
+        new_line = "\n     ";
+      }
+      return str;
+    }
+
   protected:
     // forward to inner stack
     // this also checks the allowed bounds of 'i'
@@ -421,8 +461,8 @@ namespace corsika::stack {
      * is of course a reference into the SecondaryView itself.
      */
     template <typename Particle>
-    auto new_secondary(Particle&) const {
-      C8LOG_TRACE("DefaultSecondaryProducer::new_secondary(Particle&)");
+    auto new_secondary(Particle&&) const {
+      C8LOG_TRACE("DefaultSecondaryProducer::new_secondary(Particle&&)");
     }
 
     /**
diff --git a/Framework/StackInterface/Stack.h b/Framework/StackInterface/Stack.h
index 5f22d8069cda679af8676f22c87f96bbc16b232e..e166fccba8a8acdb957222b08b42bdcf63a87193 100644
--- a/Framework/StackInterface/Stack.h
+++ b/Framework/StackInterface/Stack.h
@@ -165,11 +165,6 @@ namespace corsika::stack {
       }
       return StackIterator(*this, i);
     }
-
-    StackIterator first() { return StackIterator{*this, 0}; }
-
-    ConstStackIterator cfirst() const { return ConstStackIterator{*this, 0}; }
-
     StackIterator end() { return StackIterator(*this, getSize()); }
     StackIterator last() {
       unsigned int i = 0;
@@ -210,13 +205,10 @@ namespace corsika::stack {
       }
       return ConstStackIterator(*this, getSize() - 1 - i);
     }
-    StackIterator at(unsigned int i) {
-      return StackIterator(*this, i);
-    }
-
-    ConstStackIterator at(unsigned int i) const {
-      return ConstStackIterator(*this, i);
-    }
+    StackIterator at(unsigned int i) { return StackIterator(*this, i); }
+    ConstStackIterator at(unsigned int i) const { return ConstStackIterator(*this, i); }
+    StackIterator first() { return StackIterator{*this, 0}; }
+    ConstStackIterator cfirst() const { return ConstStackIterator{*this, 0}; }
     /// @}
 
     StackIterator GetNextParticle() {
@@ -254,15 +246,11 @@ namespace corsika::stack {
   public:
     void Swap(StackIterator a, StackIterator b) {
       C8LOG_TRACE("Stack::Swap");
-      data_.Swap(a.GetIndex(), b.GetIndex());
-      std::swap(deleted_[a.GetIndex()], deleted_[b.GetIndex()]);
+      Swap(a.GetIndex(), b.GetIndex());
     }
     void Copy(StackIterator a, StackIterator b) {
       C8LOG_TRACE("Stack::Copy");
-      data_.Copy(a.GetIndex(), b.GetIndex());
-      if (deleted_[b.GetIndex()] && !deleted_[a.GetIndex()]) nDeleted_--;
-      if (!deleted_[b.GetIndex()] && deleted_[a.GetIndex()]) nDeleted_++;
-      deleted_[b.GetIndex()] = deleted_[a.GetIndex()];
+      Copy(a.GetIndex(), b.GetIndex());
     }
     void Copy(ConstStackIterator a, StackIterator b) {
       C8LOG_TRACE("Stack::Copy");
@@ -272,18 +260,18 @@ namespace corsika::stack {
       deleted_[b.GetIndex()] = deleted_[a.GetIndex()];
     }
 
-    std::string as_string() const {
-      std::string str(fmt::format("size {}, entries {}, deleted {} \n", getSize(),
-                                  getEntries(), getDeleted()));
-      // we make our own begin/end since we want ALL entries
-      std::string new_line = "     ";
-      for (unsigned int iPart = 0; iPart != getSize(); ++iPart) {
-        ConstStackIterator itPart(*this, iPart);
-        str += fmt::format("{}{}{}", new_line, itPart.as_string(),
-                           (deleted_[itPart.GetIndex()] ? " [deleted]" : ""));
-        new_line = "\n     ";
-      }
-      return str;
+  protected:
+    void Swap(unsigned int a, unsigned int b) {
+      C8LOG_TRACE("Stack::Swap(unsigned int)");
+      data_.Swap(a, b);
+      std::swap(deleted_[a], deleted_[b]);
+    }
+    void Copy(unsigned int a, unsigned int b) {
+      C8LOG_TRACE("Stack::Copy");
+      data_.Copy(a, b);
+      if (deleted_[b] && !deleted_[a]) nDeleted_--;
+      if (!deleted_[b] && deleted_[a]) nDeleted_++;
+      deleted_[b] = deleted_[a];
     }
 
     /**
@@ -313,7 +301,6 @@ namespace corsika::stack {
     /**
      * check if this particle was already deleted
      */
-  public:
     bool isDeleted(const StackIterator& p) { return isDeleted(p.GetIndex()); }
     bool isDeleted(const ConstStackIterator& p) const { return isDeleted(p.GetIndex()); }
     bool isDeleted(const ParticleInterfaceType& p) { return isDeleted(p.GetIterator()); }
@@ -359,6 +346,20 @@ namespace corsika::stack {
 
     unsigned int getSize() const { return data_.GetSize(); }
 
+    std::string as_string() const {
+      std::string str(fmt::format("size {}, entries {}, deleted {} \n", getSize(),
+                                  getEntries(), getDeleted()));
+      // we make our own begin/end since we want ALL entries
+      std::string new_line = "     ";
+      for (unsigned int iPart = 0; iPart != getSize(); ++iPart) {
+        ConstStackIterator itPart(*this, iPart);
+        str += fmt::format("{}{}{}", new_line, itPart.as_string(),
+                           (deleted_[itPart.GetIndex()] ? " [deleted]" : ""));
+        new_line = "\n     ";
+      }
+      return str;
+    }
+
   protected:
     bool isDeleted(unsigned int i) const {
       if (i >= deleted_.size()) return false;
diff --git a/Framework/StackInterface/testSecondaryView.cc b/Framework/StackInterface/testSecondaryView.cc
index 8c3f5e87dbf0ffedb311adef0086178948f56601..9cd1e46667e08696e81bc44d25d79b6a634500d3 100644
--- a/Framework/StackInterface/testSecondaryView.cc
+++ b/Framework/StackInterface/testSecondaryView.cc
@@ -59,18 +59,18 @@ TEST_CASE("SecondaryStack", "[stack]") {
   };
 
   SECTION("secondary view") {
-    StackTest s;
-    CHECK(s.getSize() == 0);
-    CHECK(s.IsEmpty());
+    StackTest stack;
+    CHECK(stack.getSize() == 0);
+    CHECK(stack.IsEmpty());
 
-    s.AddParticle(std::tuple{9.9});
-    s.AddParticle(std::tuple{8.8});
+    stack.AddParticle(std::tuple{9.9});
+    stack.AddParticle(std::tuple{8.8});
     const double sumS = 9.9 + 8.8; // helper, see below
-    CHECK(s.getSize() == 2);
-    CHECK(s.getEntries() == 2);
-    CHECK(!s.IsEmpty());
+    CHECK(stack.getSize() == 2);
+    CHECK(stack.getEntries() == 2);
+    CHECK(!stack.IsEmpty());
 
-    auto particle = s.GetNextParticle();
+    auto particle = stack.GetNextParticle();
 
     StackTestView view(particle);
     CHECK(view.getSize() == 0);
@@ -85,41 +85,41 @@ TEST_CASE("SecondaryStack", "[stack]") {
     CHECK(view.getSize() == 1);
     CHECK(view.getEntries() == 1);
     CHECK(!view.IsEmpty());
-    CHECK(s.getSize() == 3);
-    CHECK(s.getEntries() == 3);
-    CHECK(!s.IsEmpty());
+    CHECK(stack.getSize() == 3);
+    CHECK(stack.getEntries() == 3);
+    CHECK(!stack.IsEmpty());
 
     view.AddSecondary(std::tuple{4.5});
     view.AddSecondary(std::tuple{4.6});
     CHECK(view.getSize() == 3);
     CHECK(view.getEntries() == 3);
     CHECK(!view.IsEmpty());
-    CHECK(s.getSize() == 5);
-    CHECK(s.getEntries() == 5);
-    CHECK(!s.IsEmpty());
+    CHECK(stack.getSize() == 5);
+    CHECK(stack.getEntries() == 5);
+    CHECK(!stack.IsEmpty());
 
-    CHECK(sum(s) == sumS + 4.4 + 4.5 + 4.6);
+    CHECK(sum(stack) == sumS + 4.4 + 4.5 + 4.6);
     CHECK(sumView(view) == 4.4 + 4.5 + 4.6);
 
     view.last().Delete();
     CHECK(view.getSize() == 3);
     CHECK(view.getEntries() == 2);
-    CHECK(s.getSize() == 5);
-    CHECK(s.getEntries() == 4);
+    CHECK(stack.getSize() == 5);
+    CHECK(stack.getEntries() == 4);
 
-    CHECK(sum(s) == sumS + 4.4 + 4.5);
+    CHECK(sum(stack) == sumS + 4.4 + 4.5);
     CHECK(sumView(view) == 4.4 + 4.5);
 
     auto pDel = view.GetNextParticle();
     view.Delete(pDel);
     CHECK(view.getSize() == 2);
-    CHECK(s.getSize() == 4);
+    CHECK(stack.getSize() == 4);
 
-    CHECK(sum(s) == sumS + 4.4 + 4.5 - pDel.GetData());
+    CHECK(sum(stack) == sumS + 4.4 + 4.5 - pDel.GetData());
     CHECK(sumView(view) == 4.4 + 4.5 - pDel.GetData());
 
     view.Delete(view.GetNextParticle());
-    CHECK(sum(s) == sumS);
+    CHECK(sum(stack) == sumS);
     CHECK(sumView(view) == 0);
     CHECK(view.IsEmpty());
 
@@ -128,15 +128,20 @@ TEST_CASE("SecondaryStack", "[stack]") {
       CHECK(proj.GetData() == particle.GetData());
       CHECK(particle == view.parent());
     }
+
+    // at() and first()
+    auto pTestAt = view.at(0);
+    auto pTestFirst = view.first();
+    CHECK(pTestFirst == pTestAt);
   }
 
   SECTION("secondary view, construct from ParticleType") {
-    StackTest s;
-    CHECK(s.getSize() == 0);
-    s.AddParticle(std::tuple{9.9});
-    s.AddParticle(std::tuple{8.8});
+    StackTest stack;
+    CHECK(stack.getSize() == 0);
+    stack.AddParticle(std::tuple{9.9});
+    stack.AddParticle(std::tuple{8.8});
 
-    auto iterator = s.GetNextParticle();
+    auto iterator = stack.GetNextParticle();
     typename StackTest::ParticleType& particle = iterator; // as in corsika::Cascade
 
     StackTestView view(particle);
@@ -206,4 +211,46 @@ TEST_CASE("SecondaryStack", "[stack]") {
       CHECK(stack.getSize() == 10);
     }
   }
+
+  SECTION("swap particle") {
+    StackTest stack;
+    stack.AddParticle(std::tuple{-99.});
+
+    StackTestView view(stack.first());
+    view.AddSecondary(std::tuple{-2.});
+    view.AddSecondary(std::tuple{-1.});
+    view.AddSecondary(std::tuple{1.});
+
+    auto p1 = view.begin();
+    auto p2 = p1 + 1;
+
+    CHECK(p1.GetData() == -2.);
+    CHECK(p2.GetData() == -1.);
+
+    view.Swap(p1, p2);
+
+    CHECK(p1.GetData() == -1);
+    CHECK(p2.GetData() == -2);
+  }
+
+  SECTION("copy particle") {
+    StackTest stack;
+    stack.AddParticle(std::tuple{-99.});
+
+    StackTestView view(stack.first());
+    view.AddSecondary(std::tuple{-2.});
+    view.AddSecondary(std::tuple{-1.});
+    view.AddSecondary(std::tuple{1.});
+
+    auto p1 = view.begin();
+    auto p2 = p1 + 1;
+
+    CHECK(p1.GetData() == -2.);
+    CHECK(p2.GetData() == -1.);
+
+    view.Copy(p1, p2);
+
+    CHECK(p1.GetData() == -2);
+    CHECK(p2.GetData() == -2);
+  }
 }
diff --git a/Framework/StackInterface/testStackInterface.cc b/Framework/StackInterface/testStackInterface.cc
index cef564e8b5f13dbdbd75a0c7229bc6dd551c20fa..af1f217ad361f8b4fa41c62da12b156a205e1c76 100644
--- a/Framework/StackInterface/testStackInterface.cc
+++ b/Framework/StackInterface/testStackInterface.cc
@@ -38,18 +38,20 @@ TEST_CASE("Stack", "[Stack]") {
   SECTION("StackInterface") {
 
     // construct a valid Stack object
-    StackTest s;
-    s.Clear();
-    auto pTest0 = s.AddParticle(std::tuple{0.});
-    CHECK(s.getSize() == 1);
-    auto pTest1 = s.AddParticle(std::tuple{1.});
-    s.Copy(s.cbegin(), s.begin());
-    s.Swap(s.begin(), s.begin());
-    CHECK(s.getSize() == 1);
-    auto pTestAt = s.at(0);
-    CHECK(pTestAt == pTest);
-    auto pTestFirst = s.first();
-    CHECK(pTestFirst == pTest);
+    StackTest stack;
+    stack.Clear();
+    CHECK(stack.getSize() == 0);
+    CHECK(stack.IsEmpty());                          // stack empty here
+    auto pTest0 = stack.AddParticle(std::tuple{0.}); // [0]
+    CHECK(stack.getSize() == 1);
+    CHECK(!stack.IsEmpty());
+    auto pTest1 = stack.AddParticle(std::tuple{1.}); // [0,1]
+    CHECK(stack.getSize() == 2);
+    CHECK(pTest1.GetData() == 1.);
+    auto pTestAt = stack.at(1); // -> 1
+    CHECK(pTestAt == pTest1);
+    auto pTestFirst = stack.first(); // -> 0
+    CHECK(pTestFirst == pTest0);
   }
 
   SECTION("construct") {
@@ -60,152 +62,152 @@ TEST_CASE("Stack", "[Stack]") {
 
   SECTION("write and read") {
 
-    StackTest s;
-    s.AddParticle(std::tuple{9.9});
-    const double v = sum(s);
+    StackTest stack;
+    stack.AddParticle(std::tuple{9.9});
+    const double v = sum(stack);
     CHECK(v == 9.9);
   }
 
   SECTION("delete from stack") {
 
-    StackTest s;
-    CHECK(s.getSize() == 0);
+    StackTest stack;
+    CHECK(stack.getSize() == 0);
     StackTest::StackIterator p =
-        s.AddParticle(std::tuple{0.}); // valid way to access particle data
+        stack.AddParticle(std::tuple{0.}); // valid way to access particle data
     p.SetData(9.9);
-    CHECK(s.getSize() == 1);
-    CHECK(s.getEntries() == 1);
-    s.Delete(p);
-    CHECK(s.getSize() == 1);
-    CHECK(s.getEntries() == 0);
+    CHECK(stack.getSize() == 1);
+    CHECK(stack.getEntries() == 1);
+    stack.Delete(p);
+    CHECK(stack.getSize() == 1);
+    CHECK(stack.getEntries() == 0);
   }
 
   SECTION("delete particle") {
 
-    StackTest s;
-    CHECK(s.getSize() == 0);
-    s.AddParticle(std::tuple{8.9});
-    s.AddParticle(std::tuple{7.9});
-    auto p = s.AddParticle(
+    StackTest stack;
+    CHECK(stack.getSize() == 0);
+    stack.AddParticle(std::tuple{8.9});
+    stack.AddParticle(std::tuple{7.9});
+    auto p = stack.AddParticle(
         std::tuple{9.9}); // also valid way to access particle data, identical to above
 
-    CHECK(s.getSize() == 3);
-    CHECK(s.getEntries() == 3);
-    CHECK(!s.IsEmpty());
+    CHECK(stack.getSize() == 3);
+    CHECK(stack.getEntries() == 3);
+    CHECK(!stack.IsEmpty());
 
     p.Delete(); // mark for deletion: size=3, entries=2
-    CHECK(s.getSize() == 3);
-    CHECK(s.getEntries() == 2);
-    CHECK(!s.IsEmpty());
+    CHECK(stack.getSize() == 3);
+    CHECK(stack.getEntries() == 2);
+    CHECK(!stack.IsEmpty());
 
-    s.last().Delete(); // mark for deletion: size=3, entries=1
-    CHECK(s.getSize() == 3);
-    CHECK(s.getEntries() == 1);
-    CHECK(!s.IsEmpty());
+    stack.last().Delete(); // mark for deletion: size=3, entries=1
+    CHECK(stack.getSize() == 3);
+    CHECK(stack.getEntries() == 1);
+    CHECK(!stack.IsEmpty());
 
     /*
        GetNextParticle will find two entries marked as "deleted" and
        will purge this from the end of the stack: size = 1
     */
-    s.GetNextParticle().Delete(); // mark for deletion: size=3, entries=0
-    CHECK(s.getSize() == 1);
-    CHECK(s.getEntries() == 0);
-    CHECK(s.IsEmpty());
+    stack.GetNextParticle().Delete(); // mark for deletion: size=3, entries=0
+    CHECK(stack.getSize() == 1);
+    CHECK(stack.getEntries() == 0);
+    CHECK(stack.IsEmpty());
   }
 
   SECTION("create secondaries") {
 
-    StackTest s;
-    CHECK(s.getSize() == 0);
-    auto iter = s.AddParticle(std::tuple{9.9});
+    StackTest stack;
+    CHECK(stack.getSize() == 0);
+    auto iter = stack.AddParticle(std::tuple{9.9});
     StackTest::ParticleInterfaceType& p =
         *iter; // also this is valid to access particle data
-    CHECK(s.getSize() == 1);
+    CHECK(stack.getSize() == 1);
     p.AddSecondary(std::tuple{4.4});
-    CHECK(s.getSize() == 2);
+    CHECK(stack.getSize() == 2);
   }
 
   SECTION("get next particle") {
-    StackTest s;
-    CHECK(s.getSize() == 0);
-    CHECK(s.getEntries() == 0);
-    CHECK(s.IsEmpty());
-
-    s.AddParticle(std::tuple{9.9});
-    s.AddParticle(std::tuple{8.8});
-    CHECK(s.getSize() == 2);
-    CHECK(s.getEntries() == 2);
-    CHECK(!s.IsEmpty());
-
-    auto particle = s.GetNextParticle(); // first particle
+    StackTest stack;
+    CHECK(stack.getSize() == 0);
+    CHECK(stack.getEntries() == 0);
+    CHECK(stack.IsEmpty());
+
+    stack.AddParticle(std::tuple{9.9});
+    stack.AddParticle(std::tuple{8.8});
+    CHECK(stack.getSize() == 2);
+    CHECK(stack.getEntries() == 2);
+    CHECK(!stack.IsEmpty());
+
+    auto particle = stack.GetNextParticle(); // first particle
     CHECK(particle.GetData() == 8.8);
 
     particle.Delete(); // only marks (last) particle as deleted
-    CHECK(s.getSize() == 2);
-    CHECK(s.getEntries() == 1);
-    CHECK(!s.IsEmpty());
+    CHECK(stack.getSize() == 2);
+    CHECK(stack.getEntries() == 1);
+    CHECK(!stack.IsEmpty());
 
     /*
       This following call to GetNextParticle will realize that the
       current last particle on the stack was marked "deleted" and will
       purge it: stack size is reduced by one.
      */
-    auto particle2 = s.GetNextParticle(); // first particle
+    auto particle2 = stack.GetNextParticle(); // first particle
     CHECK(particle2.GetData() == 9.9);
-    CHECK(s.getSize() == 1);
-    CHECK(s.getEntries() == 1);
-    CHECK(!s.IsEmpty());
+    CHECK(stack.getSize() == 1);
+    CHECK(stack.getEntries() == 1);
+    CHECK(!stack.IsEmpty());
 
     particle2.Delete(); // also mark this particle as deleted
 
-    CHECK(s.getSize() == 1);
-    CHECK(s.getEntries() == 0);
-    CHECK(s.IsEmpty());
+    CHECK(stack.getSize() == 1);
+    CHECK(stack.getEntries() == 0);
+    CHECK(stack.IsEmpty());
   }
 
   SECTION("swap particle") {
-    StackTest s;
-    CHECK(s.getSize() == 0);
-    CHECK(s.getEntries() == 0);
-    CHECK(s.IsEmpty());
-
-    s.AddParticle(std::tuple{9.888});
-    s.AddParticle(std::tuple{8.999});
-    CHECK(s.getSize() == 2);
-    CHECK(s.getEntries() == 2);
-    CHECK(!s.IsEmpty());
-
-    auto p1 = s.begin();
+    StackTest stack;
+    CHECK(stack.getSize() == 0);
+    CHECK(stack.getEntries() == 0);
+    CHECK(stack.IsEmpty());
+
+    stack.AddParticle(std::tuple{9.888});
+    stack.AddParticle(std::tuple{8.999});
+    CHECK(stack.getSize() == 2);
+    CHECK(stack.getEntries() == 2);
+    CHECK(!stack.IsEmpty());
+
+    auto p1 = stack.begin();
     auto p2 = p1 + 1;
 
     CHECK(p1.GetData() == 9.888);
     CHECK(p2.GetData() == 8.999);
 
-    s.Swap(p1, p2);
+    stack.Swap(p1, p2);
 
     CHECK(p1.GetData() == 8.999);
     CHECK(p2.GetData() == 9.888);
   }
 
   SECTION("copy particle") {
-    StackTest s;
-    CHECK(s.getSize() == 0);
-    CHECK(s.getEntries() == 0);
-    CHECK(s.IsEmpty());
-
-    s.AddParticle(std::tuple{9.888});
-    s.AddParticle(std::tuple{8.999});
-    CHECK(s.getSize() == 2);
-    CHECK(s.getEntries() == 2);
-    CHECK(!s.IsEmpty());
-
-    auto p1 = s.begin();
+    StackTest stack;
+    CHECK(stack.getSize() == 0);
+    CHECK(stack.getEntries() == 0);
+    CHECK(stack.IsEmpty());
+
+    stack.AddParticle(std::tuple{9.888});
+    stack.AddParticle(std::tuple{8.999});
+    CHECK(stack.getSize() == 2);
+    CHECK(stack.getEntries() == 2);
+    CHECK(!stack.IsEmpty());
+
+    auto p1 = stack.begin();
     auto p2 = p1 + 1;
 
     CHECK(p1.GetData() == 9.888);
     CHECK(p2.GetData() == 8.999);
 
-    s.Copy(p1, p2);
+    stack.Copy(p1, p2);
 
     CHECK(p1.GetData() == 9.888);
     CHECK(p2.GetData() == 9.888);
diff --git a/Framework/Testing/TestMain.cc b/Framework/Testing/TestMain.cc
index 15312a6ad3f1f987fa438806773a51e0674983af..fa52fa804f307c546f628b7ccd5d14401b6f0adb 100644
--- a/Framework/Testing/TestMain.cc
+++ b/Framework/Testing/TestMain.cc
@@ -6,6 +6,6 @@
  * the license.
  */
 
-#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one \
+#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one
                           // cpp file
 #include <catch2/catch.hpp>
diff --git a/Processes/ObservationPlane/testObservationPlane.cc b/Processes/ObservationPlane/testObservationPlane.cc
index d35aba57e9ae0e5e08a262916b4adca1bf304947..7f3f183a6def750818aa1eb05be4bec81937d587 100644
--- a/Processes/ObservationPlane/testObservationPlane.cc
+++ b/Processes/ObservationPlane/testObservationPlane.cc
@@ -6,7 +6,7 @@
  * the license.
  */
 
-#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one \
+#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one
                           // cpp file
 #include <catch2/catch.hpp>
 
diff --git a/Processes/QGSJetII/CMakeLists.txt b/Processes/QGSJetII/CMakeLists.txt
index 8e3bb52d415abf20b352c8bbd3268d9dd5e5e841..77d43794c751b59713b6d962a4cc26177a0b81aa 100644
--- a/Processes/QGSJetII/CMakeLists.txt
+++ b/Processes/QGSJetII/CMakeLists.txt
@@ -104,20 +104,4 @@ target_link_libraries (
   testQGSJetII
   ProcessQGSJetII
   CORSIKAtesting
-  )
-
-# also provide QGSJetII large data tables for testing in build tree (links)
-# -> changed that to use environment variable "${CORSIKA_DATA}/QGSJetII"
-# add_custom_command (
-#  OUTPUT  ${CMAKE_CURRENT_BINARY_DIR}/qgsdat-II-04 ${CMAKE_CURRENT_BINARY_DIR}/sectnu-II-04
-#  COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_CURRENT_SOURCE_DIR}/qgsdat-II-04 ${CMAKE_CURRENT_BINARY_DIR}/qgsdat-II-04
-#  COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_CURRENT_SOURCE_DIR}/sectnu-II-04 ${CMAKE_CURRENT_BINARY_DIR}/sectnu-II-04
-#  COMMENT "Generate link in source-dir: qgsjet-II-04"
-#  )
-
-# add_custom_target (QGSJetDataLink DEPENDS
-#  ${CMAKE_CURRENT_BINARY_DIR}/qgsdat-II-04
-#  ${CMAKE_CURRENT_BINARY_DIR}/sectnu-II-04
-#  )
-
-# add_dependencies (testQGSJetII QGSJetDataLink)
+  stdc++fs)
diff --git a/Processes/QGSJetII/testQGSJetII.cc b/Processes/QGSJetII/testQGSJetII.cc
index 33168bee7b469f18f34c0159e5ace02dd56b67b5..eafe725dbcd676afcf402ea562a589d228f468dc 100644
--- a/Processes/QGSJetII/testQGSJetII.cc
+++ b/Processes/QGSJetII/testQGSJetII.cc
@@ -18,6 +18,10 @@
 
 #include <catch2/catch.hpp>
 
+#include <cstdlib>
+#include <experimental/filesystem>
+#include <iostream>
+
 using namespace corsika;
 using namespace corsika::process::qgsjetII;
 using namespace corsika::units::si;
@@ -40,8 +44,30 @@ auto sumMomentum(TStackView const& view, geometry::CoordinateSystem const& vCS)
   return sum;
 }
 
+TEST_CASE("CORSIKA_DATA", "[processes]") {
+
+  SECTION("check CORSIKA_DATA") {
+
+    const char* data = std::getenv("CORSIKA_DATA");
+    // these REQUIRES are needed:
+    REQUIRE(data != 0);
+    REQUIRE(std::experimental::filesystem::is_directory(
+        std::experimental::filesystem::path(std::string(data) + "/QGSJetII")));
+    std::cout << "data: " << data << " isDir: "
+              << std::experimental::filesystem::is_directory(std::string(data) +
+                                                             "/QGSJetII")
+              << std::endl;
+  }
+}
+
 TEST_CASE("QgsjetII", "[processes]") {
 
+  SECTION("Corsika -> QgsjetII") {
+    CHECK(process::qgsjetII::ConvertToQgsjetII(particles::PiMinus::GetCode()) ==
+          process::qgsjetII::QgsjetIICode::PiMinus);
+    CHECK(process::qgsjetII::ConvertToQgsjetIIRaw(particles::Proton::GetCode()) == 2);
+  }
+
   SECTION("QgsjetII -> Corsika") {
     CHECK(particles::PiPlus::GetCode() == process::qgsjetII::ConvertFromQgsjetII(
                                               process::qgsjetII::QgsjetIICode::PiPlus));
diff --git a/Setup/CMakeLists.txt b/Setup/CMakeLists.txt
index f8490cc2f007c6ffb04dadab8a0e956cee32ec3b..21d59657638b3fa7974214f454632ca0417c7f97 100644
--- a/Setup/CMakeLists.txt
+++ b/Setup/CMakeLists.txt
@@ -23,6 +23,10 @@ target_link_libraries (
   CORSIKAhistory
   )
 
+if (WITH_HISTORY)
+  target_compile_definitions (CORSIKAsetup INTERFACE "WITH_HISTORY")
+endif (WITH_HISTORY)
+
 target_include_directories (
   CORSIKAsetup
   INTERFACE 
diff --git a/Setup/SetupStack.h b/Setup/SetupStack.h
index 8628f3df63181fa082801fd625bd140f8572484d..8930cb74eeae2ba63bbead4f79085617880ed0ba 100644
--- a/Setup/SetupStack.h
+++ b/Setup/SetupStack.h
@@ -59,12 +59,11 @@ namespace corsika::setup {
   // ---------------------------------------
   // this is the FINAL stack we use in C8:
 
-  // the version without history
-  // using Stack = detail::StackWithGeometry;
-  // template<typename T1, template<typename>typename M2>
-  // using StackViewProducer = corsika::stack::DefaultSecondaryProducer<T1,M2>;
+#ifdef WITH_HISTORY
 
-  // the version with history
+  /*
+   * the version with history
+   */
   using Stack = detail::StackWithHistory;
   template <typename T1, template <typename> typename M2>
   using StackViewProducer = corsika::history::HistorySecondaryProducer<T1, M2>;
@@ -85,7 +84,6 @@ namespace corsika::setup {
     using TheStackView = corsika::stack::SecondaryView<
         typename corsika::setup::Stack::StackImpl,
         // CHECK with CLANG: corsika::setup::Stack::MPIType>;
-        // corsika::setup::detail::StackWithGeometryInterface>;
         corsika::setup::detail::StackWithHistoryInterface, StackViewProducer>;
 #elif defined(__GNUC__) || defined(__GNUG__)
     using TheStackView =
@@ -93,6 +91,40 @@ namespace corsika::setup {
 #endif
   } // namespace detail
 
+#else // WITH_HISTORY
+
+  /*
+   * the version without history
+   */
+  using Stack = detail::StackWithGeometry;
+  template <typename T1, template <typename> typename M2>
+  using StackViewProducer = corsika::stack::DefaultSecondaryProducer<T1, M2>;
+
+  namespace detail {
+    /*
+      See Issue 161
+
+      unfortunately clang does not support this in the same way (yet) as
+      gcc, so we have to distinguish here. If clang cataches up, we
+      could remove the clang branch here and also in
+      corsika::Cascade. The gcc code is much more generic and
+      universal. If we could do the gcc version, we won't had to define
+      StackView globally, we could do it with MakeView whereever it is
+      actually needed. Keep an eye on this!
+    */
+#if defined(__clang__)
+    using TheStackView =
+        corsika::stack::SecondaryView<typename corsika::setup::Stack::StackImpl,
+                                      // CHECK with CLANG:
+                                      // corsika::setup::Stack::MPIType>;
+                                      corsika::setup::detail::StackWithGeometryInterface>;
+#elif defined(__GNUC__) || defined(__GNUG__)
+    using TheStackView = corsika::stack::MakeView<corsika::setup::Stack>::type;
+#endif
+  } // namespace detail
+
+#endif
+
   // ---------------------------------------
   // this is the FINAL stackitertor (particle type) we use in C8:
 
diff --git a/Stack/History/CMakeLists.txt b/Stack/History/CMakeLists.txt
index 6fd9e24a845d70cd7b51fb00014fc47a25c869fd..2a47b86189bef946269e8f2815a51b2cfcf171f6 100644
--- a/Stack/History/CMakeLists.txt
+++ b/Stack/History/CMakeLists.txt
@@ -13,17 +13,23 @@ set (
   corsika/stack/history
   )
 
-set (
-  HISTORY_SOURCES
-  HistoryObservationPlane.cpp
-)
+if (WITH_HISTORY)
+  set (
+    HISTORY_SOURCES
+    HistoryObservationPlane.cpp
+    )
+  add_library (CORSIKAhistory STATIC ${HISTORY_SOURCES})
+  set (IS_INTERFACE "")
+else (WITH_HISTORY)
+  add_library (CORSIKAhistory INTERFACE)
+  set (IS_INTERFACE "INTERFACE")
+endif (WITH_HISTORY)
 
-#add_library (CORSIKAhistory INTERFACE)
-add_library (CORSIKAhistory STATIC ${HISTORY_SOURCES})
 CORSIKA_COPY_HEADERS_TO_NAMESPACE (CORSIKAhistory ${HISTORY_NAMESPACE} ${HISTORY_HEADERS})
 
 target_link_libraries (
   CORSIKAhistory
+  ${IS_INTERFACE}
   CORSIKAparticles
   CORSIKAgeometry
   CORSIKAprocesssequence # for HistoryObservationPlane
diff --git a/Stack/History/Event.hpp b/Stack/History/Event.hpp
index fb307e5e25359a0e2f633634ab9167db7fdf7fb1..901d9db8f7c327f1ff4dab9f931114a5a1dc7b69 100644
--- a/Stack/History/Event.hpp
+++ b/Stack/History/Event.hpp
@@ -44,15 +44,6 @@ namespace corsika::history {
     void setProjectileIndex(size_t i) { projectile_index_ = i; }
     size_t projectileIndex() const { return projectile_index_; }
 
-    template <typename TStackIterator>
-    TStackIterator projectile(TStackIterator begin) {
-      // todo: change this
-      // MR: This is dangerous. You can pass any iterator though it must
-      // be stack.begin() to yield the correct projectile
-
-      return begin + projectile_index_;
-    }
-
     size_t addSecondary(units::si::HEPEnergyType energy,
                         geometry::Vector<units::si::hepmomentum_d> const& momentum,
                         particles::Code pid) {
diff --git a/Stack/History/HistoryObservationPlane.cpp b/Stack/History/HistoryObservationPlane.cpp
index 6ad06096005fc5aedb73b3983705617c0ba6a16f..eb5ca8b01ff9429b4742c645b71a26da86c71536 100644
--- a/Stack/History/HistoryObservationPlane.cpp
+++ b/Stack/History/HistoryObservationPlane.cpp
@@ -65,10 +65,9 @@ LengthType HistoryObservationPlane::MaxStepLength(setup::Stack::ParticleType con
 
 void HistoryObservationPlane::fillHistoryHistogram(
     setup::Stack::ParticleType const& muon) {
-  //  double const muonEnergy = muon.GetEnergy() / 1_eV;
-
-  // auto parent = stack_.begin() + muon.GetEvent()->projectileIndex();
-  Event* event = muon.GetEvent().get();
+  // double const muonEnergy = muon.GetEnergy() / 1_eV;
+  // auto parent = stack_.at(muon.GetEvent()->projectileIndex());
+  Event const* event = muon.GetEvent().get();
 
   int intCounter = 0;
   while (event) {
diff --git a/Stack/History/testHistoryView.cc b/Stack/History/testHistoryView.cc
index 6853571c4b4fca15ac7c717d32f71b4bf0f51c3c..de0f87d77aacf8a7cb7aaa26a67ee1b5593f5f41 100644
--- a/Stack/History/testHistoryView.cc
+++ b/Stack/History/testHistoryView.cc
@@ -136,8 +136,8 @@ TEST_CASE("HistoryStackExtension", "[stack]") {
 
       CHECK(count_generations(sec.GetEvent().get()) == 2);
 
-      CHECK((stack.begin() + sec.GetEvent()->projectileIndex()).GetEvent() ==
-            sec.GetEvent()->parentEvent());
+      const auto org_projectile = stack.at(sec.GetEvent()->projectileIndex());
+      CHECK(org_projectile.GetEvent() == sec.GetEvent()->parentEvent());
     }
 
     // read 2nd genertion particle particle
@@ -246,8 +246,8 @@ TEST_CASE("HistoryStackExtension", "[stack]") {
       CHECK(sec.GetEvent()->secondaries().size() == i + 1);
       CHECK(sec.GetEvent()->parentEvent()->parentEvent() == ev0);
 
-      CHECK((stack.begin() + sec.GetEvent()->projectileIndex()).GetEvent() ==
-            sec.GetEvent()->parentEvent());
+      const auto org_projectile = stack.at(sec.GetEvent()->projectileIndex());
+      CHECK(org_projectile.GetEvent() == sec.GetEvent()->parentEvent());
     }
     CHECK(stack.getEntries() == 16);
   }