diff --git a/dynare++/kord/approximation.cc b/dynare++/kord/approximation.cc
index 12c0dd0c9eece64ba7c1573984e8ee3960a1e6d4..e04807abeadbb28756749cc83f226b476485acab 100644
--- a/dynare++/kord/approximation.cc
+++ b/dynare++/kord/approximation.cc
@@ -81,13 +81,13 @@ Approximation::approxAtSteady()
                     model.getVcov(), journal);
       korder.switchToFolded();
       for (int k = 2; k <= model.order(); k++)
-        korder.performStep<KOrder::fold>(k);
+        korder.performStep<Storage::fold>(k);
 
       saveRuleDerivs(korder.getFoldDers());
     }
   else
     {
-      FirstOrderDerivs<KOrder::fold> fo_ders(fo);
+      FirstOrderDerivs<Storage::fold> fo_ders(fo);
       saveRuleDerivs(fo_ders);
     }
   check(0.0);
@@ -148,7 +148,7 @@ Approximation::walkStochSteady()
       /* We form the |DRFixPoint| object from the last rule with
          $\sigma=dsigma$. Then we save the steady state to |ss|. The new steady
          is also put to |model.getSteady()|. */
-      DRFixPoint<KOrder::fold> fp(*rule_ders, ypart, model.getSteady(), dsigma);
+      DRFixPoint<Storage::fold> fp(*rule_ders, ypart, model.getSteady(), dsigma);
       bool converged = fp.calcFixPoint(DecisionRule::emethod::horner, model.getSteady());
       JournalRecord rec(journal);
       rec << "Fix point calcs: iter=" << fp.getNumIter() << ", newton_iter="
@@ -171,7 +171,7 @@ Approximation::walkStochSteady()
       Vector dy(model.getSteady());
       dy.add(-1.0, last_steady);
 
-      StochForwardDerivs<KOrder::fold> hh(ypart, model.nexog(), *rule_ders_ss, mom, dy,
+      StochForwardDerivs<Storage::fold> hh(ypart, model.nexog(), *rule_ders_ss, mom, dy,
                                           dsigma, sigma_so_far);
       JournalRecord rec1(journal);
       rec1 << "Calculation of g** expectations done" << endrec;
@@ -183,7 +183,7 @@ Approximation::walkStochSteady()
       KOrderStoch korder_stoch(ypart, model.nexog(), model.getModelDerivatives(),
                                hh, journal);
       for (int d = 1; d <= model.order(); d++)
-        korder_stoch.performStep<KOrder::fold>(d);
+        korder_stoch.performStep<Storage::fold>(d);
 
       saveRuleDerivs(korder_stoch.getFoldDers());
 
@@ -198,7 +198,7 @@ Approximation::walkStochSteady()
   if (steps == 0 && dr_centralize)
     {
       // centralize decision rule for zero steps
-      DRFixPoint<KOrder::fold> fp(*rule_ders, ypart, model.getSteady(), 1.0);
+      DRFixPoint<Storage::fold> fp(*rule_ders, ypart, model.getSteady(), 1.0);
       bool converged = fp.calcFixPoint(DecisionRule::emethod::horner, model.getSteady());
       JournalRecord rec(journal);
       rec << "Fix point calcs: iter=" << fp.getNumIter() << ", newton_iter="
diff --git a/dynare++/kord/decision_rule.cc b/dynare++/kord/decision_rule.cc
index 10de34f239d88b010b35aefb59f8cb8b003dfc36..deee95946dea01cdcce3d11e26765f93476a65ed 100644
--- a/dynare++/kord/decision_rule.cc
+++ b/dynare++/kord/decision_rule.cc
@@ -15,20 +15,20 @@
 
 // |FoldDecisionRule| conversion from |UnfoldDecisionRule|
 FoldDecisionRule::FoldDecisionRule(const UnfoldDecisionRule &udr)
-  : DecisionRuleImpl<KOrder::fold>(ctraits<KOrder::fold>::Tpol(udr.nrows(), udr.nvars()),
+  : DecisionRuleImpl<Storage::fold>(ctraits<Storage::fold>::Tpol(udr.nrows(), udr.nvars()),
                                    udr.ypart, udr.nu, udr.ysteady)
 {
   for (const auto &it : udr)
-    insert(std::make_unique<ctraits<KOrder::fold>::Ttensym>(*(it.second)));
+    insert(std::make_unique<ctraits<Storage::fold>::Ttensym>(*(it.second)));
 }
 
 // |UnfoldDecisionRule| conversion from |FoldDecisionRule|
 UnfoldDecisionRule::UnfoldDecisionRule(const FoldDecisionRule &fdr)
-  : DecisionRuleImpl<KOrder::unfold>(ctraits<KOrder::unfold>::Tpol(fdr.nrows(), fdr.nvars()),
+  : DecisionRuleImpl<Storage::unfold>(ctraits<Storage::unfold>::Tpol(fdr.nrows(), fdr.nvars()),
                                      fdr.ypart, fdr.nu, fdr.ysteady)
 {
   for (const auto &it : fdr)
-    insert(std::make_unique<ctraits<KOrder::unfold>::Ttensym>(*(it.second)));
+    insert(std::make_unique<ctraits<Storage::unfold>::Ttensym>(*(it.second)));
 }
 
 /* This runs simulations with an output to journal file. Note that we
diff --git a/dynare++/kord/decision_rule.hh b/dynare++/kord/decision_rule.hh
index ed0165c7f827608b18d8acbc0fe51058fb8a7f8a..ff201fd062dd5a641f83a30fc6c68b4b20c25a77 100644
--- a/dynare++/kord/decision_rule.hh
+++ b/dynare++/kord/decision_rule.hh
@@ -90,25 +90,28 @@ public:
    \left[\matrix{y^*_{t-1}-\tilde y^*\cr u_t}\right]^{\alpha_m}.$$
    We provide a method and a constructor to transform a rule to the centralized form.
 
-   The class is templated, the template argument is either |KOrder::fold|
-   or |KOrder::unfold|. So, there are two implementations of |DecisionRule|
+   The class is templated, the template argument is either |Storage::fold|
+   or |Storage::unfold|. So, there are two implementations of |DecisionRule|
    interface. */
 
-template <int t>
+template <Storage t>
 class DecisionRuleImpl : public ctraits<t>::Tpol, public DecisionRule
 {
 protected:
-  using _Tparent = typename ctraits<t>::Tpol;
+  using _Tpol = typename ctraits<t>::Tpol;
+  using _Tg = typename ctraits<t>::Tg;
+  using _Ttensor = typename ctraits<t>::Ttensor;
+  using _Ttensym = typename ctraits<t>::Ttensym;
   const Vector ysteady;
   const PartitionY ypart;
   const int nu;
 public:
-  DecisionRuleImpl(const _Tparent &pol, const PartitionY &yp, int nuu,
+  DecisionRuleImpl(const _Tpol &pol, const PartitionY &yp, int nuu,
                    const ConstVector &ys)
     : ctraits<t>::Tpol(pol), ysteady(ys), ypart(yp), nu(nuu)
   {
   }
-  DecisionRuleImpl(_Tparent &pol, const PartitionY &yp, int nuu,
+  DecisionRuleImpl(_Tpol &pol, const PartitionY &yp, int nuu,
                    const ConstVector &ys)
     : ctraits<t>::Tpol(0, yp.ny(), pol), ysteady(ys), ypart(yp),
     nu(nuu)
@@ -190,7 +193,7 @@ protected:
    So we go through $i+j=d=0\ldots q$ and in each loop we form the fully
    symmetric tensor $[g_{(yu)^l}]$ and insert it to the container. */
 
-template <int t>
+template <Storage t>
 void
 DecisionRuleImpl<t>::fillTensors(const _Tg &g, double sigma)
 {
@@ -244,7 +247,7 @@ DecisionRuleImpl<t>::fillTensors(const _Tg &g, double sigma)
    $$dstate=\left[\matrix{\tilde y^*-\bar y^*\cr 0}\right],$$
    where $\bar y$ is the steady state of the original rule |dr|. */
 
-template <int t>
+template <Storage t>
 void
 DecisionRuleImpl<t>::centralize(const DecisionRuleImpl &dr)
 {
@@ -278,7 +281,7 @@ DecisionRuleImpl<t>::centralize(const DecisionRuleImpl &dr)
    |ysteady| is canceled from |ystart|, we simulate, and at the end
    |ysteady| is added to all columns of the result. */
 
-template <int t>
+template <Storage t>
 TwoDMatrix
 DecisionRuleImpl<t>::simulate(emethod em, int np, const ConstVector &ystart,
                               ShockRealization &sr) const
@@ -347,7 +350,7 @@ DecisionRuleImpl<t>::simulate(emethod em, int np, const ConstVector &ystart,
    that the steady state (fix point) is cancelled and added once. Hence
    we have two special methods. */
 
-template <int t>
+template <Storage t>
 void
 DecisionRuleImpl<t>::evaluate(emethod em, Vector &out, const ConstVector &ys,
                               const ConstVector &u) const
@@ -370,7 +373,7 @@ DecisionRuleImpl<t>::evaluate(emethod em, Vector &out, const ConstVector &ys,
 /* This is easy. We just return the newly created copy using the
    centralized constructor. */
 
-template <int t>
+template <Storage t>
 std::unique_ptr<DecisionRule>
 DecisionRuleImpl<t>::centralizedClone(const Vector &fixpoint) const
 {
@@ -380,19 +383,19 @@ DecisionRuleImpl<t>::centralizedClone(const Vector &fixpoint) const
 /* Here we only encapsulate two implementations to one, deciding
    according to the parameter. */
 
-template <int t>
+template <Storage t>
 void
 DecisionRuleImpl<t>::eval(emethod em, Vector &out, const ConstVector &v) const
 {
   if (em == emethod::horner)
-    _Tparent::evalHorner(out, v);
+    _Tpol::evalHorner(out, v);
   else
-    _Tparent::evalTrad(out, v);
+    _Tpol::evalTrad(out, v);
 }
 
 /* Write the decision rule and steady state to the MAT file. */
 
-template <int t>
+template <Storage t>
 void
 DecisionRuleImpl<t>::writeMat(mat_t *fd, const std::string &prefix) const
 {
@@ -402,63 +405,63 @@ DecisionRuleImpl<t>::writeMat(mat_t *fd, const std::string &prefix) const
   ConstTwoDMatrix(dum).writeMat(fd, prefix + "_ss");
 }
 
-/* This is exactly the same as |DecisionRuleImpl<KOrder::fold>|. The
+/* This is exactly the same as |DecisionRuleImpl<Storage::fold>|. The
    only difference is that we have a conversion from
    |UnfoldDecisionRule|, which is exactly
-   |DecisionRuleImpl<KOrder::unfold>|. */
+   |DecisionRuleImpl<Storage::unfold>|. */
 
 class UnfoldDecisionRule;
-class FoldDecisionRule : public DecisionRuleImpl<KOrder::fold>
+class FoldDecisionRule : public DecisionRuleImpl<Storage::fold>
 {
   friend class UnfoldDecisionRule;
 public:
-  FoldDecisionRule(const ctraits<KOrder::fold>::Tpol &pol, const PartitionY &yp, int nuu,
+  FoldDecisionRule(const ctraits<Storage::fold>::Tpol &pol, const PartitionY &yp, int nuu,
                    const ConstVector &ys)
-    : DecisionRuleImpl<KOrder::fold>(pol, yp, nuu, ys)
+    : DecisionRuleImpl<Storage::fold>(pol, yp, nuu, ys)
   {
   }
-  FoldDecisionRule(ctraits<KOrder::fold>::Tpol &pol, const PartitionY &yp, int nuu,
+  FoldDecisionRule(ctraits<Storage::fold>::Tpol &pol, const PartitionY &yp, int nuu,
                    const ConstVector &ys)
-    : DecisionRuleImpl<KOrder::fold>(pol, yp, nuu, ys)
+    : DecisionRuleImpl<Storage::fold>(pol, yp, nuu, ys)
   {
   }
-  FoldDecisionRule(const ctraits<KOrder::fold>::Tg &g, const PartitionY &yp, int nuu,
+  FoldDecisionRule(const ctraits<Storage::fold>::Tg &g, const PartitionY &yp, int nuu,
                    const ConstVector &ys, double sigma)
-    : DecisionRuleImpl<KOrder::fold>(g, yp, nuu, ys, sigma)
+    : DecisionRuleImpl<Storage::fold>(g, yp, nuu, ys, sigma)
   {
   }
-  FoldDecisionRule(const DecisionRuleImpl<KOrder::fold> &dr, const ConstVector &fixpoint)
-    : DecisionRuleImpl<KOrder::fold>(dr, fixpoint)
+  FoldDecisionRule(const DecisionRuleImpl<Storage::fold> &dr, const ConstVector &fixpoint)
+    : DecisionRuleImpl<Storage::fold>(dr, fixpoint)
   {
   }
   FoldDecisionRule(const UnfoldDecisionRule &udr);
 };
 
-/* This is exactly the same as |DecisionRuleImpl<KOrder::unfold>|, but
+/* This is exactly the same as |DecisionRuleImpl<Storage::unfold>|, but
    with a conversion from |FoldDecisionRule|, which is exactly
-   |DecisionRuleImpl<KOrder::fold>|. */
+   |DecisionRuleImpl<Storage::fold>|. */
 
-class UnfoldDecisionRule : public DecisionRuleImpl<KOrder::unfold>
+class UnfoldDecisionRule : public DecisionRuleImpl<Storage::unfold>
 {
   friend class FoldDecisionRule;
 public:
-  UnfoldDecisionRule(const ctraits<KOrder::unfold>::Tpol &pol, const PartitionY &yp, int nuu,
+  UnfoldDecisionRule(const ctraits<Storage::unfold>::Tpol &pol, const PartitionY &yp, int nuu,
                      const ConstVector &ys)
-    : DecisionRuleImpl<KOrder::unfold>(pol, yp, nuu, ys)
+    : DecisionRuleImpl<Storage::unfold>(pol, yp, nuu, ys)
   {
   }
-  UnfoldDecisionRule(ctraits<KOrder::unfold>::Tpol &pol, const PartitionY &yp, int nuu,
+  UnfoldDecisionRule(ctraits<Storage::unfold>::Tpol &pol, const PartitionY &yp, int nuu,
                      const ConstVector &ys)
-    : DecisionRuleImpl<KOrder::unfold>(pol, yp, nuu, ys)
+    : DecisionRuleImpl<Storage::unfold>(pol, yp, nuu, ys)
   {
   }
-  UnfoldDecisionRule(const ctraits<KOrder::unfold>::Tg &g, const PartitionY &yp, int nuu,
+  UnfoldDecisionRule(const ctraits<Storage::unfold>::Tg &g, const PartitionY &yp, int nuu,
                      const ConstVector &ys, double sigma)
-    : DecisionRuleImpl<KOrder::unfold>(g, yp, nuu, ys, sigma)
+    : DecisionRuleImpl<Storage::unfold>(g, yp, nuu, ys, sigma)
   {
   }
-  UnfoldDecisionRule(const DecisionRuleImpl<KOrder::unfold> &dr, const ConstVector &fixpoint)
-    : DecisionRuleImpl<KOrder::unfold>(dr, fixpoint)
+  UnfoldDecisionRule(const DecisionRuleImpl<Storage::unfold> &dr, const ConstVector &fixpoint)
+    : DecisionRuleImpl<Storage::unfold>(dr, fixpoint)
   {
   }
   UnfoldDecisionRule(const FoldDecisionRule &udr);
@@ -477,18 +480,21 @@ public:
    Jacobian of the solved system is given by derivatives stored in
    |bigfder|. */
 
-template <int t>
+template <Storage t>
 class DRFixPoint : public ctraits<t>::Tpol
 {
-  using _Tparent = typename ctraits<t>::Tpol;
+  using _Tpol = typename ctraits<t>::Tpol;
+  using _Tg = typename ctraits<t>::Tg;
+  using _Ttensor = typename ctraits<t>::Ttensor;
+  using _Ttensym = typename ctraits<t>::Ttensym;
   constexpr static int max_iter = 10000;
   constexpr static int max_newton_iter = 50;
   constexpr static int newton_pause = 100;
   constexpr static double tol = 1e-10;
   const Vector ysteady;
   const PartitionY ypart;
-  std::unique_ptr<_Tparent> bigf;
-  std::unique_ptr<_Tparent> bigfder;
+  std::unique_ptr<_Tpol> bigf;
+  std::unique_ptr<_Tpol> bigfder;
 public:
   using emethod = typename DecisionRule::emethod;
   DRFixPoint(const _Tg &g, const PartitionY &yp,
@@ -526,19 +532,19 @@ private:
    (|Symmetry(1)|). Then the derivative of the $F$ polynomial is
    calculated. */
 
-template <int t>
+template <Storage t>
 DRFixPoint<t>::DRFixPoint(const _Tg &g, const PartitionY &yp,
                           const Vector &ys, double sigma)
   : ctraits<t>::Tpol(yp.ny(), yp.nys()),
   ysteady(ys), ypart(yp)
 {
   fillTensors(g, sigma);
-  _Tparent yspol(ypart.nstat, ypart.nys(), *this);
-  bigf = std::make_unique<_Tparent>(const_cast<const _Tparent &>(yspol));
+  _Tpol yspol(ypart.nstat, ypart.nys(), *this);
+  bigf = std::make_unique<_Tpol>(const_cast<const _Tpol &>(yspol));
   _Ttensym &frst = bigf->get(Symmetry{1});
   for (int i = 0; i < ypart.nys(); i++)
     frst.get(i, i) = frst.get(i, i) - 1;
-  bigfder = std::make_unique<_Tparent>(*bigf, 0);
+  bigfder = std::make_unique<_Tpol>(*bigf, 0);
 }
 
 /* Here we fill the tensors for the |DRFixPoint| class. We ignore the
@@ -547,7 +553,7 @@ DRFixPoint<t>::DRFixPoint(const _Tg &g, const PartitionY &yp,
    dimension and |d|, and add ${\sigma^k\over d!k!}g_{y^d\sigma^k}$ to
    the tensor $g_{(y)^d}$. */
 
-template <int t>
+template <Storage t>
 void
 DRFixPoint<t>::fillTensors(const _Tg &g, double sigma)
 {
@@ -584,7 +590,7 @@ DRFixPoint<t>::fillTensors(const _Tg &g, double sigma)
    |urelax| is less that |urelax_threshold|, we stop searching and stop
    the Newton. */
 
-template <int t>
+template <Storage t>
 bool
 DRFixPoint<t>::solveNewton(Vector &y)
 {
@@ -661,7 +667,7 @@ DRFixPoint<t>::solveNewton(Vector &y)
 
    The |out| vector is not touched if the algorithm has not convered. */
 
-template <int t>
+template <Storage t>
 bool
 DRFixPoint<t>::calcFixPoint(emethod em, Vector &out)
 {
@@ -695,7 +701,7 @@ DRFixPoint<t>::calcFixPoint(emethod em, Vector &out)
 
   if (converged)
     {
-      _Tparent::evalHorner(out, ystar);
+      _Tpol::evalHorner(out, ystar);
       out.add(1.0, ysteady);
     }
 
diff --git a/dynare++/kord/dynamic_model.cc b/dynare++/kord/dynamic_model.cc
index 6766a706015ed8014b4a229239c76d338bdf2396..118e7f1251a2ec3c4114b0bbf8eba9ac6a4a564e 100644
--- a/dynare++/kord/dynamic_model.cc
+++ b/dynare++/kord/dynamic_model.cc
@@ -2,31 +2,31 @@
 
 #include "dynamic_model.hh"
 
-#include <cstring>
+#include <iostream>
+#include <algorithm>
 
 void
 NameList::print() const
 {
   for (int i = 0; i < getNum(); i++)
-    printf("%s\n", getName(i));
+    std::cout << getName(i) << '\n';
 }
 
 void
-NameList::writeMat(mat_t *fd, const char *vname) const
+NameList::writeMat(mat_t *fd, const std::string &vname) const
 {
   int maxlen = 0;
   for (int i = 0; i < getNum(); i++)
-    if (maxlen < (int) strlen(getName(i)))
-      maxlen = (int) strlen(getName(i));
+    maxlen = std::max(maxlen, static_cast<int>(getName(i).size()));
 
   if (maxlen == 0)
     return;
 
-  auto *m = new char[getNum()*maxlen];
+  std::vector<char> m(getNum()*maxlen);
 
   for (int i = 0; i < getNum(); i++)
     for (int j = 0; j < maxlen; j++)
-      if (j < (int) strlen(getName(i)))
+      if (j < static_cast<int>(getName(i).size()))
         m[j*getNum()+i] = getName(i)[j];
       else
         m[j*getNum()+i] = ' ';
@@ -35,23 +35,20 @@ NameList::writeMat(mat_t *fd, const char *vname) const
   dims[0] = getNum();
   dims[1] = maxlen;
 
-  matvar_t *v = Mat_VarCreate(vname, MAT_C_CHAR, MAT_T_UINT8, 2, dims, m, 0);
+  matvar_t *v = Mat_VarCreate(vname.c_str(), MAT_C_CHAR, MAT_T_UINT8, 2, dims, m.data(), 0);
 
   Mat_VarWrite(fd, v, MAT_COMPRESSION_NONE);
 
   Mat_VarFree(v);
-  delete[] m;
 }
 
 void
-NameList::writeMatIndices(mat_t *fd, const char *prefix) const
+NameList::writeMatIndices(mat_t *fd, const std::string &prefix) const
 {
-  char tmp[100];
   TwoDMatrix aux(1, 1);
   for (int i = 0; i < getNum(); i++)
     {
-      sprintf(tmp, "%s_i_%s", prefix, getName(i));
       aux.get(0, 0) = i+1;
-      aux.writeMat(fd, tmp);
+      aux.writeMat(fd, prefix + "_i_" + getName(i));
     }
 }
diff --git a/dynare++/kord/dynamic_model.hh b/dynare++/kord/dynamic_model.hh
index 58021f01d05997d2605a49384971d6f51d36df7c..df8609b99df831f2d32e735893b79a1bb57dc2ab 100644
--- a/dynare++/kord/dynamic_model.hh
+++ b/dynare++/kord/dynamic_model.hh
@@ -2,7 +2,7 @@
 
 // Dynamic model abstraction
 
-/* This file only defines a generic interface to an SDGE model. The model
+/* This file only defines a generic interface to a DSGE model. The model
    takes the form:
    $$E_t\left[f(g^{**}(g^*(y,u_t),u_{t+1}),g(y,u),y,u_t)\right]=0$$
    The interface is defined via pure virtual class |DynamicModel|. */
@@ -15,22 +15,24 @@
 
 #include "Vector.hh"
 
+#include <memory>
+#include <string>
+
 /* The class is a virtual pure class which provides an access to names
    of the variables. */
 
 class NameList
 {
 public:
-  virtual ~NameList()
-  = default;
+  virtual ~NameList() = default;
   virtual int getNum() const = 0;
-  virtual const char *getName(int i) const = 0;
+  virtual const std::string &getName(int i) const = 0;
   void print() const;
-  void writeMat(mat_t *fd, const char *vname) const;
-  void writeMatIndices(mat_t *fd, const char *prefix) const;
+  void writeMat(mat_t *fd, const std::string &vname) const;
+  void writeMatIndices(mat_t *fd, const std::string &prefix) const;
 };
 
-/* This is the interface to an information on a generic SDGE
+/* This is the interface to an information on a generic DSGE
    model. It is sufficient for calculations of policy rule Taylor
    approximations at some (not necessarily deterministic) steady state.
 
@@ -82,9 +84,8 @@ public:
 class DynamicModel
 {
 public:
-  virtual DynamicModel *clone() const = 0;
-  virtual ~DynamicModel()
-  = default;
+  virtual std::unique_ptr<DynamicModel> clone() const = 0;
+  virtual ~DynamicModel() = default;
 
   virtual int nstat() const = 0;
   virtual int nboth() const = 0;
@@ -98,13 +99,13 @@ public:
     return nstat()+nboth()+npred()+nforw();
   }
 
-  virtual const NameList&getAllEndoNames() const = 0;
-  virtual const NameList&getStateNames() const = 0;
-  virtual const NameList&getExogNames() const = 0;
-  virtual const TwoDMatrix&getVcov() const = 0;
-  virtual const TensorContainer<FSSparseTensor>&getModelDerivatives() const = 0;
-  virtual const Vector&getSteady() const = 0;
-  virtual Vector&getSteady() = 0;
+  virtual const NameList &getAllEndoNames() const = 0;
+  virtual const NameList &getStateNames() const = 0;
+  virtual const NameList &getExogNames() const = 0;
+  virtual const TwoDMatrix &getVcov() const = 0;
+  virtual const TensorContainer<FSSparseTensor> &getModelDerivatives() const = 0;
+  virtual const Vector &getSteady() const = 0;
+  virtual Vector &getSteady() = 0;
 
   virtual void solveDeterministicSteady() = 0;
   virtual void evaluateSystem(Vector &out, const ConstVector &yy, const Vector &xx) = 0;
diff --git a/dynare++/kord/faa_di_bruno.cc b/dynare++/kord/faa_di_bruno.cc
index d303d2b945ac79c6017defdd85dd3f43775c86f4..5cde7551bf502375df389162636166ddd338d7e4 100644
--- a/dynare++/kord/faa_di_bruno.cc
+++ b/dynare++/kord/faa_di_bruno.cc
@@ -5,8 +5,6 @@
 
 #include <cmath>
 
-double FaaDiBruno::magic_mult = 1.5;
-
 // |FaaDiBruno::calculate| folded sparse code
 /* We take an opportunity to refine the stack container to avoid
    allocation of more memory than available. */
@@ -121,19 +119,19 @@ FaaDiBruno::estimRefinment(const TensorDimens &tdims, int nr, int l,
                            int &avmem_mb, int &tmpmem_mb)
 {
   int nthreads = sthread::detach_thread_group::max_parallel_threads;
-  long int per_size1 = tdims.calcUnfoldMaxOffset();
-  auto per_size2 = (long int) pow((double) tdims.getNVS().getMax(), l);
+  long per_size1 = tdims.calcUnfoldMaxOffset();
+  long per_size2 = static_cast<long>(std::pow(tdims.getNVS().getMax(), l));
   double lambda = 0.0;
-  long int per_size = sizeof(double)*nr
-    *(long int) (lambda*per_size1+(1-lambda)*per_size2);
-  long int mem = SystemResources::availableMemory();
+  long per_size = sizeof(double)*nr
+    *static_cast<long>(lambda*per_size1+(1-lambda)*per_size2);
+  long mem = SystemResources::availableMemory();
   int max = 0;
-  double num_cols = ((double) (mem-magic_mult*nthreads*per_size))
+  double num_cols = static_cast<double>(mem-magic_mult*nthreads*per_size)
     /nthreads/sizeof(double)/nr;
   if (num_cols > 0)
     {
-      double maxd = pow(num_cols, ((double) 1)/l);
-      max = (int) floor(maxd);
+      double maxd = std::pow(num_cols, 1.0/l);
+      max = static_cast<int>(std::floor(maxd));
     }
   if (max == 0)
     {
@@ -145,6 +143,6 @@ FaaDiBruno::estimRefinment(const TensorDimens &tdims, int nr, int l,
       rec << endrec;
     }
   avmem_mb = mem/1024/1024;
-  tmpmem_mb = (nthreads*per_size)/1024/1024;
+  tmpmem_mb = nthreads*per_size/1024/1024;
   return max;
 }
diff --git a/dynare++/kord/faa_di_bruno.hh b/dynare++/kord/faa_di_bruno.hh
index 07913e2b8baf2ed43ff2c32d044d7ded89698bca..aabcff0276036d8db0f1a2bb071b282ca5bcf815 100644
--- a/dynare++/kord/faa_di_bruno.hh
+++ b/dynare++/kord/faa_di_bruno.hh
@@ -38,7 +38,7 @@ public:
                  UGSTensor &out);
 protected:
   int estimRefinment(const TensorDimens &tdims, int nr, int l, int &avmem_mb, int &tmpmem_mb);
-  static double magic_mult;
+  constexpr static double magic_mult = 1.5;
 };
 
 #endif
diff --git a/dynare++/kord/first_order.cc b/dynare++/kord/first_order.cc
index 21de0808bd151f5d46f0238969c42359e798cd02..d5672342937c85c42257d58965daf029baf01f71 100644
--- a/dynare++/kord/first_order.cc
+++ b/dynare++/kord/first_order.cc
@@ -5,16 +5,17 @@
 
 #include <dynlapack.h>
 
-double qz_criterium = 1.000001;
+double FirstOrder::qz_criterium_global;
+std::mutex FirstOrder::mut;
 
 /* This is a function which selects the eigenvalues pair used by
    |dgges|. See documentation to DGGES for details. Here we want
    to select (return true) the pairs for which $\alpha<\beta$. */
 
 lapack_int
-order_eigs(const double *alphar, const double *alphai, const double *beta)
+FirstOrder::order_eigs(const double *alphar, const double *alphai, const double *beta)
 {
-  return (*alphar **alphar + *alphai **alphai < *beta **beta * qz_criterium * qz_criterium);
+  return (*alphar **alphar + *alphai **alphai < *beta **beta * qz_criterium_global * qz_criterium_global);
 }
 
 /* Here we solve the linear approximation. The result are the matrices
@@ -36,8 +37,6 @@ FirstOrder::solve(const TwoDMatrix &fd)
   JournalRecordPair pa(journal);
   pa << "Recovering first order derivatives " << endrec;
 
-  ::qz_criterium = FirstOrder::qz_criterium;
-
   // **********************
   // solve derivatives |gy|
   // **********************
@@ -164,21 +163,22 @@ FirstOrder::solve(const TwoDMatrix &fd)
   lapack_int ldvsl = vsl.getLD(), ldvsr = vsr.getLD();
   lapack_int lwork = 100*n+16;
   Vector work(lwork);
-  auto *bwork = new lapack_int[n];
+  std::vector<lapack_int> bwork(n);
   lapack_int info;
   lapack_int sdim2 = sdim;
-  dgges("N", "V", "S", order_eigs, &n, matE.getData().base(), &lda,
+  {
+    std::lock_guard<std::mutex> lk{mut};
+    qz_criterium_global = qz_criterium;
+    dgges("N", "V", "S", order_eigs, &n, matE.getData().base(), &lda,
         matD.getData().base(), &ldb, &sdim2, alphar.base(), alphai.base(),
         beta.base(), vsl.getData().base(), &ldvsl, vsr.getData().base(), &ldvsr,
-        work.base(), &lwork, bwork, &info);
+        work.base(), &lwork, bwork.data(), &info);
+  }
   if (info)
-    {
-      throw KordException(__FILE__, __LINE__,
-                          "DGGES returns an error in FirstOrder::solve");
-    }
+    throw KordException(__FILE__, __LINE__,
+                        "DGGES returns an error in FirstOrder::solve");
   sdim = sdim2;
   bk_cond = (sdim == ypart.nys());
-  delete[] bwork;
 
   // make submatrices of right space
   /* Here we setup submatrices of the matrix $Z$. */
@@ -214,7 +214,7 @@ FirstOrder::solve(const TwoDMatrix &fd)
   gy.place(fder, ypart.nstat+ypart.nys(), 0);
 
   // check difference for derivatives of both
-  GeneralMatrix bder((const GeneralMatrix &)sfder, ypart.nstat, 0, ypart.nboth, ypart.nys());
+  GeneralMatrix bder(const_cast<const GeneralMatrix &>(sfder), ypart.nstat, 0, ypart.nboth, ypart.nys());
   GeneralMatrix bder2(preder, ypart.npred, 0, ypart.nboth, ypart.nys());
   bder.add(-1, bder2);
   b_error = bder.getData().getMax();
@@ -248,10 +248,8 @@ FirstOrder::solve(const TwoDMatrix &fd)
   journalEigs();
 
   if (!gy.isFinite() || !gu.isFinite())
-    {
-      throw KordException(__FILE__, __LINE__,
-                          "NaN or Inf asserted in first order derivatives in FirstOrder::solve");
-    }
+    throw KordException(__FILE__, __LINE__,
+                        "NaN or Inf asserted in first order derivatives in FirstOrder::solve");
 }
 
 void
@@ -269,24 +267,22 @@ FirstOrder::journalEigs()
          << " " << "npred=" << ypart.nys() << endrec;
     }
   if (!bk_cond)
-    {
-      for (int i = 0; i < alphar.length(); i++)
-        {
-          if (i == sdim || i == ypart.nys())
-            {
-              JournalRecord jr(journal);
-              jr << "---------------------------------------------------- ";
-              if (i == sdim)
-                jr << "sdim";
-              else
-                jr << "npred";
-              jr << endrec;
-            }
-          JournalRecord jr(journal);
-          double mod = sqrt(alphar[i]*alphar[i]+alphai[i]*alphai[i]);
-          mod = mod/round(100000*std::abs(beta[i]))*100000;
-          jr << i << "\t(" << alphar[i] << "," << alphai[i] << ") / " << beta[i]
-             << "  \t" << mod << endrec;
-        }
-    }
+    for (int i = 0; i < alphar.length(); i++)
+      {
+        if (i == sdim || i == ypart.nys())
+          {
+            JournalRecord jr(journal);
+            jr << "---------------------------------------------------- ";
+            if (i == sdim)
+              jr << "sdim";
+            else
+              jr << "npred";
+            jr << endrec;
+          }
+        JournalRecord jr(journal);
+        double mod = std::sqrt(alphar[i]*alphar[i]+alphai[i]*alphai[i]);
+        mod = mod/std::round(100000*std::abs(beta[i]))*100000;
+        jr << i << "\t(" << alphar[i] << "," << alphai[i] << ") / " << beta[i]
+           << "  \t" << mod << endrec;
+      }
 }
diff --git a/dynare++/kord/first_order.hh b/dynare++/kord/first_order.hh
index 79045a9378570928f0ac985c24c6a21ac9091482..03326927677f28d41dadbb4d9b6f43833045fc89 100644
--- a/dynare++/kord/first_order.hh
+++ b/dynare++/kord/first_order.hh
@@ -7,11 +7,13 @@
 
 #include "korder.hh"
 
-template<int>
+#include <mutex>
+
+template<Storage>
 class FirstOrderDerivs;
 class FirstOrder
 {
-  template <int>
+  template <Storage>
   friend class FirstOrderDerivs;
   PartitionY ypart;
   int nu;
@@ -25,6 +27,17 @@ class FirstOrder
   Vector beta;
   double qz_criterium;
   Journal &journal;
+
+  // Passed to LAPACK's DGGES
+  static lapack_int order_eigs(const double *alphar, const double *alphai, const double *beta);
+
+  // The value of qz_criterium_global used by the order_eigs function
+  /* NB: we have no choice but to use a global variable, since LAPACK won't
+     take a closure */
+  static double qz_criterium_global;
+
+  // Protects the static qz_criterium_global
+  static std::mutex mut;
 public:
   FirstOrder(int num_stat, int num_pred, int num_both, int num_forw,
              int num_u, const FSSparseTensor &f, Journal &jr, double qz_crit)
@@ -63,7 +76,7 @@ protected:
 /* This class only converts the derivatives $g_{y^*}$ and $g_u$ to a
    folded or unfolded container. */
 
-template <int t>
+template <Storage t>
 class FirstOrderDerivs : public ctraits<t>::Tg
 {
 public:
@@ -71,11 +84,11 @@ public:
     : ctraits<t>::Tg(4)
   {
     IntSequence nvs{fo.ypart.nys(), fo.nu, fo.nu, 1};
-    auto ten = std::make_unique<_Ttensor>(fo.ypart.ny(), TensorDimens(Symmetry{1, 0, 0, 0}, nvs));
+    auto ten = std::make_unique<typename ctraits<t>::Ttensor>(fo.ypart.ny(), TensorDimens(Symmetry{1, 0, 0, 0}, nvs));
     ten->zeros();
     ten->add(1.0, fo.gy);
     this->insert(std::move(ten));
-    ten = std::make_unique<_Ttensor>(fo.ypart.ny(), TensorDimens(Symmetry{0, 1, 0, 0}, nvs));
+    ten = std::make_unique<typename ctraits<t>::Ttensor>(fo.ypart.ny(), TensorDimens(Symmetry{0, 1, 0, 0}, nvs));
     ten->zeros();
     ten->add(1.0, fo.gu);
     this->insert(std::move(ten));
diff --git a/dynare++/kord/global_check.cc b/dynare++/kord/global_check.cc
index 43027d5e5e05eea0ea6dd7c4bb627ed42417fe75..80f66eeef7ddb454e065abaf6133cca4ab8dadd6 100644
--- a/dynare++/kord/global_check.cc
+++ b/dynare++/kord/global_check.cc
@@ -9,6 +9,7 @@
 #include "product.hh"
 #include "quasi_mcarlo.hh"
 
+#include <utility>
 #include <cmath>
 
 /* Here we just set a reference to the approximation, and create a new
@@ -16,37 +17,21 @@
 
 ResidFunction::ResidFunction(const Approximation &app)
   : VectorFunction(app.getModel().nexog(), app.getModel().numeq()), approx(app),
-    model(app.getModel().clone()),
-    yplus(nullptr), ystar(nullptr), u(nullptr), hss(nullptr)
+    model(app.getModel().clone())
 {
 }
 
 ResidFunction::ResidFunction(const ResidFunction &rf)
-  : VectorFunction(rf), approx(rf.approx), model(rf.model->clone()),
-    yplus(nullptr), ystar(nullptr), u(nullptr), hss(nullptr)
+  : VectorFunction(rf), approx(rf.approx), model(rf.model->clone())
 {
   if (rf.yplus)
-    yplus = new Vector(*(rf.yplus));
+    yplus = std::make_unique<Vector>(*(rf.yplus));
   if (rf.ystar)
-    ystar = new Vector(*(rf.ystar));
+    ystar = std::make_unique<Vector>(*(rf.ystar));
   if (rf.u)
-    u = new Vector(*(rf.u));
+    u = std::make_unique<Vector>(*(rf.u));
   if (rf.hss)
-    hss = new FTensorPolynomial(*(rf.hss));
-}
-
-ResidFunction::~ResidFunction()
-{
-  delete model;
-  // delete |y| and |u| dependent data
-  if (yplus)
-    delete yplus;
-  if (ystar)
-    delete ystar;
-  if (u)
-    delete u;
-  if (hss)
-    delete hss;
+    hss = std::make_unique<FTensorPolynomial>(*(rf.hss));
 }
 
 /* This sets $y^*$ and $u$. We have to create |ystar|, |u|, |yplus| and
@@ -55,58 +40,41 @@ ResidFunction::~ResidFunction()
 void
 ResidFunction::setYU(const ConstVector &ys, const ConstVector &xx)
 {
-  // delete |y| and |u| dependent data
-  /* NB: code shared with the destructor */
-  if (yplus)
-    delete yplus;
-  if (ystar)
-    delete ystar;
-  if (u)
-    delete u;
-  if (hss)
-    delete hss;
-
-  ystar = new Vector(ys);
-  u = new Vector(xx);
-  yplus = new Vector(model->numeq());
+  ystar = std::make_unique<Vector>(ys);
+  u = std::make_unique<Vector>(xx);
+  yplus = std::make_unique<Vector>(model->numeq());
   approx.getFoldDecisionRule().evaluate(DecisionRule::emethod::horner,
                                         *yplus, *ystar, *u);
 
   // make a tensor polynomial of in-place subtensors from decision rule
-  /* Here we use a dirty tricky of converting |const| to non-|const| to
-     obtain a polynomial of subtensor corresponding to non-predetermined
-     variables. However, this new non-|const| polynomial will be used for a
+  /* Note that the non-|const| polynomial will be used for a
      construction of |hss| and will be used in |const| context. So this
-     dirty thing is safe.
+     const_cast is safe.
 
      Note, that there is always a folded decision rule in |Approximation|. */
-  union {const FoldDecisionRule *c; FoldDecisionRule *n;} dr;
-  dr.c = &(approx.getFoldDecisionRule());
+  const FoldDecisionRule &dr = approx.getFoldDecisionRule();
   FTensorPolynomial dr_ss(model->nstat()+model->npred(), model->nboth()+model->nforw(),
-                          *(dr.n));
+                          const_cast<FoldDecisionRule &>(dr));
 
   // make |ytmp_star| be a difference of |yplus| from steady
   Vector ytmp_star(ConstVector(*yplus, model->nstat(), model->npred()+model->nboth()));
-  ConstVector ysteady_star(dr.c->getSteady(), model->nstat(),
+  ConstVector ysteady_star(dr.getSteady(), model->nstat(),
                            model->npred()+model->nboth());
   ytmp_star.add(-1.0, ysteady_star);
 
   // make |hss| and add steady to it
   /* Here is the |const| context of |dr_ss|. */
-  hss = new FTensorPolynomial(dr_ss, ytmp_star);
-  ConstVector ysteady_ss(dr.c->getSteady(), model->nstat()+model->npred(),
+  hss = std::make_unique<FTensorPolynomial>(dr_ss, ytmp_star);
+  ConstVector ysteady_ss(dr.getSteady(), model->nstat()+model->npred(),
                          model->nboth()+model->nforw());
   if (hss->check(Symmetry{0}))
-    {
-      hss->get(Symmetry{0}).getData().add(1.0, ysteady_ss);
-    }
+    hss->get(Symmetry{0}).getData().add(1.0, ysteady_ss);
   else
     {
       auto ten = std::make_unique<FFSTensor>(hss->nrows(), hss->nvars(), 0);
       ten->getData() = ysteady_ss;
       hss->insert(std::move(ten));
     }
-
 }
 
 /* Here we evaluate the residual $F(y^*,u,u')$. We have to evaluate |hss|
@@ -133,7 +101,7 @@ GlobalChecker::check(const Quadrature &quad, int level,
                      const ConstVector &ys, const ConstVector &x, Vector &out)
 {
   for (int ifunc = 0; ifunc < vfs.getNum(); ifunc++)
-    ((GResidFunction &) (vfs.getFunc(ifunc))).setYU(ys, x);
+    dynamic_cast<GResidFunction &>(vfs.getFunc(ifunc)).setYU(ys, x);
   quad.integrate(vfs, level, out);
 }
 
@@ -168,13 +136,13 @@ GlobalChecker::check(int max_evals, const ConstTwoDMatrix &y,
 
   bool take_smolyak = (smol_evals < prod_evals) && (smol_level >= prod_level-1);
 
-  Quadrature *quad;
+  std::unique_ptr<Quadrature> quad;
   int lev;
 
   // create the quadrature and report the decision
   if (take_smolyak)
     {
-      quad = new SmolyakQuadrature(model.nexog(), smol_level, gh);
+      quad = std::make_unique<SmolyakQuadrature>(model.nexog(), smol_level, gh);
       lev = smol_level;
       JournalRecord rec(journal);
       rec << "Selected Smolyak (level,evals)=(" << smol_level << ","
@@ -183,7 +151,7 @@ GlobalChecker::check(int max_evals, const ConstTwoDMatrix &y,
     }
   else
     {
-      quad = new ProductQuadrature(model.nexog(), gh);
+      quad = std::make_unique<ProductQuadrature>(model.nexog(), gh);
       lev = prod_level;
       JournalRecord rec(journal);
       rec << "Selected product (level,evals)=(" << prod_level << ","
@@ -201,8 +169,6 @@ GlobalChecker::check(int max_evals, const ConstTwoDMatrix &y,
       Vector outj{out.getCol(j)};
       check(*quad, lev, yj, xj, outj);
     }
-
-  delete quad;
 }
 
 /* This method checks an error of the approximation by evaluating
@@ -211,7 +177,7 @@ GlobalChecker::check(int max_evals, const ConstTwoDMatrix &y,
    $-mult\cdot\sigma$ to $mult\cdot\sigma$ in |m| steps. */
 
 void
-GlobalChecker::checkAlongShocksAndSave(mat_t *fd, const char *prefix,
+GlobalChecker::checkAlongShocksAndSave(mat_t *fd, const std::string &prefix,
                                        int m, double mult, int max_evals)
 {
   JournalRecordPair pa(journal);
@@ -219,15 +185,15 @@ GlobalChecker::checkAlongShocksAndSave(mat_t *fd, const char *prefix,
      << mult << " std errors, granularity " << m << endrec;
 
   // setup |y_mat| of steady states for checking
-  TwoDMatrix y_mat(model.numeq(), 2*m *model.nexog()+1);
+  TwoDMatrix y_mat(model.numeq(), 2*m*model.nexog()+1);
   for (int j = 0; j < 2*m*model.nexog()+1; j++)
     {
       Vector yj{y_mat.getCol(j)};
-      yj = (const Vector &) model.getSteady();
+      yj = model.getSteady();
     }
 
   // setup |exo_mat| for checking
-  TwoDMatrix exo_mat(model.nexog(), 2*m *model.nexog()+1);
+  TwoDMatrix exo_mat(model.nexog(), 2*m*model.nexog()+1);
   exo_mat.zeros();
   for (int ishock = 0; ishock < model.nexog(); ishock++)
     {
@@ -235,12 +201,11 @@ GlobalChecker::checkAlongShocksAndSave(mat_t *fd, const char *prefix,
       for (int j = 0; j < 2*m; j++)
         {
           int jmult = (j < m) ? j-m : j-m+1;
-          exo_mat.get(ishock, 1+2*m*ishock+j)
-            = mult*jmult*max_sigma/m;
+          exo_mat.get(ishock, 1+2*m*ishock+j) = mult*jmult*max_sigma/m;
         }
     }
 
-  TwoDMatrix errors(model.numeq(), 2*m *model.nexog()+1);
+  TwoDMatrix errors(model.numeq(), 2*m*model.nexog()+1);
   check(max_evals, y_mat, exo_mat, errors);
 
   // report errors along shock and save them
@@ -248,12 +213,9 @@ GlobalChecker::checkAlongShocksAndSave(mat_t *fd, const char *prefix,
   JournalRecord rec(journal);
   rec << "Shock    value         error" << endrec;
   ConstVector err0{errors.getCol(0)};
-  char shock[9];
-  char erbuf[17];
   for (int ishock = 0; ishock < model.nexog(); ishock++)
     {
       TwoDMatrix err_out(model.numeq(), 2*m+1);
-      sprintf(shock, "%-8s", model.getExogNames().getName(ishock));
       for (int j = 0; j < 2*m+1; j++)
         {
           int jj;
@@ -273,13 +235,12 @@ GlobalChecker::checkAlongShocksAndSave(mat_t *fd, const char *prefix,
               error = err0;
             }
           JournalRecord rec1(journal);
-          sprintf(erbuf, "%12.7g    ", error.getMax());
-          rec1 << shock << " " << exo_mat.get(ishock, jj)
-               << "\t" << erbuf << endrec;
+          std::string shockname{model.getExogNames().getName(ishock)};
+          shockname.resize(8, ' ');
+          rec1 << shockname << ' ' << exo_mat.get(ishock, jj)
+               << "\t" << error.getMax() << endrec;
         }
-      char tmp[100];
-      sprintf(tmp, "%s_shock_%s_errors", prefix, model.getExogNames().getName(ishock));
-      err_out.writeMat(fd, tmp);
+      err_out.writeMat(fd, prefix + "_shock_" + model.getExogNames().getName(ishock) + "_errors");
     }
 }
 
@@ -298,7 +259,7 @@ GlobalChecker::checkAlongShocksAndSave(mat_t *fd, const char *prefix,
    the results. */
 
 void
-GlobalChecker::checkOnEllipseAndSave(mat_t *fd, const char *prefix,
+GlobalChecker::checkOnEllipseAndSave(mat_t *fd, const std::string &prefix,
                                      int m, double mult, int max_evals)
 {
   JournalRecordPair pa(journal);
@@ -310,7 +271,7 @@ GlobalChecker::checkOnEllipseAndSave(mat_t *fd, const char *prefix,
      a submatrix of covariances of all endogenous variables. The submatrix
      corresponds to state variables (predetermined plus both). */
   TwoDMatrix ycov{approx.calcYCov()};
-  TwoDMatrix ycovpred((const TwoDMatrix &) ycov, model.nstat(), model.nstat(),
+  TwoDMatrix ycovpred(const_cast<const TwoDMatrix &>(ycov), model.nstat(), model.nstat(),
                       model.npred()+model.nboth(), model.npred()+model.nboth());
   SymSchurDecomp ssd(ycovpred);
   ssd.correctDefinitness(1.e-05);
@@ -381,18 +342,15 @@ GlobalChecker::checkOnEllipseAndSave(mat_t *fd, const char *prefix,
   TwoDMatrix out(model.numeq(), ymat.ncols());
   check(max_evals, ymat, umat, out);
 
-  char tmp[100];
-  sprintf(tmp, "%s_ellipse_points", prefix);
-  ymat.writeMat(fd, tmp);
-  sprintf(tmp, "%s_ellipse_errors", prefix);
-  out.writeMat(fd, tmp);
+  ymat.writeMat(fd, prefix + "_ellipse_points");
+  out.writeMat(fd, prefix + "_ellipse_errors");
 }
 
 /* Here we check the errors along a simulation. We simulate, then set
    |x| to zeros, check and save results. */
 
 void
-GlobalChecker::checkAlongSimulationAndSave(mat_t *fd, const char *prefix,
+GlobalChecker::checkAlongSimulationAndSave(mat_t *fd, const std::string &prefix,
                                            int m, int max_evals)
 {
   JournalRecordPair pa(journal);
@@ -406,9 +364,6 @@ GlobalChecker::checkAlongSimulationAndSave(mat_t *fd, const char *prefix,
   TwoDMatrix out(model.numeq(), m);
   check(max_evals, y, x, out);
 
-  char tmp[100];
-  sprintf(tmp, "%s_simul_points", prefix);
-  y.writeMat(fd, tmp);
-  sprintf(tmp, "%s_simul_errors", prefix);
-  out.writeMat(fd, tmp);
+  y.writeMat(fd, prefix + "_simul_points");
+  out.writeMat(fd, prefix + "_simul_errors");
 }
diff --git a/dynare++/kord/global_check.hh b/dynare++/kord/global_check.hh
index e35be844e65f63d9dc46d0c3e355eba6917b1ba6..c25536fa61c476b70c7539596576659ded5f05d1 100644
--- a/dynare++/kord/global_check.hh
+++ b/dynare++/kord/global_check.hh
@@ -68,16 +68,13 @@ class ResidFunction : public VectorFunction
 {
 protected:
   const Approximation &approx;
-  DynamicModel *model;
-  Vector *yplus;
-  Vector *ystar;
-  Vector *u;
-  FTensorPolynomial *hss;
+  std::unique_ptr<DynamicModel> model;
+  std::unique_ptr<Vector> yplus, ystar, u;
+  std::unique_ptr<FTensorPolynomial> hss;
 public:
   ResidFunction(const Approximation &app);
   ResidFunction(const ResidFunction &rf);
   
-  ~ResidFunction() override;
   std::unique_ptr<VectorFunction>
   clone() const override
   {
@@ -96,8 +93,6 @@ public:
     : GaussConverterFunction(std::make_unique<ResidFunction>(app), app.getModel().getVcov())
   {
   }
-  GResidFunction(const GResidFunction &rf) = default;
-  ~GResidFunction() override = default;
   std::unique_ptr<VectorFunction>
   clone() const override
   {
@@ -106,7 +101,7 @@ public:
   void
   setYU(const ConstVector &ys, const ConstVector &xx)
   {
-    ((ResidFunction *) func)->setYU(ys, xx);
+    dynamic_cast<ResidFunction *>(func)->setYU(ys, xx);
   }
 };
 
@@ -137,13 +132,13 @@ public:
   }
   void check(int max_evals, const ConstTwoDMatrix &y,
              const ConstTwoDMatrix &x, TwoDMatrix &out);
-  void checkAlongShocksAndSave(mat_t *fd, const char *prefix,
+  void checkAlongShocksAndSave(mat_t *fd, const std::string &prefix,
                                int m, double mult, int max_evals);
-  void checkOnEllipseAndSave(mat_t *fd, const char *prefix,
+  void checkOnEllipseAndSave(mat_t *fd, const std::string &prefix,
                              int m, double mult, int max_evals);
-  void checkAlongSimulationAndSave(mat_t *fd, const char *prefix,
+  void checkAlongSimulationAndSave(mat_t *fd, const std::string &prefix,
                                    int m, int max_evals);
-  void checkUnconditionalAndSave(mat_t *fd, const char *prefix,
+  void checkUnconditionalAndSave(mat_t *fd, const std::string &prefix,
                                  int m, int max_evals);
 protected:
   void check(const Quadrature &quad, int level,
diff --git a/dynare++/kord/journal.cc b/dynare++/kord/journal.cc
index 5f42e3384bcc5a1fa20260e10265b033092606e4..c38128bf668e719708bd428cd16bf0b2af9b385c 100644
--- a/dynare++/kord/journal.cc
+++ b/dynare++/kord/journal.cc
@@ -6,6 +6,7 @@
 #include <iomanip>
 #include <cmath>
 #include <ctime>
+#include <limits>
 
 #ifndef __MINGW32__
 # include <sys/time.h>     // For getrusage()
@@ -89,8 +90,8 @@ SystemResources::SystemResources()
   idrss = rus.ru_idrss;
   majflt = rus.ru_majflt;
 #else
-  utime = -1.0;
-  stime = -1.0;
+  utime = std::numeric_limits<double>::quiet_NaN();
+  stime = std::numeric_limits<double>::quiet_NaN();
   idrss = -1;
   majflt = -1;
 #endif
@@ -98,7 +99,7 @@ SystemResources::SystemResources()
 #ifndef __MINGW32__
   getloadavg(&load_avg, 1);
 #else
-  load_avg = -1.0;
+  load_avg = std::numeric_limits<double>::quiet_NaN();
 #endif
 
   pg_avail = availablePhysicalPages();
diff --git a/dynare++/kord/korder.cc b/dynare++/kord/korder.cc
index fec3b0ac8efae3a014ec5731339cecb4f34733af..162025e9a3916afcd1c477ce86ea9d23a846718e 100644
--- a/dynare++/kord/korder.cc
+++ b/dynare++/kord/korder.cc
@@ -3,12 +3,6 @@
 #include "kord_exception.hh"
 #include "korder.hh"
 
-PLUMatrix::PLUMatrix(const PLUMatrix &plu)
-  : TwoDMatrix(plu), inv(plu.inv), ipiv(new lapack_int[nrows()])
-{
-  memcpy(ipiv, plu.ipiv, nrows()*sizeof(lapack_int));
-}
-
 /* Here we set |ipiv| and |inv| members of the |PLUMatrix| depending on
    its content. It is assumed that subclasses will call this method at
    the end of their constructors. */
@@ -18,8 +12,8 @@ PLUMatrix::calcPLU()
 {
   lapack_int info;
   lapack_int rows = nrows(), lda = ld;
-  inv = (const Vector &) getData();
-  dgetrf(&rows, &rows, inv.base(), &lda, ipiv, &info);
+  inv = const_cast<const Vector &>(getData());
+  dgetrf(&rows, &rows, inv.base(), &lda, ipiv.data(), &info);
 }
 
 /* Here we just call the LAPACK machinery to multiply by the inverse. */
@@ -34,9 +28,8 @@ PLUMatrix::multInv(TwoDMatrix &m) const
   lapack_int mcols = m.ncols();
   lapack_int mrows = m.nrows();
   lapack_int ldb = m.getLD();
-  double *mbase = m.getData().base();
-  dgetrs("N", &mrows, &mcols, inv.base(), &lda, ipiv,
-         mbase, &ldb, &info);
+  dgetrs("N", &mrows, &mcols, inv.base(), &lda, ipiv.data(),
+         m.getData().base(), &ldb, &info);
   KORD_RAISE_IF(info != 0,
                 "Info!=0 in PLUMatrix::multInv");
 }
@@ -101,116 +94,116 @@ MatrixS::MatrixS(const FSSparseTensor &f, const IntSequence &ss,
    interesting here. */
 
 template<>
-ctraits<KOrder::unfold>::Tg& KOrder::g<KOrder::unfold>()
+ctraits<Storage::unfold>::Tg& KOrder::g<Storage::unfold>()
 {
   return _ug;
 }
 template<>
-const ctraits<KOrder::unfold>::Tg& KOrder::g<KOrder::unfold>() const
+const ctraits<Storage::unfold>::Tg& KOrder::g<Storage::unfold>() const
 { return _ug;}
 template<>
-ctraits<KOrder::fold>::Tg& KOrder::g<KOrder::fold>()
+ctraits<Storage::fold>::Tg& KOrder::g<Storage::fold>()
 {
   return _fg;
 }
 template<>
-const ctraits<KOrder::fold>::Tg& KOrder::g<KOrder::fold>() const
+const ctraits<Storage::fold>::Tg& KOrder::g<Storage::fold>() const
 { return _fg;}
 template<>
-ctraits<KOrder::unfold>::Tgs& KOrder::gs<KOrder::unfold>()
+ctraits<Storage::unfold>::Tgs& KOrder::gs<Storage::unfold>()
 {
   return _ugs;
 }
 template<>
-const ctraits<KOrder::unfold>::Tgs& KOrder::gs<KOrder::unfold>() const
+const ctraits<Storage::unfold>::Tgs& KOrder::gs<Storage::unfold>() const
 { return _ugs;}
 template<>
-ctraits<KOrder::fold>::Tgs& KOrder::gs<KOrder::fold>()
+ctraits<Storage::fold>::Tgs& KOrder::gs<Storage::fold>()
 {
   return _fgs;
 }
 template<>
-const ctraits<KOrder::fold>::Tgs& KOrder::gs<KOrder::fold>() const
+const ctraits<Storage::fold>::Tgs& KOrder::gs<Storage::fold>() const
 { return _fgs;}
 template<>
-ctraits<KOrder::unfold>::Tgss& KOrder::gss<KOrder::unfold>()
+ctraits<Storage::unfold>::Tgss& KOrder::gss<Storage::unfold>()
 {
   return _ugss;
 }
 template<>
-const ctraits<KOrder::unfold>::Tgss& KOrder::gss<KOrder::unfold>() const
+const ctraits<Storage::unfold>::Tgss& KOrder::gss<Storage::unfold>() const
 { return _ugss;}
 template<>
-ctraits<KOrder::fold>::Tgss& KOrder::gss<KOrder::fold>()
+ctraits<Storage::fold>::Tgss& KOrder::gss<Storage::fold>()
 {
   return _fgss;
 }
 template<>
-const ctraits<KOrder::fold>::Tgss& KOrder::gss<KOrder::fold>() const
+const ctraits<Storage::fold>::Tgss& KOrder::gss<Storage::fold>() const
 { return _fgss;}
 template<>
-ctraits<KOrder::unfold>::TG& KOrder::G<KOrder::unfold>()
+ctraits<Storage::unfold>::TG& KOrder::G<Storage::unfold>()
 {
   return _uG;
 }
 template<>
-const ctraits<KOrder::unfold>::TG& KOrder::G<KOrder::unfold>() const
+const ctraits<Storage::unfold>::TG& KOrder::G<Storage::unfold>() const
 { return _uG;}
 template<>
-ctraits<KOrder::fold>::TG& KOrder::G<KOrder::fold>()
+ctraits<Storage::fold>::TG& KOrder::G<Storage::fold>()
 {
   return _fG;
 }
 template<>
-const ctraits<KOrder::fold>::TG& KOrder::G<KOrder::fold>() const
+const ctraits<Storage::fold>::TG& KOrder::G<Storage::fold>() const
 { return _fG;}
 template<>
-ctraits<KOrder::unfold>::TZstack& KOrder::Zstack<KOrder::unfold>()
+ctraits<Storage::unfold>::TZstack& KOrder::Zstack<Storage::unfold>()
 {
   return _uZstack;
 }
 template<>
-const ctraits<KOrder::unfold>::TZstack& KOrder::Zstack<KOrder::unfold>() const
+const ctraits<Storage::unfold>::TZstack& KOrder::Zstack<Storage::unfold>() const
 { return _uZstack;}
 template<>
-ctraits<KOrder::fold>::TZstack& KOrder::Zstack<KOrder::fold>()
+ctraits<Storage::fold>::TZstack& KOrder::Zstack<Storage::fold>()
 {
   return _fZstack;
 }
 template<>
-const ctraits<KOrder::fold>::TZstack& KOrder::Zstack<KOrder::fold>() const
+const ctraits<Storage::fold>::TZstack& KOrder::Zstack<Storage::fold>() const
 { return _fZstack;}
 template<>
-ctraits<KOrder::unfold>::TGstack& KOrder::Gstack<KOrder::unfold>()
+ctraits<Storage::unfold>::TGstack& KOrder::Gstack<Storage::unfold>()
 {
   return _uGstack;
 }
 template<>
-const ctraits<KOrder::unfold>::TGstack& KOrder::Gstack<KOrder::unfold>() const
+const ctraits<Storage::unfold>::TGstack& KOrder::Gstack<Storage::unfold>() const
 { return _uGstack;}
 template<>
-ctraits<KOrder::fold>::TGstack& KOrder::Gstack<KOrder::fold>()
+ctraits<Storage::fold>::TGstack& KOrder::Gstack<Storage::fold>()
 {
   return _fGstack;
 }
 template<>
-const ctraits<KOrder::fold>::TGstack& KOrder::Gstack<KOrder::fold>() const
+const ctraits<Storage::fold>::TGstack& KOrder::Gstack<Storage::fold>() const
 { return _fGstack;}
 template<>
-ctraits<KOrder::unfold>::Tm& KOrder::m<KOrder::unfold>()
+ctraits<Storage::unfold>::Tm& KOrder::m<Storage::unfold>()
 {
   return _um;
 }
 template<>
-const ctraits<KOrder::unfold>::Tm& KOrder::m<KOrder::unfold>() const
+const ctraits<Storage::unfold>::Tm& KOrder::m<Storage::unfold>() const
 { return _um;}
 template<>
-ctraits<KOrder::fold>::Tm& KOrder::m<KOrder::fold>()
+ctraits<Storage::fold>::Tm& KOrder::m<Storage::fold>()
 {
   return _fm;
 }
 template<>
-const ctraits<KOrder::fold>::Tm& KOrder::m<KOrder::fold>() const
+const ctraits<Storage::fold>::Tm& KOrder::m<Storage::fold>() const
 { return _fm;}
 
 /* Here is the constructor of the |KOrder| class. We pass what we have
@@ -264,19 +257,19 @@ KOrder::KOrder(int num_stat, int num_pred, int num_both, int num_forw,
      the container. We insert a new physical copies. */
   auto tgy = std::make_unique<UGSTensor>(ny, TensorDimens(Symmetry{1, 0, 0, 0}, nvs));
   tgy->getData() = gy.getData();
-  insertDerivative<unfold>(std::move(tgy));
+  insertDerivative<Storage::unfold>(std::move(tgy));
   auto tgu = std::make_unique<UGSTensor>(ny, TensorDimens(Symmetry{0, 1, 0, 0}, nvs));
   tgu->getData() = gu.getData();
-  insertDerivative<unfold>(std::move(tgu));
+  insertDerivative<Storage::unfold>(std::move(tgu));
 
   // put $G_y$, $G_u$ and $G_{u'}$ to the container
   /* Also note that since $g_\sigma$ is zero, so $G_\sigma$. */
-  auto tGy = faaDiBrunoG<unfold>(Symmetry{1, 0, 0, 0});
-  G<unfold>().insert(std::move(tGy));
-  auto tGu = faaDiBrunoG<unfold>(Symmetry{0, 1, 0, 0});
-  G<unfold>().insert(std::move(tGu));
-  auto tGup = faaDiBrunoG<unfold>(Symmetry{0, 0, 1, 0});
-  G<unfold>().insert(std::move(tGup));
+  auto tGy = faaDiBrunoG<Storage::unfold>(Symmetry{1, 0, 0, 0});
+  G<Storage::unfold>().insert(std::move(tGy));
+  auto tGu = faaDiBrunoG<Storage::unfold>(Symmetry{0, 1, 0, 0});
+  G<Storage::unfold>().insert(std::move(tGu));
+  auto tGup = faaDiBrunoG<Storage::unfold>(Symmetry{0, 0, 1, 0});
+  G<Storage::unfold>().insert(std::move(tGup));
 }
 
 // |KOrder::sylvesterSolve| unfolded specialization
@@ -295,7 +288,7 @@ KOrder::KOrder(int num_stat, int num_pred, int num_both, int num_forw,
 
 template<>
 void
-KOrder::sylvesterSolve<KOrder::unfold>(ctraits<unfold>::Ttensor &der) const
+KOrder::sylvesterSolve<Storage::unfold>(ctraits<Storage::unfold>::Ttensor &der) const
 {
   JournalRecordPair pa(journal);
   pa << "Sylvester equation for dimension = " << der.getSym()[0] << endrec;
@@ -303,7 +296,7 @@ KOrder::sylvesterSolve<KOrder::unfold>(ctraits<unfold>::Ttensor &der) const
     {
       KORD_RAISE_IF(!der.isFinite(),
                     "RHS of Sylverster is not finite");
-      TwoDMatrix gs_y(gs<unfold>().get(Symmetry{1, 0, 0, 0}));
+      TwoDMatrix gs_y(gs<Storage::unfold>().get(Symmetry{1, 0, 0, 0}));
       GeneralSylvester sylv(der.getSym()[0], ny, ypart.nys(),
                             ypart.nstat+ypart.npred,
                             matA.getData(), matB.getData(),
@@ -323,11 +316,11 @@ KOrder::sylvesterSolve<KOrder::unfold>(ctraits<unfold>::Ttensor &der) const
 
 template<>
 void
-KOrder::sylvesterSolve<KOrder::fold>(ctraits<fold>::Ttensor &der) const
+KOrder::sylvesterSolve<Storage::fold>(ctraits<Storage::fold>::Ttensor &der) const
 {
-  ctraits<unfold>::Ttensor tmp(der);
-  sylvesterSolve<unfold>(tmp);
-  ctraits<fold>::Ttensor ftmp(tmp);
+  ctraits<Storage::unfold>::Ttensor tmp(der);
+  sylvesterSolve<Storage::unfold>(tmp);
+  ctraits<Storage::fold>::Ttensor ftmp(tmp);
   der.getData() = (const Vector &) (ftmp.getData());
 }
 
@@ -337,28 +330,28 @@ KOrder::switchToFolded()
   JournalRecordPair pa(journal);
   pa << "Switching from unfolded to folded" << endrec;
 
-  int maxdim = g<unfold>().getMaxDim();
+  int maxdim = g<Storage::unfold>().getMaxDim();
   for (int dim = 1; dim <= maxdim; dim++)
     for (auto &si : SymmetrySet(dim, 4))
       {
-        if (si[2] == 0 && g<unfold>().check(si))
+        if (si[2] == 0 && g<Storage::unfold>().check(si))
           {
-            auto ft = std::make_unique<FGSTensor>(g<unfold>().get(si));
-            insertDerivative<fold>(std::move(ft));
+            auto ft = std::make_unique<FGSTensor>(g<Storage::unfold>().get(si));
+            insertDerivative<Storage::fold>(std::move(ft));
             if (dim > 1)
               {
-                gss<unfold>().remove(si);
-                gs<unfold>().remove(si);
-                g<unfold>().remove(si);
+                gss<Storage::unfold>().remove(si);
+                gs<Storage::unfold>().remove(si);
+                g<Storage::unfold>().remove(si);
               }
           }
-        if (G<unfold>().check(si))
+        if (G<Storage::unfold>().check(si))
           {
-            auto ft = std::make_unique<FGSTensor>(G<unfold>().get(si));
-            G<fold>().insert(std::move(ft));
+            auto ft = std::make_unique<FGSTensor>(G<Storage::unfold>().get(si));
+            G<Storage::fold>().insert(std::move(ft));
             if (dim > 1)
               {
-                G<fold>().remove(si);
+                G<Storage::fold>().remove(si);
               }
           }
       }
diff --git a/dynare++/kord/korder.hh b/dynare++/kord/korder.hh
index 11cb6ebe9706eb496a4639d89fd929b781a82394..da1e122148cc9962bc53a1c203c4016e04fe31e4 100644
--- a/dynare++/kord/korder.hh
+++ b/dynare++/kord/korder.hh
@@ -44,50 +44,34 @@
 #include <cmath>
 #include <type_traits>
 
-#define TYPENAME typename
-
-#define _Ttensor TYPENAME ctraits<t>::Ttensor
-#define _Ttensym TYPENAME ctraits<t>::Ttensym
-#define _Tg TYPENAME ctraits<t>::Tg
-#define _Tgs TYPENAME ctraits<t>::Tgs
-#define _Tgss TYPENAME ctraits<t>::Tgss
-#define _TG TYPENAME ctraits<t>::TG
-#define _TZstack TYPENAME ctraits<t>::TZstack
-#define _TGstack TYPENAME ctraits<t>::TGstack
-#define _TZXstack TYPENAME ctraits<t>::TZXstack
-#define _TGXstack TYPENAME ctraits<t>::TGXstack
-#define __Tm TYPENAME ctraits<t>::Tm
-#define _Tpol TYPENAME ctraits<t>::Tpol
-
-/* Here we use a classical IF template, and in |ctraits| we define a
-   number of types. We have a type for tensor |Ttensor|, and types for
-   each pair of folded/unfolded containers used as a member in |KOrder|.
-
-   Note that we have enumeration |fold| and |unfold|. These must have the
-   same value as the same enumeration in |KOrder|. */
+// The enum class passed as template parameter for many data structures
+enum class Storage { fold, unfold };
+
+/* In |ctraits| we define a number of types. We have a type for tensor
+   |Ttensor|, and types for each pair of folded/unfolded containers used as a
+   member in |KOrder|. */
 
 class FoldedZXContainer;
 class UnfoldedZXContainer;
 class FoldedGXContainer;
 class UnfoldedGXContainer;
 
-template <int type>
+template <Storage type>
 class ctraits
 {
 public:
-  enum { fold, unfold };
-  using Ttensor = std::conditional_t<type == fold, FGSTensor, UGSTensor>;
-  using Ttensym = std::conditional_t<type == fold, FFSTensor, UFSTensor>;
-  using Tg = std::conditional_t<type == fold, FGSContainer, UGSContainer>;
-  using Tgs = std::conditional_t<type == fold, FGSContainer, UGSContainer>;
-  using Tgss = std::conditional_t<type == fold, FGSContainer, UGSContainer>;
-  using TG = std::conditional_t<type == fold, FGSContainer, UGSContainer>;
-  using TZstack = std::conditional_t<type == fold, FoldedZContainer, UnfoldedZContainer>;
-  using TGstack = std::conditional_t<type == fold, FoldedGContainer, UnfoldedGContainer>;
-  using Tm = std::conditional_t<type == fold, FNormalMoments, UNormalMoments>;
-  using Tpol = std::conditional_t<type == fold, FTensorPolynomial, UTensorPolynomial>;
-  using TZXstack = std::conditional_t<type == fold, FoldedZXContainer, UnfoldedZXContainer>;
-  using TGXstack = std::conditional_t<type == fold, FoldedGXContainer, UnfoldedGXContainer>;
+  using Ttensor = std::conditional_t<type == Storage::fold, FGSTensor, UGSTensor>;
+  using Ttensym = std::conditional_t<type == Storage::fold, FFSTensor, UFSTensor>;
+  using Tg = std::conditional_t<type == Storage::fold, FGSContainer, UGSContainer>;
+  using Tgs = std::conditional_t<type == Storage::fold, FGSContainer, UGSContainer>;
+  using Tgss = std::conditional_t<type == Storage::fold, FGSContainer, UGSContainer>;
+  using TG = std::conditional_t<type == Storage::fold, FGSContainer, UGSContainer>;
+  using TZstack = std::conditional_t<type == Storage::fold, FoldedZContainer, UnfoldedZContainer>;
+  using TGstack = std::conditional_t<type == Storage::fold, FoldedGContainer, UnfoldedGContainer>;
+  using Tm = std::conditional_t<type == Storage::fold, FNormalMoments, UNormalMoments>;
+  using Tpol = std::conditional_t<type == Storage::fold, FTensorPolynomial, UTensorPolynomial>;
+  using TZXstack = std::conditional_t<type == Storage::fold, FoldedZXContainer, UnfoldedZXContainer>;
+  using TGXstack = std::conditional_t<type == Storage::fold, FoldedGXContainer, UnfoldedGXContainer>;
 };
 
 /* The |PartitionY| class defines the partitioning of state variables
@@ -148,18 +132,13 @@ public:
   PLUMatrix(int n)
     : TwoDMatrix(n, n),
       inv(nrows()*ncols()),
-      ipiv(new lapack_int[nrows()])
-  {
-  }
-  PLUMatrix(const PLUMatrix &plu);
-  ~PLUMatrix() override
+      ipiv(nrows())
   {
-    delete [] ipiv;
   }
   void multInv(TwoDMatrix &m) const;
 private:
   Vector inv;
-  lapack_int *ipiv;
+  std::vector<lapack_int> ipiv;
 protected:
   void calcPLU();
 };
@@ -258,9 +237,7 @@ public:
 
    Most of the code is templated, and template types are calculated in
    |ctraits|. So all templated methods get a template argument |T|, which
-   can be either |fold|, or |unfold|. To shorten a reference to a type
-   calculated by |ctraits| for a particular |t|, we define the following
-   macros.
+   can be either |Storage::fold|, or |Storage::unfold|.
 */
 
 class KOrder
@@ -296,34 +273,40 @@ protected:
 
   /* These are the declarations of the template functions accessing the
      containers. */
-  template<int t>
-  _Tg&g();
-  template<int t>
-  const _Tg&g() const;
-  template<int t>
-  _Tgs&gs();
-  template<int t>
-  const _Tgs&gs() const;
-  template<int t>
-  _Tgss&gss();
-  template<int t>
-  const _Tgss&gss() const;
-  template<int t>
-  _TG&G();
-  template<int t>
-  const _TG&G() const;
-  template<int t>
-  _TZstack&Zstack();
-  template<int t>
-  const _TZstack&Zstack() const;
-  template<int t>
-  _TGstack&Gstack();
-  template<int t>
-  const _TGstack&Gstack() const;
-  template<int t>
-  __Tm&m();
-  template<int t>
-  const __Tm&m() const;
+  template<Storage t>
+  typename ctraits<t>::Tg &g();
+  template<Storage t>
+  const typename ctraits<t>::Tg &g() const;
+
+  template<Storage t>
+  typename ctraits<t>::Tgs &gs();
+  template<Storage t>
+  const typename ctraits<t>::Tgs &gs() const;
+
+  template<Storage t>
+  typename ctraits<t>::Tgss &gss();
+  template<Storage t>
+  const typename ctraits<t>::Tgss &gss() const;
+
+  template<Storage t>
+  typename ctraits<t>::TG &G();
+  template<Storage t>
+  const typename ctraits<t>::TG &G() const;
+
+  template<Storage t>
+  typename ctraits<t>::TZstack &Zstack();
+  template<Storage t>
+  const typename ctraits<t>::TZstack &Zstack() const;
+
+  template<Storage t>
+  typename ctraits<t>::TGstack &Gstack();
+  template<Storage t>
+  const typename ctraits<t>::TGstack &Gstack() const;
+
+  template<Storage t>
+  typename ctraits<t>::Tm &m();
+  template<Storage t>
+  const typename ctraits<t>::Tm &m() const;
 
   Journal &journal;
 public:
@@ -331,13 +314,12 @@ public:
          const TensorContainer<FSSparseTensor> &fcont,
          const TwoDMatrix &gy, const TwoDMatrix &gu, const TwoDMatrix &v,
          Journal &jr);
-  enum { fold, unfold };
-  template <int t>
+  template <Storage t>
   void performStep(int order);
-  template <int t>
+  template <Storage t>
   double check(int dim) const;
-  template <int t>
-  Vector *calcStochShift(int order, double sigma) const;
+  template <Storage t>
+  Vector calcStochShift(int order, double sigma) const;
   void switchToFolded();
   const PartitionY &
   getPartY() const
@@ -357,59 +339,59 @@ public:
   static bool
   is_even(int i)
   {
-    return (i/2)*2 == i;
+    return i % 2 == 0;
   }
 protected:
-  template <int t>
-  void insertDerivative(std::unique_ptr<_Ttensor> der);
-  template<int t>
-  void sylvesterSolve(_Ttensor &der) const;
+  template <Storage t>
+  void insertDerivative(std::unique_ptr<typename ctraits<t>::Ttensor> der);
+  template<Storage t>
+  void sylvesterSolve(typename ctraits<t>::Ttensor &der) const;
 
-  template <int t>
-  std::unique_ptr<_Ttensor> faaDiBrunoZ(const Symmetry &sym) const;
-  template <int t>
-  std::unique_ptr<_Ttensor> faaDiBrunoG(const Symmetry &sym) const;
+  template <Storage t>
+  std::unique_ptr<typename ctraits<t>::Ttensor> faaDiBrunoZ(const Symmetry &sym) const;
+  template <Storage t>
+  std::unique_ptr<typename ctraits<t>::Ttensor> faaDiBrunoG(const Symmetry &sym) const;
 
-  template<int t>
+  template<Storage t>
   void recover_y(int i);
-  template <int t>
+  template <Storage t>
   void recover_yu(int i, int j);
-  template <int t>
+  template <Storage t>
   void recover_ys(int i, int j);
-  template <int t>
+  template <Storage t>
   void recover_yus(int i, int j, int k);
-  template <int t>
+  template <Storage t>
   void recover_s(int i);
-  template<int t>
+  template<Storage t>
   void fillG(int i, int j, int k);
 
-  template <int t>
-  _Ttensor *calcD_ijk(int i, int j, int k) const;
-  template <int t>
-  _Ttensor *calcD_ik(int i, int k) const;
-  template <int t>
-  _Ttensor *calcD_k(int k) const;
-
-  template <int t>
-  _Ttensor *calcE_ijk(int i, int j, int k) const;
-  template <int t>
-  _Ttensor *calcE_ik(int i, int k) const;
-  template <int t>
-  _Ttensor *calcE_k(int k) const;
+  template <Storage t>
+  typename ctraits<t>::Ttensor calcD_ijk(int i, int j, int k) const;
+  template <Storage t>
+  typename ctraits<t>::Ttensor calcD_ik(int i, int k) const;
+  template <Storage t>
+  typename ctraits<t>::Ttensor calcD_k(int k) const;
+
+  template <Storage t>
+  typename ctraits<t>::Ttensor calcE_ijk(int i, int j, int k) const;
+  template <Storage t>
+  typename ctraits<t>::Ttensor calcE_ik(int i, int k) const;
+  template <Storage t>
+  typename ctraits<t>::Ttensor calcE_k(int k) const;
 };
 
 /* Here we insert the result to the container. Along the insertion, we
    also create subtensors and insert as well. */
 
-template <int t>
+template <Storage t>
 void
-KOrder::insertDerivative(std::unique_ptr<_Ttensor> der)
+KOrder::insertDerivative(std::unique_ptr<typename ctraits<t>::Ttensor> der)
 {
   auto der_ptr = der.get();
   g<t>().insert(std::move(der));
-  gs<t>().insert(std::make_unique<_Ttensor>(ypart.nstat, ypart.nys(), *der_ptr));
-  gss<t>().insert(std::make_unique<_Ttensor>(ypart.nstat+ypart.npred,
-                                             ypart.nyss(), *der_ptr));
+  gs<t>().insert(std::make_unique<typename ctraits<t>::Ttensor>(ypart.nstat, ypart.nys(), *der_ptr));
+  gss<t>().insert(std::make_unique<typename ctraits<t>::Ttensor>(ypart.nstat+ypart.npred,
+                                                                 ypart.nyss(), *der_ptr));
 }
 
 /* Here we implement Faa Di Bruno formula
@@ -419,13 +401,13 @@ KOrder::insertDerivative(std::unique_ptr<_Ttensor> der)
    where $s$ is a given outer symmetry and $k$ is the dimension of the
    symmetry. */
 
-template <int t>
-std::unique_ptr<_Ttensor>
+template <Storage t>
+std::unique_ptr<typename ctraits<t>::Ttensor>
 KOrder::faaDiBrunoZ(const Symmetry &sym) const
 {
   JournalRecordPair pa(journal);
   pa << "Faa Di Bruno Z container for " << sym << endrec;
-  auto res = std::make_unique<_Ttensor>(ny, TensorDimens(sym, nvs));
+  auto res = std::make_unique<typename ctraits<t>::Ttensor>(ny, TensorDimens(sym, nvs));
   FaaDiBruno bruno(journal);
   bruno.calculate(Zstack<t>(), f, *res);
   return res;
@@ -434,14 +416,14 @@ KOrder::faaDiBrunoZ(const Symmetry &sym) const
 /* The same as |@<|KOrder::faaDiBrunoZ| templated code@>|, but for
    $g^{**}$ and $G$ stack. */
 
-template <int t>
-std::unique_ptr<_Ttensor>
+template <Storage t>
+std::unique_ptr<typename ctraits<t>::Ttensor>
 KOrder::faaDiBrunoG(const Symmetry &sym) const
 {
   JournalRecordPair pa(journal);
   pa << "Faa Di Bruno G container for " << sym << endrec;
   TensorDimens tdims(sym, nvs);
-  auto res = std::make_unique<_Ttensor>(ypart.nyss(), tdims);
+  auto res = std::make_unique<typename ctraits<t>::Ttensor>(ypart.nyss(), tdims);
   FaaDiBruno bruno(journal);
   bruno.calculate(Gstack<t>(), gss<t>(), *res);
   return res;
@@ -459,7 +441,7 @@ KOrder::faaDiBrunoG(const Symmetry &sym) const
 
    {\bf Provides:} $g_{y^i}$, and $G_{y^i}$ */
 
-template<int t>
+template<Storage t>
 void
 KOrder::recover_y(int i)
 {
@@ -478,9 +460,9 @@ KOrder::recover_y(int i)
 
   insertDerivative<t>(std::move(g_yi));
 
-  _Ttensor &gss_y = gss<t>().get(Symmetry{1, 0, 0, 0});
+  auto &gss_y = gss<t>().get(Symmetry{1, 0, 0, 0});
   gs<t>().multAndAdd(gss_y, *G_yi_ptr);
-  _Ttensor &gss_yi = gss<t>().get(sym);
+  auto &gss_yi = gss<t>().get(sym);
   gs<t>().multAndAdd(gss_yi, *G_yi_ptr);
 }
 
@@ -495,7 +477,7 @@ KOrder::recover_y(int i)
 
    {\bf Provides:} $g_{y^iu^j}$, and $G_{y^iu^j}$ */
 
-template <int t>
+template <Storage t>
 void
 KOrder::recover_yu(int i, int j)
 {
@@ -535,7 +517,7 @@ KOrder::recover_yu(int i, int j)
    $G_{y^iu'^m\sigma^{j-m}}$ for $m=1,\ldots,j$. The latter is calculated
    by |fillG| before the actual calculation. */
 
-template <int t>
+template <Storage t>
 void
 KOrder::recover_ys(int i, int j)
 {
@@ -554,16 +536,14 @@ KOrder::recover_ys(int i, int j)
       auto g_yisj = faaDiBrunoZ<t>(sym);
 
       {
-        _Ttensor *D_ij = calcD_ik<t>(i, j);
-        g_yisj->add(1.0, *D_ij);
-        delete D_ij;
+        auto D_ij = calcD_ik<t>(i, j);
+        g_yisj->add(1.0, D_ij);
       }
 
       if (j >= 3)
         {
-          _Ttensor *E_ij = calcE_ik<t>(i, j);
-          g_yisj->add(1.0, *E_ij);
-          delete E_ij;
+          auto E_ij = calcE_ik<t>(i, j);
+          g_yisj->add(1.0, E_ij);
         }
 
       g_yisj->mult(-1.0);
@@ -596,7 +576,7 @@ KOrder::recover_ys(int i, int j)
    {\bf Provides:} $g_{y^iu^j\sigma^k}$, $G_{y^iu^j\sigma^k}$, and
    $G_{y^iu^ju'^m\sigma^{k-m}}$ for $m=1,\ldots, k$ */
 
-template <int t>
+template <Storage t>
 void
 KOrder::recover_yus(int i, int j, int k)
 {
@@ -615,16 +595,14 @@ KOrder::recover_yus(int i, int j, int k)
       auto g_yiujsk = faaDiBrunoZ<t>(sym);
 
       {
-        _Ttensor *D_ijk = calcD_ijk<t>(i, j, k);
-        g_yiujsk->add(1.0, *D_ijk);
-        delete D_ijk;
+        auto D_ijk = calcD_ijk<t>(i, j, k);
+        g_yiujsk->add(1.0, D_ijk);
       }
 
       if (k >= 3)
         {
-          _Ttensor *E_ijk = calcE_ijk<t>(i, j, k);
-          g_yiujsk->add(1.0, *E_ijk);
-          delete E_ijk;
+          auto E_ijk = calcE_ijk<t>(i, j, k);
+          g_yiujsk->add(1.0, E_ijk);
         }
 
       g_yiujsk->mult(-1.0);
@@ -664,7 +642,7 @@ KOrder::recover_yus(int i, int j, int k)
    {\bf Provides:} $g_{\sigma^i}$, $G_{\sigma^i}$, and
    $G_{u'^m\sigma^{i-m}}$ for $m=1,\ldots,i$ */
 
-template <int t>
+template <Storage t>
 void
 KOrder::recover_s(int i)
 {
@@ -683,16 +661,14 @@ KOrder::recover_s(int i)
       auto g_si = faaDiBrunoZ<t>(sym);
 
       {
-        _Ttensor *D_i = calcD_k<t>(i);
-        g_si->add(1.0, *D_i);
-        delete D_i;
+        auto D_i = calcD_k<t>(i);
+        g_si->add(1.0, D_i);
       }
 
       if (i >= 3)
         {
-          _Ttensor *E_i = calcE_k<t>(i);
-          g_si->add(1.0, *E_i);
-          delete E_i;
+          auto E_i = calcE_k<t>(i);
+          g_si->add(1.0, E_i);
         }
 
       g_si->mult(-1.0);
@@ -709,18 +685,16 @@ KOrder::recover_s(int i)
    $m=1,\ldots, k$. The derivatives are inserted only for $k-m$ being
    even. */
 
-template<int t>
+template<Storage t>
 void
 KOrder::fillG(int i, int j, int k)
 {
   for (int m = 1; m <= k; m++)
-    {
-      if (is_even(k-m))
-        {
-          auto G_yiujupms = faaDiBrunoG<t>(Symmetry{i, j, m, k-m});
-          G<t>().insert(std::move(G_yiujupms));
-        }
-    }
+    if (is_even(k-m))
+      {
+        auto G_yiujupms = faaDiBrunoG<t>(Symmetry{i, j, m, k-m});
+        G<t>().insert(std::move(G_yiujupms));
+      }
 }
 
 /* Here we calculate
@@ -730,16 +704,16 @@ KOrder::fillG(int i, int j, int k)
    \left[\Sigma\right]^{\gamma_1\ldots\gamma_k}$$
    So it is non zero only for even $k$. */
 
-template <int t>
-_Ttensor *
+template <Storage t>
+typename ctraits<t>::Ttensor
 KOrder::calcD_ijk(int i, int j, int k) const
 {
-  _Ttensor *res =       new _Ttensor(ny, TensorDimens(Symmetry{i, j, 0, 0}, nvs));
-  res->zeros();
+  typename ctraits<t>::Ttensor res(ny, TensorDimens(Symmetry{i, j, 0, 0}, nvs));
+  res.zeros();
   if (is_even(k))
     {
       auto tmp = faaDiBrunoZ<t>(Symmetry{i, j, k, 0});
-      tmp->contractAndAdd(2, *res, m<t>().get(Symmetry{k}));
+      tmp->contractAndAdd(2, res, m<t>().get(Symmetry{k}));
     }
   return res;
 }
@@ -751,44 +725,44 @@ KOrder::calcD_ijk(int i, int j, int k) const
    \left[\Sigma\right]^{\gamma_1\ldots\gamma_m}$$
    The sum can sum only for even $m$. */
 
-template <int t>
-_Ttensor *
+template <Storage t>
+typename ctraits<t>::Ttensor
 KOrder::calcE_ijk(int i, int j, int k) const
 {
-  _Ttensor *res = new _Ttensor(ny, TensorDimens(Symmetry{i, j, 0, 0}, nvs));
-  res->zeros();
+  typename ctraits<t>::Ttensor res(ny, TensorDimens(Symmetry{i, j, 0, 0}, nvs));
+  res.zeros();
   for (int n = 2; n <= k-1; n += 2)
     {
       auto tmp = faaDiBrunoZ<t>(Symmetry{i, j, n, k-n});
-      tmp->mult((double) (PascalTriangle::noverk(k, n)));
-      tmp->contractAndAdd(2, *res, m<t>().get(Symmetry{n}));
+      tmp->mult(static_cast<double>(PascalTriangle::noverk(k, n)));
+      tmp->contractAndAdd(2, res, m<t>().get(Symmetry{n}));
     }
   return res;
 }
 
-template <int t>
-_Ttensor *
+template <Storage t>
+typename ctraits<t>::Ttensor
 KOrder::calcD_ik(int i, int k) const
 {
   return calcD_ijk<t>(i, 0, k);
 }
 
-template <int t>
-_Ttensor *
+template <Storage t>
+typename ctraits<t>::Ttensor
 KOrder::calcD_k(int k) const
 {
   return calcD_ijk<t>(0, 0, k);
 }
 
-template <int t>
-_Ttensor *
+template <Storage t>
+typename ctraits<t>::Ttensor
 KOrder::calcE_ik(int i, int k) const
 {
   return calcE_ijk<t>(i, 0, k);
 }
 
-template <int t>
-_Ttensor *
+template <Storage t>
+typename ctraits<t>::Ttensor
 KOrder::calcE_k(int k) const
 {
   return calcE_ijk<t>(0, 0, k);
@@ -816,7 +790,7 @@ KOrder::calcE_k(int k) const
    through all the recovering methods, he should find out that also all
    $G$ are provided. */
 
-template <int t>
+template <Storage t>
 void
 KOrder::performStep(int order)
 {
@@ -828,23 +802,18 @@ KOrder::performStep(int order)
   recover_y<t>(order);
 
   for (int i = 0; i < order; i++)
-    {
-      recover_yu<t>(i, order-i);
-    }
+    recover_yu<t>(i, order-i);
 
   for (int j = 1; j < order; j++)
     {
       for (int i = j-1; i >= 1; i--)
-        {
-          recover_yus<t>(order-j, i, j-i);
-        }
+        recover_yus<t>(order-j, i, j-i);
       recover_ys<t>(order-j, j);
     }
 
   for (int i = order-1; i >= 1; i--)
-    {
-      recover_yus<t>(0, i, order-i);
-    }
+    recover_yus<t>(0, i, order-i);
+
   recover_s<t>(order);
 }
 
@@ -852,7 +821,7 @@ KOrder::performStep(int order)
    order. The method returns the largest residual size. Each check simply
    evaluates the equation. */
 
-template <int t>
+template <Storage t>
 double
 KOrder::check(int dim) const
 {
@@ -884,12 +853,10 @@ KOrder::check(int dim) const
         {
           Symmetry sym{i, j, 0, k};
           auto r = faaDiBrunoZ<t>(sym);
-          _Ttensor *D_ijk = calcD_ijk<t>(i, j, k);
-          r->add(1.0, *D_ijk);
-          delete D_ijk;
-          _Ttensor *E_ijk = calcE_ijk<t>(i, j, k);
-          r->add(1.0, *E_ijk);
-          delete E_ijk;
+          auto D_ijk = calcD_ijk<t>(i, j, k);
+          r->add(1.0, D_ijk);
+          auto E_ijk = calcE_ijk<t>(i, j, k);
+          r->add(1.0, E_ijk);
           double err = r->getData().getMax();
           JournalRecord(journal) << "\terror for symmetry " << sym << "\tis " << err << endrec;
         }
@@ -897,12 +864,10 @@ KOrder::check(int dim) const
 
   // check for $F_{\sigma^i}+D_i+E_i=0
   auto r = faaDiBrunoZ<t>(Symmetry{0, 0, 0, dim});
-  _Ttensor *D_k = calcD_k<t>(dim);
-  r->add(1.0, *D_k);
-  delete D_k;
-  _Ttensor *E_k = calcE_k<t>(dim);
-  r->add(1.0, *E_k);
-  delete E_k;
+  auto D_k = calcD_k<t>(dim);
+  r->add(1.0, D_k);
+  auto E_k = calcE_k<t>(dim);
+  r->add(1.0, E_k);
   double err = r->getData().getMax();
   Symmetry sym{0, 0, 0, dim};
   JournalRecord(journal) << "\terror for symmetry " << sym << "\tis " << err << endrec;
@@ -912,19 +877,18 @@ KOrder::check(int dim) const
   return maxerror;
 }
 
-template <int t>
-Vector *
+template <Storage t>
+Vector
 KOrder::calcStochShift(int order, double sigma) const
 {
-  auto *res = new Vector(ny);
-  res->zeros();
+  Vector res(ny);
+  res.zeros();
   int jfac = 1;
   for (int j = 1; j <= order; j++, jfac *= j)
     if (is_even(j))
       {
-        _Ttensor *ten = calcD_k<t>(j);
-        res->add(std::pow(sigma, j)/jfac, ten->getData());
-        delete ten;
+        auto ten = calcD_k<t>(j);
+        res.add(std::pow(sigma, j)/jfac, ten.getData());
       }
   return res;
 }
diff --git a/dynare++/kord/korder_stoch.cc b/dynare++/kord/korder_stoch.cc
index 924f797a7cb811793f08d045750fc30566a7a0f4..1bdc404b7756879d71885fcd991e4c1e4cb29bfe 100644
--- a/dynare++/kord/korder_stoch.cc
+++ b/dynare++/kord/korder_stoch.cc
@@ -11,7 +11,7 @@ MatrixAA::MatrixAA(const FSSparseTensor &f, const IntSequence &ss,
 {
   zeros();
 
-  IntSequence c(1); c[0] = 1;
+  IntSequence c{1};
   FGSTensor f_y(f, ss, c, TensorDimens(ss, c));
   add(1.0, f_y);
 
@@ -59,88 +59,112 @@ KOrderStoch::KOrderStoch(const PartitionY &yp, int nu,
 
 // |KOrderStoch| convenience method specializations
 template<>
-ctraits<KOrder::unfold>::Tg& KOrderStoch::g<KOrder::unfold>()
+ctraits<Storage::unfold>::Tg &KOrderStoch::g<Storage::unfold>()
 {
   return _ug;
 }
 template<>
-const ctraits<KOrder::unfold>::Tg& KOrderStoch::g<KOrder::unfold>() const
-{ return _ug;}
+const ctraits<Storage::unfold>::Tg &KOrderStoch::g<Storage::unfold>() const
+{
+  return _ug;
+}
 template<>
-ctraits<KOrder::fold>::Tg& KOrderStoch::g<KOrder::fold>()
+ctraits<Storage::fold>::Tg &KOrderStoch::g<Storage::fold>()
 {
   return _fg;
 }
 template<>
-const ctraits<KOrder::fold>::Tg& KOrderStoch::g<KOrder::fold>() const
-{ return _fg;}
+const ctraits<Storage::fold>::Tg &KOrderStoch::g<Storage::fold>() const
+{
+  return _fg;
+}
 template<>
-ctraits<KOrder::unfold>::Tgs& KOrderStoch::gs<KOrder::unfold>()
+ctraits<Storage::unfold>::Tgs &KOrderStoch::gs<Storage::unfold>()
 {
   return _ugs;
 }
 template<>
-const ctraits<KOrder::unfold>::Tgs& KOrderStoch::gs<KOrder::unfold>() const
-{ return _ugs;}
+const ctraits<Storage::unfold>::Tgs &KOrderStoch::gs<Storage::unfold>() const
+{
+  return _ugs;
+}
 template<>
-ctraits<KOrder::fold>::Tgs& KOrderStoch::gs<KOrder::fold>()
+ctraits<Storage::fold>::Tgs &KOrderStoch::gs<Storage::fold>()
 {
   return _fgs;
 }
 template<>
-const ctraits<KOrder::fold>::Tgs& KOrderStoch::gs<KOrder::fold>() const
-{ return _fgs;}
+const ctraits<Storage::fold>::Tgs &KOrderStoch::gs<Storage::fold>() const
+{
+  return _fgs;
+}
 template<>
-const ctraits<KOrder::unfold>::Tgss& KOrderStoch::h<KOrder::unfold>() const
-{ return *_uh;}
+const ctraits<Storage::unfold>::Tgss &KOrderStoch::h<Storage::unfold>() const
+{
+  return *_uh;
+}
 template<>
-const ctraits<KOrder::fold>::Tgss& KOrderStoch::h<KOrder::fold>() const
-{ return *_fh;}
+const ctraits<Storage::fold>::Tgss &KOrderStoch::h<Storage::fold>() const
+{
+  return *_fh;
+}
 template<>
-ctraits<KOrder::unfold>::TG& KOrderStoch::G<KOrder::unfold>()
+ctraits<Storage::unfold>::TG &KOrderStoch::G<Storage::unfold>()
 {
   return _uG;
 }
 template<>
-const ctraits<KOrder::unfold>::TG& KOrderStoch::G<KOrder::unfold>() const
-{ return _uG;}
+const ctraits<Storage::unfold>::TG &KOrderStoch::G<Storage::unfold>() const
+{
+  return _uG;
+}
 template<>
-ctraits<KOrder::fold>::TG& KOrderStoch::G<KOrder::fold>()
+ctraits<Storage::fold>::TG &KOrderStoch::G<Storage::fold>()
 {
   return _fG;
 }
 template<>
-const ctraits<KOrder::fold>::TG& KOrderStoch::G<KOrder::fold>() const
-{ return _fG;}
+const ctraits<Storage::fold>::TG& KOrderStoch::G<Storage::fold>() const
+{
+  return _fG;
+}
 template<>
-ctraits<KOrder::unfold>::TZXstack& KOrderStoch::Zstack<KOrder::unfold>()
+ctraits<Storage::unfold>::TZXstack &KOrderStoch::Zstack<Storage::unfold>()
 {
   return _uZstack;
 }
 template<>
-const ctraits<KOrder::unfold>::TZXstack& KOrderStoch::Zstack<KOrder::unfold>() const
-{ return _uZstack;}
+const ctraits<Storage::unfold>::TZXstack &KOrderStoch::Zstack<Storage::unfold>() const
+{
+  return _uZstack;
+}
 template<>
-ctraits<KOrder::fold>::TZXstack& KOrderStoch::Zstack<KOrder::fold>()
+ctraits<Storage::fold>::TZXstack &KOrderStoch::Zstack<Storage::fold>()
 {
   return _fZstack;
 }
 template<>
-const ctraits<KOrder::fold>::TZXstack& KOrderStoch::Zstack<KOrder::fold>() const
-{ return _fZstack;}
+const ctraits<Storage::fold>::TZXstack &KOrderStoch::Zstack<Storage::fold>() const
+{
+  return _fZstack;
+}
 template<>
-ctraits<KOrder::unfold>::TGXstack& KOrderStoch::Gstack<KOrder::unfold>()
+ctraits<Storage::unfold>::TGXstack &KOrderStoch::Gstack<Storage::unfold>()
 {
   return _uGstack;
 }
 template<>
-const ctraits<KOrder::unfold>::TGXstack& KOrderStoch::Gstack<KOrder::unfold>() const
-{ return _uGstack;}
+const ctraits<Storage::unfold>::TGXstack &KOrderStoch::Gstack<Storage::unfold>() const
+{
+  return _uGstack;
+}
 template<>
-ctraits<KOrder::fold>::TGXstack& KOrderStoch::Gstack<KOrder::fold>()
+ctraits<Storage::fold>::TGXstack &KOrderStoch::Gstack<Storage::fold>()
 {
   return _fGstack;
 }
 template<>
-const ctraits<KOrder::fold>::TGXstack& KOrderStoch::Gstack<KOrder::fold>() const
-{ return _fGstack;}
+const ctraits<Storage::fold>::TGXstack &KOrderStoch::Gstack<Storage::fold>() const
+{
+  return _fGstack;
+}
diff --git a/dynare++/kord/korder_stoch.hh b/dynare++/kord/korder_stoch.hh
index 38f0cc040937bba9fc60419b7cfaeb2388b34389..2adf37cd0a2f8b57486c116779ab39936c74c42c 100644
--- a/dynare++/kord/korder_stoch.hh
+++ b/dynare++/kord/korder_stoch.hh
@@ -32,12 +32,12 @@
 /* This class is a container, which has a specialized constructor
    integrating the policy rule at given $\sigma$. */
 
-template <int t>
+template <Storage t>
 class IntegDerivs : public ctraits<t>::Tgss
 {
 public:
-  IntegDerivs(int r, const IntSequence &nvs, const _Tgss &g, const __Tm &mom,
-              double at_sigma);
+  IntegDerivs(int r, const IntSequence &nvs, const typename ctraits<t>::Tgss &g,
+              const typename ctraits<t>::Tm &mom, double at_sigma);
 };
 
 /* This constructor integrates a rule (namely its $g^{**}$ part) with
@@ -79,9 +79,9 @@ public:
    \Sigma^{m+n}{\tilde\sigma}^m$$
    and this is exactly what the code does. */
 
-template <int t>
-IntegDerivs<t>::IntegDerivs(int r, const IntSequence &nvs, const _Tgss &g, const __Tm &mom,
-                            double at_sigma)
+template <Storage t>
+IntegDerivs<t>::IntegDerivs(int r, const IntSequence &nvs, const typename ctraits<t>::Tgss &g,
+                            const typename ctraits<t>::Tm &mom, double at_sigma)
   : ctraits<t>::Tgss(4)
 {
   int maxd = g.getMaxDim();
@@ -91,7 +91,7 @@ IntegDerivs<t>::IntegDerivs(int r, const IntSequence &nvs, const _Tgss &g, const
         {
           int p = d-i;
           Symmetry sym{i, 0, 0, p};
-          auto ten = std::make_unique<_Ttensor>(r, TensorDimens(sym, nvs));
+          auto ten = std::make_unique<typename ctraits<t>::Ttensor>(r, TensorDimens(sym, nvs));
 
           // calculate derivative $h_{y^i\sigma^p}$
           /* This code calculates
@@ -113,7 +113,7 @@ IntegDerivs<t>::IntegDerivs(int r, const IntSequence &nvs, const _Tgss &g, const
                     ten->add(mult, g.get(sym_mn));
                   if (m+n > 0 && KOrder::is_even(m+n) && g.check(sym_mn))
                     {
-                      _Ttensor gtmp(g.get(sym_mn));
+                      typename ctraits<t>::Ttensor gtmp(g.get(sym_mn));
                       gtmp.mult(mult);
                       gtmp.contractAndAdd(1, *ten, mom.get(Symmetry{m+n}));
                     }
@@ -133,12 +133,12 @@ IntegDerivs<t>::IntegDerivs(int r, const IntSequence &nvs, const _Tgss &g, const
    y^*,\bar\sigma)$. The derivatives are extrapolated based on
    derivatives at $(\tilde y^*,\tilde\sigma)$. */
 
-template <int t>
+template <Storage t>
 class StochForwardDerivs : public ctraits<t>::Tgss
 {
 public:
   StochForwardDerivs(const PartitionY &ypart, int nu,
-                     const _Tgss &g, const __Tm &m,
+                     const typename ctraits<t>::Tgss &g, const typename ctraits<t>::Tm &m,
                      const Vector &ydelta, double sdelta,
                      double at_sigma);
 };
@@ -160,9 +160,10 @@ public:
    \li Recover general symmetry tensors from the (full symmetric) polynomial
    \endorderedlist */
 
-template <int t>
+template <Storage t>
 StochForwardDerivs<t>::StochForwardDerivs(const PartitionY &ypart, int nu,
-                                          const _Tgss &g, const __Tm &m,
+                                          const typename ctraits<t>::Tgss &g,
+                                          const typename ctraits<t>::Tm &m,
                                           const Vector &ydelta, double sdelta,
                                           double at_sigma)
   : ctraits<t>::Tgss(4)
@@ -181,10 +182,10 @@ StochForwardDerivs<t>::StochForwardDerivs(const PartitionY &ypart, int nu,
   // make |g_int_sym| be full symmetric polynomial from |g_int|
   /* Here we just form a polynomial whose unique variable corresponds to
      $\left[\matrix{y^*\cr\sigma}\right]$ stack. */
-  _Tpol g_int_sym(r, ypart.nys()+1);
+  typename ctraits<t>::Tpol g_int_sym(r, ypart.nys()+1);
   for (int d = 1; d <= maxd; d++)
     {
-      auto ten = std::make_unique<_Ttensym>(r, ypart.nys()+1, d);
+      auto ten = std::make_unique<typename ctraits<t>::Ttensym>(r, ypart.nys()+1, d);
       ten->zeros();
       for (int i = 0; i <= d; i++)
         {
@@ -207,7 +208,7 @@ StochForwardDerivs<t>::StochForwardDerivs(const PartitionY &ypart, int nu,
   ConstVector dy_in(ydelta, ypart.nstat, ypart.nys());
   dy = dy_in;
   delta[ypart.nys()] = sdelta;
-  _Tpol g_int_cent(r, ypart.nys()+1);
+  typename ctraits<t>::Tpol g_int_cent(r, ypart.nys()+1);
   for (int d = 1; d <= maxd; d++)
     {
       g_int_sym.derivative(d-1);
@@ -224,19 +225,16 @@ StochForwardDerivs<t>::StochForwardDerivs(const PartitionY &ypart, int nu,
   true_nvs[1] = nu;
   true_nvs[2] = nu;
   for (int d = 1; d <= maxd; d++)
-    {
-      if (g_int_cent.check(Symmetry{d}))
+    if (g_int_cent.check(Symmetry{d}))
+      for (int i = 0; i <= d; i++)
         {
-          for (int i = 0; i <= d; i++)
-            {
-              Symmetry sym{i, 0, 0, d-i};
-              IntSequence coor(pp.unfold(sym));
-              auto ten = std::make_unique<_Ttensor>(g_int_cent.get(Symmetry{d}), ss, coor,
-                                                    TensorDimens(sym, true_nvs));
-              this->insert(std::move(ten));
-            }
+          Symmetry sym{i, 0, 0, d-i};
+          IntSequence coor(pp.unfold(sym));
+          auto ten = std::make_unique<typename ctraits<t>::Ttensor>(g_int_cent.get(Symmetry{d}),
+                                                                    ss, coor,
+                                                                    TensorDimens(sym, true_nvs));
+          this->insert(std::move(ten));
         }
-    }
 }
 
 /* This container corresponds to $h(g^*(y,u,\sigma),\sigma)$. Note that
@@ -425,7 +423,7 @@ public:
               const FGSContainer &hh, Journal &jr);
   KOrderStoch(const PartitionY &ypart, int nu, const TensorContainer<FSSparseTensor> &fcont,
               const UGSContainer &hh, Journal &jr);
-  template <int t>
+  template <Storage t>
   void performStep(int order);
   const FGSContainer &
   getFoldDers() const
@@ -438,46 +436,51 @@ public:
     return _ug;
   }
 protected:
-  template <int t>
-  std::unique_ptr<_Ttensor> faaDiBrunoZ(const Symmetry &sym) const;
-  template <int t>
-  std::unique_ptr<_Ttensor> faaDiBrunoG(const Symmetry &sym) const;
+  template <Storage t>
+  std::unique_ptr<typename ctraits<t>::Ttensor> faaDiBrunoZ(const Symmetry &sym) const;
+  template <Storage t>
+  std::unique_ptr<typename ctraits<t>::Ttensor> faaDiBrunoG(const Symmetry &sym) const;
 
   // convenience access methods
-  template<int t>
-  _Tg&g();
-  template<int t>
-  const _Tg&g() const;
-  template<int t>
-  _Tgs&gs();
-  template<int t>
-  const _Tgs&gs() const;
-  template<int t>
-  const _Tgss&h() const;
-  template<int t>
-  _TG&G();
-  template<int t>
-  const _TG&G() const;
-  template<int t>
-  _TZXstack&Zstack();
-  template<int t>
-  const _TZXstack&Zstack() const;
-  template<int t>
-  _TGXstack&Gstack();
-  template<int t>
-  const _TGXstack&Gstack() const;
+  template<Storage t>
+  typename ctraits<t>::Tg &g();
+  template<Storage t>
+  const typename ctraits<t>::Tg &g() const;
+
+  template<Storage t>
+  typename ctraits<t>::Tgs &gs();
+  template<Storage t>
+  const typename ctraits<t>::Tgs &gs() const;
+
+  template<Storage t>
+  const typename ctraits<t>::Tgss &h() const;
+
+  template<Storage t>
+  typename ctraits<t>::TG &G();
+  template<Storage t>
+  const typename ctraits<t>::TG &G() const;
+
+  template<Storage t>
+  typename ctraits<t>::TZXstack &Zstack();
+  template<Storage t>
+  const typename ctraits<t>::TZXstack &Zstack() const;
+
+  template<Storage t>
+  typename ctraits<t>::TGXstack &Gstack();
+  template<Storage t>
+  const typename ctraits<t>::TGXstack &Gstack() const;
 };
 
 /* This calculates a derivative of $f(G(y,u,\sigma),g(y,u,\sigma),y,u)$
    of a given symmetry. */
 
-template <int t>
-std::unique_ptr<_Ttensor>
+template <Storage t>
+std::unique_ptr<typename ctraits<t>::Ttensor>
 KOrderStoch::faaDiBrunoZ(const Symmetry &sym) const
 {
   JournalRecordPair pa(journal);
   pa << "Faa Di Bruno ZX container for " << sym << endrec;
-  auto res = std::make_unique<_Ttensor>(ypart.ny(), TensorDimens(sym, nvs));
+  auto res = std::make_unique<typename ctraits<t>::Ttensor>(ypart.ny(), TensorDimens(sym, nvs));
   FaaDiBruno bruno(journal);
   bruno.calculate(Zstack<t>(), f, *res);
   return res;
@@ -486,14 +489,14 @@ KOrderStoch::faaDiBrunoZ(const Symmetry &sym) const
 /* This calculates a derivative of
    $G(y,u,\sigma)=h(g^*(y,u,\sigma),\sigma)$ of a given symmetry. */
 
-template <int t>
-std::unique_ptr<_Ttensor>
+template <Storage t>
+std::unique_ptr<typename ctraits<t>::Ttensor>
 KOrderStoch::faaDiBrunoG(const Symmetry &sym) const
 {
   JournalRecordPair pa(journal);
   pa << "Faa Di Bruno GX container for " << sym << endrec;
   TensorDimens tdims(sym, nvs);
-  auto res = std::make_unique<_Ttensor>(ypart.nyss(), tdims);
+  auto res = std::make_unique<typename ctraits<t>::Ttensor>(ypart.nyss(), tdims);
   FaaDiBruno bruno(journal);
   bruno.calculate(Gstack<t>(), h<t>(), *res);
   return res;
@@ -510,7 +513,7 @@ KOrderStoch::faaDiBrunoG(const Symmetry &sym) const
    $$g_s=-matA^{-1}\cdot RHS.$$ Finally we have to update $G_s$ by
    calling |Gstack<t>().multAndAdd(1, h<t>(), *G_sym)|. */
 
-template <int t>
+template <Storage t>
 void
 KOrderStoch::performStep(int order)
 {
@@ -518,24 +521,23 @@ KOrderStoch::performStep(int order)
   KORD_RAISE_IF(order-1 != maxd && (order != 1 || maxd != -1),
                 "Wrong order for KOrderStoch::performStep");
   for (auto &si : SymmetrySet(order, 4))
-    {
-      if (si[2] == 0)
-        {
-          JournalRecordPair pa(journal);
-          pa << "Recovering symmetry " << si << endrec;
-
-          auto G_sym = faaDiBrunoG<t>(si);
-          auto G_sym_ptr = G_sym.get();
-          G<t>().insert(std::move(G_sym));
-
-          auto g_sym = faaDiBrunoZ<t>(si);
-          auto g_sym_ptr = g_sym.get();
-          g_sym->mult(-1.0);
-          matA.multInv(*g_sym);
-          g<t>().insert(std::move(g_sym));
-          gs<t>().insert(std::make_unique<_Ttensor>(ypart.nstat, ypart.nys(), *g_sym_ptr));
-
-          Gstack<t>().multAndAdd(1, h<t>(), *G_sym_ptr);
-        }
-    }
+    if (si[2] == 0)
+      {
+        JournalRecordPair pa(journal);
+        pa << "Recovering symmetry " << si << endrec;
+
+        auto G_sym = faaDiBrunoG<t>(si);
+        auto G_sym_ptr = G_sym.get();
+        G<t>().insert(std::move(G_sym));
+
+        auto g_sym = faaDiBrunoZ<t>(si);
+        auto g_sym_ptr = g_sym.get();
+        g_sym->mult(-1.0);
+        matA.multInv(*g_sym);
+        g<t>().insert(std::move(g_sym));
+        gs<t>().insert(std::make_unique<typename ctraits<t>::Ttensor>(ypart.nstat, ypart.nys(),
+                                                                      *g_sym_ptr));
+
+        Gstack<t>().multAndAdd(1, h<t>(), *G_sym_ptr);
+      }
 }
diff --git a/dynare++/kord/tests.cc b/dynare++/kord/tests.cc
index 8a626733aa051e9db71b0661200fb204ad84943f..26db77f44d352b1ad68c4dbb50a46ad2954f8913 100644
--- a/dynare++/kord/tests.cc
+++ b/dynare++/kord/tests.cc
@@ -298,12 +298,12 @@ TestRunnable::korder_unfold_fold(int maxdim, int unfold_dim,
   for (int d = 2; d <= unfold_dim; d++)
     {
       clock_t pertime = clock();
-      kord.performStep<KOrder::unfold>(d);
+      kord.performStep<Storage::unfold>(d);
       pertime = clock()-pertime;
       std::cout << "\ttime for unfolded step dim=" << d << ": " << std::setprecision(4)
                 << static_cast<double>(pertime)/CLOCKS_PER_SEC << std::endl;
       clock_t checktime = clock();
-      double err = kord.check<KOrder::unfold>(d);
+      double err = kord.check<Storage::unfold>(d);
       checktime = clock()-checktime;
       std::cout << "\ttime for step check dim=" << d << ":    " << std::setprecision(4)
                 << static_cast<double>(checktime)/CLOCKS_PER_SEC << '\n'
@@ -324,12 +324,12 @@ TestRunnable::korder_unfold_fold(int maxdim, int unfold_dim,
       for (int d = unfold_dim+1; d <= maxdim; d++)
         {
           clock_t pertime = clock();
-          kord.performStep<KOrder::fold>(d);
+          kord.performStep<Storage::fold>(d);
           pertime = clock()-pertime;
           std::cout << "\ttime for folded step dim=" << d << ":   " << std::setprecision(4)
                     << static_cast<double>(pertime)/CLOCKS_PER_SEC << std::endl;
           clock_t checktime = clock();
-          double err = kord.check<KOrder::fold>(d);
+          double err = kord.check<Storage::fold>(d);
           checktime = clock()-checktime;
           std::cout << "\ttime for step check dim=" << d << ":    " << std::setprecision(4)
                     << static_cast<double>(checktime)/CLOCKS_PER_SEC << '\n'
diff --git a/dynare++/src/dynare3.cc b/dynare++/src/dynare3.cc
index 973e36f0e7a0a1194675364c6032d246ccc19ecd..36f3f65a5b3661e44ef19d07bf88ce5c01fb413f 100644
--- a/dynare++/src/dynare3.cc
+++ b/dynare++/src/dynare3.cc
@@ -20,13 +20,13 @@
 /*       DynareNameList class                                                         */
 /**************************************************************************************/
 std::vector<int>
-DynareNameList::selectIndices(const std::vector<const char *> &ns) const
+DynareNameList::selectIndices(const std::vector<std::string> &ns) const
 {
   std::vector<int> res;
-  for (auto n : ns)
+  for (const auto &n : ns)
     {
       int j = 0;
-      while (j < getNum() && strcmp(getName(j), n) != 0)
+      while (j < getNum() && n != getName(j))
         j++;
       if (j == getNum())
         throw DynareException(__FILE__, __LINE__,
diff --git a/dynare++/src/dynare3.hh b/dynare++/src/dynare3.hh
index 6a7fa48463f751b870d6add4b049297154807d2a..f270010af682eb1c7be0c81144246b7b35de740b 100644
--- a/dynare++/src/dynare3.hh
+++ b/dynare++/src/dynare3.hh
@@ -20,15 +20,15 @@ class Dynare;
 
 class DynareNameList : public NameList
 {
-  std::vector<const char *> names;
+  std::vector<std::string> names;
 public:
   DynareNameList(const Dynare &dynare);
   int
   getNum() const override
   {
-    return (int) names.size();
+    return static_cast<int>(names.size());
   }
-  const char *
+  const std::string &
   getName(int i) const override
   {
     return names[i];
@@ -36,20 +36,20 @@ public:
   /** This for each string of the input vector calculates its index
    * in the names. And returns the resulting vector of indices. If
    * the name cannot be found, then an exception is raised. */
-  std::vector<int> selectIndices(const std::vector<const char *> &ns) const;
+  std::vector<int> selectIndices(const std::vector<std::string> &ns) const;
 };
 
 class DynareExogNameList : public NameList
 {
-  std::vector<const char *> names;
+  std::vector<std::string> names;
 public:
   DynareExogNameList(const Dynare &dynare);
   int
   getNum() const override
   {
-    return (int) names.size();
+    return static_cast<int>(names.size());
   }
-  const char *
+  const std::string &
   getName(int i) const override
   {
     return names[i];
@@ -58,16 +58,16 @@ public:
 
 class DynareStateNameList : public NameList
 {
-  std::vector<const char *> names;
+  std::vector<std::string> names;
 public:
   DynareStateNameList(const Dynare &dynare, const DynareNameList &dnl,
                       const DynareExogNameList &denl);
   int
   getNum() const override
   {
-    return (int) names.size();
+    return static_cast<int>(names.size());
   }
-  const char *
+  const std::string &
   getName(int i) const override
   {
     return names[i];
@@ -105,10 +105,10 @@ public:
          double sstol, Journal &jr);
   /** Makes a deep copy of the object. */
   Dynare(const Dynare &dyn);
-  DynamicModel *
+  std::unique_ptr<DynamicModel>
   clone() const override
   {
-    return new Dynare(*this);
+    return std::make_unique<Dynare>(*this);
   }
   
   ~Dynare() override;
diff --git a/dynare++/src/dynare_params.hh b/dynare++/src/dynare_params.hh
index 3e5ebe6789bf3946992f4acd9ecf1fbcf1596e46..e8aef5c438700ecb939b9aab857cf011aef7171c 100644
--- a/dynare++/src/dynare_params.hh
+++ b/dynare++/src/dynare_params.hh
@@ -40,7 +40,7 @@ struct DynareParams
   /** Flag for doing IRFs even if the irf_list is empty. */
   bool do_irfs_all;
   /** List of shocks for which IRF will be calculated. */
-  std::vector<const char *> irf_list;
+  std::vector<std::string> irf_list;
   bool do_centralize;
   double qz_criterium;
   bool help;
diff --git a/mex/sources/k_order_perturbation/k_ord_dynare.cc b/mex/sources/k_order_perturbation/k_ord_dynare.cc
index 700f61fc6b1ba4fc62e49a9863146b0cc95e69e1..00e0c2d78f813cff2d370a0b55c55d6a583a42ed 100644
--- a/mex/sources/k_order_perturbation/k_ord_dynare.cc
+++ b/mex/sources/k_order_perturbation/k_ord_dynare.cc
@@ -340,7 +340,7 @@ KordpDynare::ReorderDynareJacobianIndices() noexcept(false)
 /*       DynareNameList class                                                         */
 /**************************************************************************************/
 
-DynareNameList::DynareNameList(const KordpDynare &dynare, const std::vector<std::string> &names_arg) : names(names_arg)
+DynareNameList::DynareNameList(const KordpDynare &dynare, std::vector<std::string> names_arg) : names(std::move(names_arg))
 {
 }
 
@@ -348,7 +348,7 @@ DynareStateNameList::DynareStateNameList(const KordpDynare &dynare, const Dynare
                                          const DynareNameList &denl)
 {
   for (int i = 0; i < dynare.nys(); i++)
-    names.push_back(std::string{dnl.getName(i+dynare.nstat())});
+    names.emplace_back(dnl.getName(i+dynare.nstat()));
   for (int i = 0; i < dynare.nexog(); i++)
-    names.push_back(std::string{denl.getName(i)});
+    names.emplace_back(denl.getName(i));
 }
diff --git a/mex/sources/k_order_perturbation/k_ord_dynare.hh b/mex/sources/k_order_perturbation/k_ord_dynare.hh
index 49cc1d96ec58ca3e15b214782281e3a6ee372ef2..f8325083c73ad3c5a3e606a5a305fe45487882fd 100644
--- a/mex/sources/k_order_perturbation/k_ord_dynare.hh
+++ b/mex/sources/k_order_perturbation/k_ord_dynare.hh
@@ -44,16 +44,16 @@ class DynareNameList : public NameList
 {
   std::vector<std::string> names;
 public:
-  DynareNameList(const KordpDynare &dynare, const std::vector<std::string> &names_arg);
+  DynareNameList(const KordpDynare &dynare, std::vector<std::string> names_arg);
   int
   getNum() const
   {
-    return (int) names.size();
+    return static_cast<int>(names.size());
   }
-  const char *
+  const std::string &
   getName(int i) const
   {
-    return names[i].c_str();
+    return names[i];
   }
 };
 
@@ -66,12 +66,12 @@ public:
   int
   getNum() const
   {
-    return (int) names.size();
+    return static_cast<int>(names.size());
   }
-  const char *
+  const std::string &
   getName(int i) const
   {
-    return names[i].c_str();
+    return names[i];
   }
 };
 /*********************************************/
@@ -235,7 +235,7 @@ public:
                       const ConstVector &yyp, const Vector &xx) noexcept(false);
   void calcDerivativesAtSteady();
   std::unique_ptr<DynamicModelAC> dynamicModelFile;
-  DynamicModel *
+  std::unique_ptr<DynamicModel>
   clone() const
   {
     std::cerr << "KordpDynare::clone() not implemented" << std::endl;