diff --git a/dynare++/extern/R/Makefile b/dynare++/extern/R/Makefile
index 4501ebdb56cf0cab337bb10f2b27fb482f8e16eb..92097b79b3d67e28b2848dafb940859834bd322a 100644
--- a/dynare++/extern/R/Makefile
+++ b/dynare++/extern/R/Makefile
@@ -1,37 +1,28 @@
 RINTERNALS=/usr/share/R/include/
 
-sylvcppsource := $(wildcard ../../sylv/cc/*.cpp)
-sylvhsource := $(wildcard ../../sylv/cc/*.h)
-sylvobjects := $(patsubst %.cpp, %.o, $(sylvcppsource))
-
-tlcwebsource := $(wildcard ../../tl/cc/*.cweb)
-tlcppsource := $(patsubst %.cweb,%.cpp,$(tlcwebsource))
-tlhwebsource := $(wildcard ../../tl/cc/*.hweb)
-tlhsource := $(patsubst %.hweb,%.h,$(tlhwebsource))
-tlobjects := $(patsubst %.cweb,%.o,$(tlcwebsource))
-
-kordcwebsource := $(wildcard ../../kord/*.cweb)
-kordcppsource := $(patsubst %.cweb,%.cpp,$(kordcwebsource))
-kordhwebsource := $(wildcard ../../kord/*.hweb)
-kordhsource := $(patsubst %.hweb,%.h,$(kordhwebsource))
-kordobjects := $(patsubst %.cweb,%.o,$(kordcwebsource))
-
-integcwebsource := $(wildcard ../../integ/cc/*.cweb)
-integcppsource := $(patsubst %.cweb,%.cpp,$(integcwebsource))
-integhwebsource := $(wildcard ../../integ/cc/*.hweb)
-integhsource := $(patsubst %.hweb,%.h,$(integhwebsource))
-integobjects := $(patsubst %.cweb,%.o,$(integcwebsource))
-
-parserhsource := $(wildcard ../../parser/cc/*.h)
-parsercppsource := $(wildcard ../parser/cc/*.cpp)
-
-utilshsource := $(wildcard ../../utils/cc/*.h)
-utilscppsource := $(wildcard ../utils/cc/*.cpp)
-
-srccpp := dynare3.cpp dynare_model.cpp planner_builder.cpp dynare_atoms.cpp dynare_params.cpp  nlsolve.cpp
-objects := $(patsubst %.cpp,../../src/%.o,$(srccpp)) \
-$(patsubst %.y,%_ll.o,$(wildcard ../../src/*.y)) \
-$(patsubst %.lex,%_tab.o,$(wildcard ../../src/*.lex))
+sylvcppsource := $(wildcard ../../sylv/cc/*.cc)
+sylvhsource := $(wildcard ../../sylv/cc/*.hh)
+sylvobjects := $(patsubst %.cc, %.o, $(sylvcppsource))
+
+tlcppsource := $(wildcard ../../tl/cc/*.cc)
+tlhsource := $(wildcard ../../tl/cc/*.hh)
+
+kordcppsource := $(wildcard ../../kord/*.cc)
+kordhsource := $(wildcard ../../kord/*.hh)
+
+integcppsource := $(wildcard ../../integ/cc/*.cc)
+integhsource := $(wildcard ../../integ/cc/*.hh)
+
+parserhsource := $(wildcard ../../parser/cc/*.hh)
+parsercppsource := $(wildcard ../parser/cc/*.cc)
+
+utilshsource := $(wildcard ../../utils/cc/*.hh)
+utilscppsource := $(wildcard ../utils/cc/*.cc)
+
+srccpp := dynare3.cc dynare_model.cc planner_builder.cc dynare_atoms.cc dynare_params.cc  nlsolve.cc
+objects := $(patsubst %.cc,../../src/%.o,$(srccpp)) \
+$(patsubst %.yy,%_ll.o,$(wildcard ../../src/*.yy)) \
+$(patsubst %.ll,%_tab.o,$(wildcard ../../src/*.ll))
 
 PKG_CPPFLAGS= -I../../tl/cc -I../../sylv/cc -I../../kord -I../../src -I../.. -I$(RINTERNALS)
 PKG_LIBS= ${LAPACK_LIBS} ${BLAS_LIBS} $(objects) $(kordobjects) $(integobjects) $(tlobjects) ../../parser/cc/parser.a ../../utils/cc/utils.a $(sylvobjects) -lpthread -llapack -lcblas -lf77blas -latlas -lg2c -lstdc++
@@ -43,12 +34,12 @@ endif
 dynareR.so: dynareR.o
 	g++ -shared  -o dynareR.so dynareR.o -L/usr/lib/R/lib -lR $(PKG_LIBS)
 
-dynareR.o: dynareR.cpp
+dynareR.o: dynareR.cc
 	g++ -I/usr/share/R/include -I/usr/share/R/include $(PKG_CPPFLAGS) \
-	-fpic  -g -O2 -c dynareR.cpp -o dynareR.o -DDEBUG
+	-fpic  -g -O2 -c dynareR.cc -o dynareR.o -DDEBUG
 
-test: test.cpp dynareR.cpp
-	g++ -O0 -g -o test test.cpp -DDEBUG $(PKG_LIBS) $(PKG_CPPFLAGS)
+test: test.cc dynareR.cc
+	g++ -O0 -g -o test test.cc -DDEBUG $(PKG_LIBS) $(PKG_CPPFLAGS)
 
 test-debug:
 	valgrind --leak-check=yes ./test
diff --git a/dynare++/extern/R/dynareR.cc b/dynare++/extern/R/dynareR.cc
new file mode 100644
index 0000000000000000000000000000000000000000..4aef455cfa9956cdd61670c86f8cc298e8a591e1
--- /dev/null
+++ b/dynare++/extern/R/dynareR.cc
@@ -0,0 +1,271 @@
+// $Id: dynareR.cpp 862 2006-08-04 17:34:56Z tamas $
+
+// Copyright 2006, Tamas K Papp
+
+#include "dynare3.hh"                   // Dynare class
+#include "approximation.hh"             // Approximation class
+
+// exceptions
+#include "dynare_exception.hh"
+#include "parser/cc/parser_exception.hh"
+#include "utils/cc/exception.hh"
+#include "SylvException.hh"
+#include "tl_exception.hh"
+#include "kord_exception.hh"
+
+#include <algorithm>
+
+#include <string.h>
+
+#ifdef DEBUG
+# include <stdio.h>
+#endif
+
+#include <R_ext/Memory.h>
+
+/** This file containt the C glue functions for an R interface to
+ * Dynare++.  Although written in standard C (except for the use of
+ * R_alloc), the indexing, calling and memory management conventions
+ * of the functions in this file were tailored for R.
+ *
+ * It is not recommended that you use this interface for anything else
+ * but R.
+ */
+
+/** Error codes: these error codes correspond to possible
+ * exceptions. */
+#define DYNARER_SYLVEXCEPTION 1
+#define DYNARER_DYNAREEXCEPTION 2
+#define DYNARER_OGUEXCEPTION 3
+#define DYNARER_TLEXCEPTION 4
+#define DYNARER_KORDEXCEPTION 5
+#define DYNARER_NAMESMATCHINGERROR 6
+
+/** Copies the message into a buffer.  The buffer is allocated and
+ * managed by R, ie it will be garbage collected after the .C call
+ * returns and the contents are duplicated.
+ */
+char *
+passmessage(const char *errormessage)
+{
+  long l = strlen(errormessage);
+  char *em = R_alloc(l, 1);
+  return strcpy(em, errormessage);
+}
+
+/** This function puts the mapping between the newtotal items after
+ * nl[offset] and the items in orig into the buffer perm, which has to
+ * be at least as long as newtotal.  The function uses R indexing,
+ * that is to say, the first index is 1.
+ */
+int
+matchnames(const char **orig, int origtotal,
+           const NameList &nl, int offset, int newtotal,
+           int *perm)
+{
+#ifdef DEBUG
+  printf("matching names (R indexing):\n");
+#endif
+  for (int i = 0; i < newtotal; i++)
+    {
+      int j;
+      for (j = 0; j < origtotal; j++)
+        if (strcmp(nl.getName(offset+i), *(orig+j)) == 0)
+          {
+            *(perm+i) = j+1;
+#ifdef DEBUG
+            printf("%d -> %d\n", i+1, j+1);
+#endif
+            break;
+          }
+      if (j == origtotal)
+        return 1;
+    }
+  return 0;
+}
+
+/** dynareR is the interface function.  The user provides:
+ * - a list of endogenous and exogenous variables, a list of
+ *   parameters (and the length of each list)
+ * - the model equations (modeleq, pointer to a 0-terminated string)
+ * - the order of expansion (ord)
+ * - journal file name (jnlfile, can be "/dev/null" for no journal)
+ * - values for the parametes (parval)
+ * - variance-covariance matrix (vcov, stacked by columns, R does
+ *   this)
+ * - initial values for finding the steady state (initval)
+ * - and the number of steps for the approximation algorithm
+ *   (numsteps)
+ *
+ * If successful, the interface will write the results to these
+ * buffers:
+ * - tensorbuffer for the steady state and the flattened tensors
+ * - num_state for the number of endogenous variables that ended up in
+ *   the state
+ * - mappings to variable names (ordering_state, ordering_endo,
+ *   ordering_exo), indices start from 1
+ * - the deterministic steady state (newinitval)
+ *
+ * If dynare throws an exception, the interface tries to catch it and
+ * return an error code (error), and error message (errormessage), and
+ * if applicable, information on the stability of the model
+ * (kordcode).  errormessage is allocated into R's memory, and will be
+ * collected after duplication.
+ */
+extern "C" {
+  void
+  dynareR(const char **endo, const int *num_endo,
+          const char **exo, const int *num_exo,
+          const char **par, const int *num_par,
+          const char **equations, const int *ord, const char *jnlfile,
+          const double *parval, const double *vcov,
+          const double *initval,
+          const int *num_steps,
+          double *tensorbuffer,
+          int *num_state, int *ordering_state,
+          int *ordering_endo, int *ordering_exo,
+          double *newinitval,
+          int *error, char **errormessage, int *kordcode)
+  {
+    // construct the model here
+    try
+      {
+#ifdef DEBUG                                    // will print only first var names etc.
+        printf("eq: %s\nendo: %d %s\nexo: %d %s\npar: %d %s\nord: %d\n",
+               *equations, *num_endo, *endo, *num_exo, *exo, *num_par, *par, *ord);
+#endif
+        // create journal
+        Journal journal(jnlfile);
+        // create Dynare object
+        Dynare dynare(endo, *num_endo, exo, *num_exo,
+                      par, *num_par, *equations, strlen(*equations),
+                      *ord, journal);
+        // set Vcov and parameter values
+        copy(parval, parval+(*num_par), dynare.getParams().base());
+#ifdef DEBUG
+        printf("parameter values (%d):\n", dynare.getParams().length());
+        dynare.getParams().print();
+#endif
+        copy(vcov, vcov+(*num_exo)*(*num_exo), dynare.getVcov().base());
+#ifdef DEBUG
+        printf("vcov matrix:\n");
+        dynare.getVcov().print();
+#endif
+        // set initial values
+        Vector iv(initval, *num_endo);
+#ifdef DEBUG
+        printf("initial values:\n");
+        iv.print();
+#endif
+        dynare.setInitOuter(iv);
+        // construct approximation
+        tls.init(dynare.order(),
+                 dynare.nstat()+2*dynare.npred()+3*dynare.nboth()
+                 +2*dynare.nforw()+dynare.nexog());
+        Approximation approximation(dynare, journal, *num_steps);
+        approximation.walkStochSteady();
+        // write the steady state into the buffer
+        int ny = dynare.ny();
+        const Vector ss(dynare.getSteady());
+        //			ss = ConstVector(approximation.getSS(), 0); // FIXME allow
+        //														// for nonzero
+        int s = dynare.getStateNames().getNum();
+        int sm = s;
+        tensorbuffer = copy(ss.base(), ss.base()+ny, tensorbuffer);
+        // write the tensors into buffer
+        const UnfoldDecisionRule &udr
+          = approximation.getUnfoldDecisionRule();
+        for (int i = 1; i <= *ord; i++)
+          {
+            const UFSTensor *t = udr.get(Symmetry(i));
+#ifdef DEBUG
+            printf("tensor %d:\n", i);
+            t->print();
+#endif
+            tensorbuffer = copy(t->base(), t->base()+ny*sm, tensorbuffer);
+            sm *= s;
+          }
+        // save number of endogenous states
+        *num_state = s-(*num_exo);
+        // ordering
+#ifdef DEBUG
+        printf("all endo names:\n");
+        dynare.getAllEndoNames().print();
+        printf("all state names:\n");
+        dynare.getStateNames().print();
+#endif
+        if (matchnames(endo, *num_endo, dynare.getAllEndoNames(),
+                       0, *num_endo, ordering_endo)
+            || matchnames(endo, *num_endo, dynare.getStateNames(),
+                          0, *num_state, ordering_state)
+            || matchnames(exo, *num_exo, dynare.getStateNames(),
+                          *num_state, *num_exo, ordering_exo))
+          {
+            *error = DYNARER_NAMESMATCHINGERROR;
+            *errormessage = "There was a problem when matching names.  This is weird and should not happen.";
+            return;
+          }
+        // return new init values (first column of SS matrix)
+        ConstVector newinit((const GeneralMatrix &)approximation.getSS(), 0);
+#ifdef DEBUG
+        printf("new initial values:\n");
+        newinit.print();
+#endif
+        copy(newinit.base(), newinit.base()+(*num_endo), newinitval);
+      }
+    catch (const SylvException &e)
+      {
+        *error = DYNARER_SYLVEXCEPTION;
+        char errorbuffer[501];
+        e.printMessage(errorbuffer, 500);
+        *errormessage = passmessage(errorbuffer);
+#ifdef DEBUG
+        printf("Caught Sylv exception: ");
+        e.printMessage();
+#endif
+        return;
+      }
+    catch (const DynareException &e)
+      {
+        *error = DYNARER_DYNAREEXCEPTION;
+        *errormessage = passmessage(e.message());
+#ifdef DEBUG
+        printf("Caught Dynare exception: %s\n", e.message());
+#endif
+        return;
+      }
+    catch (const ogu::Exception &e)
+      {
+        *error = DYNARER_OGUEXCEPTION;
+        *errormessage = passmessage(e.message());
+#ifdef DEBUG
+        printf("Caught ogu::Exception: ");
+        e.print();
+#endif
+        return;
+      }
+    catch (const TLException &e)
+      {
+        *error = DYNARER_TLEXCEPTION;
+        *errormessage = passmessage(e.getmessage());
+#ifdef DEBUG
+        printf("Caugth TL exception: ");
+        e.print();
+#endif
+        return;
+      }
+    catch (const KordException &e)
+      {
+        *error = DYNARER_KORDEXCEPTION;
+        *errormessage = passmessage(e.getmessage());
+        *kordcode = e.code(); // Kord error code
+#ifdef DEBUG
+        printf("Caugth Kord exception: ");
+        e.print();
+#endif
+        return;
+      }
+    *error = 0;
+    return;
+  }
+}
diff --git a/dynare++/extern/R/dynareR.cpp b/dynare++/extern/R/dynareR.cpp
deleted file mode 100644
index 727fe9967c2ad3672fab9c85d607478e7c86f11d..0000000000000000000000000000000000000000
--- a/dynare++/extern/R/dynareR.cpp
+++ /dev/null
@@ -1,249 +0,0 @@
-// $Id: dynareR.cpp 862 2006-08-04 17:34:56Z tamas $
-
-// Copyright 2006, Tamas K Papp
-
-#include "dynare3.h"			// Dynare class
-#include "approximation.h"		// Approximation class
-
-// exceptions
-#include "dynare_exception.h"
-#include "parser/cc/parser_exception.h"
-#include "utils/cc/exception.h"
-#include "SylvException.h"
-#include "tl_exception.h"
-#include "kord_exception.h"
-
-#include <algorithm>
-
-#include <string.h>
-
-#ifdef DEBUG
-#include <stdio.h>
-#endif
-
-#include <R_ext/Memory.h>
-
-/** This file containt the C glue functions for an R interface to
- * Dynare++.  Although written in standard C (except for the use of
- * R_alloc), the indexing, calling and memory management conventions
- * of the functions in this file were tailored for R.
- *
- * It is not recommended that you use this interface for anything else
- * but R.
- */ 
-
-/** Error codes: these error codes correspond to possible
- * exceptions. */
-#define DYNARER_SYLVEXCEPTION 1
-#define DYNARER_DYNAREEXCEPTION 2
-#define DYNARER_OGUEXCEPTION 3
-#define DYNARER_TLEXCEPTION 4
-#define DYNARER_KORDEXCEPTION 5
-#define DYNARER_NAMESMATCHINGERROR 6
-
-/** Copies the message into a buffer.  The buffer is allocated and
- * managed by R, ie it will be garbage collected after the .C call
- * returns and the contents are duplicated.
- */
-char *passmessage(const char *errormessage) {
-	long l = strlen(errormessage);
-	char *em = R_alloc(l, 1);
-	return strcpy(em, errormessage);
-}
-
-/** This function puts the mapping between the newtotal items after
- * nl[offset] and the items in orig into the buffer perm, which has to
- * be at least as long as newtotal.  The function uses R indexing,
- * that is to say, the first index is 1.
- */
-int matchnames(const char **orig, int origtotal, 
-			   const NameList &nl, int offset, int newtotal,
-			   int *perm) {
-#ifdef DEBUG
-	printf("matching names (R indexing):\n");
-#endif
-	for (int i=0; i < newtotal; i++) {
-		int j;
-		for (j=0; j < origtotal; j++)
-			if (strcmp(nl.getName(offset+i), *(orig+j))==0) {
-				*(perm+i) = j+1;
-#ifdef DEBUG
-				printf("%d -> %d\n",i+1,j+1);
-#endif
-				break;
-			}
-		if (j==origtotal)
-			return 1;
-	}
-	return 0;
-}
-
-/** dynareR is the interface function.  The user provides:
- * - a list of endogenous and exogenous variables, a list of
- *   parameters (and the length of each list)
- * - the model equations (modeleq, pointer to a 0-terminated string)
- * - the order of expansion (ord)
- * - journal file name (jnlfile, can be "/dev/null" for no journal)
- * - values for the parametes (parval)
- * - variance-covariance matrix (vcov, stacked by columns, R does
- *   this)
- * - initial values for finding the steady state (initval)
- * - and the number of steps for the approximation algorithm
- *   (numsteps)
- *
- * If successful, the interface will write the results to these
- * buffers:
- * - tensorbuffer for the steady state and the flattened tensors
- * - num_state for the number of endogenous variables that ended up in
- *   the state
- * - mappings to variable names (ordering_state, ordering_endo,
- *   ordering_exo), indices start from 1
- * - the deterministic steady state (newinitval)
- *
- * If dynare throws an exception, the interface tries to catch it and
- * return an error code (error), and error message (errormessage), and
- * if applicable, information on the stability of the model
- * (kordcode).  errormessage is allocated into R's memory, and will be
- * collected after duplication.
- */
-extern "C" {
-	void dynareR(const char** endo, const int* num_endo,
-				 const char** exo, const int* num_exo,
-				 const char** par, const int* num_par,
-				 const char** equations, const int* ord, const char* jnlfile,
-				 const double *parval, const double *vcov, 
-				 const double *initval,
-				 const int *num_steps,
-				 double* tensorbuffer,
-				 int *num_state, int *ordering_state,
-				 int *ordering_endo, int *ordering_exo,
-				 double *newinitval,
-				 int* error, char **errormessage, int *kordcode) {
-		// construct the model here
-		try {	
-#ifdef DEBUG					// will print only first var names etc.
-			printf("eq: %s\nendo: %d %s\nexo: %d %s\npar: %d %s\nord: %d\n",
-				   *equations,*num_endo,*endo,*num_exo,*exo,*num_par,*par,*ord);
-#endif
-			// create journal
-			Journal journal(jnlfile);
-			// create Dynare object
-			Dynare dynare(endo, *num_endo, exo, *num_exo,
-						  par, *num_par, *equations, strlen(*equations),
-						  *ord, journal);
-			// set Vcov and parameter values
-			copy(parval,parval+(*num_par),dynare.getParams().base());
-#ifdef DEBUG
-			printf("parameter values (%d):\n",dynare.getParams().length());
-			dynare.getParams().print();
-#endif
-			copy(vcov,vcov+(*num_exo)*(*num_exo),dynare.getVcov().base());
-#ifdef DEBUG
-			printf("vcov matrix:\n");
-			dynare.getVcov().print();
-#endif
-			// set initial values
-			Vector iv(initval,*num_endo);
-#ifdef DEBUG
-			printf("initial values:\n");
-			iv.print();
-#endif
-			dynare.setInitOuter(iv);
-			// construct approximation
-			tls.init(dynare.order(),
-					 dynare.nstat()+2*dynare.npred()+3*dynare.nboth()+
-					 2*dynare.nforw()+dynare.nexog());
-			Approximation approximation(dynare,journal,*num_steps);
-			approximation.walkStochSteady();
-			// write the steady state into the buffer
-			int ny = dynare.ny();
-			const Vector ss(dynare.getSteady());
-//			ss = ConstVector(approximation.getSS(), 0); // FIXME allow
-//														// for nonzero
-			int s = dynare.getStateNames().getNum();
-			int sm = s;
-			tensorbuffer = copy(ss.base(),ss.base()+ny,tensorbuffer);
-			// write the tensors into buffer
-			const UnfoldDecisionRule& udr = 
-				approximation.getUnfoldDecisionRule();
-			for (int i=1; i <= *ord; i++) {
-				const UFSTensor* t = udr.get(Symmetry(i));
-#ifdef DEBUG
-				printf("tensor %d:\n", i);
-				t->print();
-#endif
-				tensorbuffer = copy(t->base(), t->base()+ny*sm, tensorbuffer);
-				sm *= s;
-				}
-			// save number of endogenous states
-			*num_state = s-(*num_exo);
-			// ordering
-#ifdef DEBUG
-			printf("all endo names:\n");
-			dynare.getAllEndoNames().print();
-			printf("all state names:\n");
-			dynare.getStateNames().print();
-#endif
-			if (matchnames(endo, *num_endo, dynare.getAllEndoNames(),
-						   0, *num_endo, ordering_endo) ||
-				matchnames(endo, *num_endo, dynare.getStateNames(),
-						   0, *num_state, ordering_state) ||
-				matchnames(exo, *num_exo, dynare.getStateNames(),
-						   *num_state, *num_exo, ordering_exo)) {
-				*error = DYNARER_NAMESMATCHINGERROR;
-				*errormessage = "There was a problem when matching names.  This is weird and should not happen.";
-				return;
-			}
-			// return new init values (first column of SS matrix)
-			ConstVector newinit((const GeneralMatrix&) approximation.getSS(), 0);
-#ifdef DEBUG
-			printf("new initial values:\n");
-			newinit.print();
-#endif
-			copy(newinit.base(),newinit.base()+(*num_endo),newinitval);
-		} catch (const SylvException &e) {
-			*error = DYNARER_SYLVEXCEPTION;
-			char errorbuffer[501];
-			e.printMessage(errorbuffer, 500);
-			*errormessage = passmessage(errorbuffer);
-#ifdef DEBUG
-			printf("Caught Sylv exception: ");
-			e.printMessage();
-#endif
-			return;
-		} catch (const DynareException &e) {
-			*error = DYNARER_DYNAREEXCEPTION;
-			*errormessage = passmessage(e.message());
-#ifdef DEBUG
-			printf("Caught Dynare exception: %s\n", e.message());
-#endif
-			return;
-		}  catch (const ogu::Exception &e) {
-			*error = DYNARER_OGUEXCEPTION;
-			*errormessage = passmessage(e.message());
-#ifdef DEBUG
-			printf("Caught ogu::Exception: ");
-			e.print();
-#endif
-			return;
-		} catch (const TLException &e) {
-			*error = DYNARER_TLEXCEPTION;
-			*errormessage = passmessage(e.getmessage());
-#ifdef DEBUG
-			printf("Caugth TL exception: ");
-			e.print();
-#endif
-			return;
-		} catch (const KordException &e) {
-			*error = DYNARER_KORDEXCEPTION;
-			*errormessage = passmessage(e.getmessage());
-			*kordcode = e.code(); // Kord error code
-#ifdef DEBUG
-			printf("Caugth Kord exception: ");
-			e.print();
-#endif
-			return;
-		}
-		*error = 0;
-		return;}
-}
diff --git a/dynare++/extern/R/test.cc b/dynare++/extern/R/test.cc
new file mode 100644
index 0000000000000000000000000000000000000000..68de75490479d45b038364befcf63f034e894d86
--- /dev/null
+++ b/dynare++/extern/R/test.cc
@@ -0,0 +1,34 @@
+#include "dynareR.cc"
+
+int
+main(void)
+{
+  const char *parameters[] = {"beta", "gamma", "rho", "alpha", "delta"};
+  const char *varendo[] = {"k", "c", "a"};
+  const char *varexo[] = {"eps"};
+  const int numpar = 5;
+  const int numendo = 3;
+  const int numexo = 1;
+  const int ord = 2;
+  const int numsteps = 0;
+  const double parval[] = {.99, 2, .9, .3, .025};
+  const double vcov[] = {0.001};
+  const double initval[] = {0.066, 0.43, 0.01};
+
+  int e;
+  double tensorbuffer[100];
+  int num_state;
+  int ordering_state[] = {0, 0, 0};
+  int ordering_endo[] = {0, 0, 0};
+  int ordering_exo[] = {0};
+  double newinitval[] = {0, 0, 0};
+
+  const char *modeleq[] = {"(c/c(1))^gamma*beta*(alpha*exp(a(1))*k^(alpha-1)+1-delta)=1; a=rho*a(-1)+eps; k+c=exp(a)*k(-1)^alpha+(1-delta)*k(-1);"};
+
+  dynareR(varendo, &numendo, varexo, &numexo, parameters, &numpar, modeleq,
+          &ord, "journal", parval, vcov, initval,
+          &numsteps, tensorbuffer,
+          &num_state, ordering_state, ordering_endo, ordering_exo,
+          newinitval, &e);
+  printf("error code: %d\n", e);
+}
diff --git a/dynare++/extern/R/test.cpp b/dynare++/extern/R/test.cpp
deleted file mode 100644
index 6c843c609e941d2903db35260c840f4472f6fe86..0000000000000000000000000000000000000000
--- a/dynare++/extern/R/test.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-#include "dynareR.cpp"
-
-int main(void) {
-	const char *parameters[] = {"beta","gamma","rho","alpha","delta"};
-	const char *varendo[] = {"k","c","a"};
-	const char *varexo[] = {"eps"};
-	const int numpar = 5;
-	const int numendo = 3;
-	const int numexo = 1;
-	const int ord = 2;
-	const int numsteps = 0;
-	const double parval[] = {.99,2,.9,.3,.025};
-	const double vcov[] = {0.001};
-	const double initval[] = {0.066, 0.43, 0.01};
-
-	int e;
-	double tensorbuffer[100];
-	int num_state;
-	int ordering_state[] = {0,0,0};
-	int ordering_endo[] = {0,0,0};
-	int ordering_exo[] = {0};
-	double newinitval[] = {0,0,0};
-	
-	const char *modeleq[] = {"(c/c(1))^gamma*beta*(alpha*exp(a(1))*k^(alpha-1)+1-delta)=1; a=rho*a(-1)+eps; k+c=exp(a)*k(-1)^alpha+(1-delta)*k(-1);"};
-
-	dynareR(varendo, &numendo, varexo, &numexo, parameters, &numpar, modeleq,
-			&ord, "journal", parval, vcov, initval,
-			&numsteps, tensorbuffer,
-			&num_state, ordering_state, ordering_endo, ordering_exo,
-			newinitval,&e);
-	printf("error code: %d\n", e);
-}
diff --git a/dynare++/extern/matlab/dynare_simul.cc b/dynare++/extern/matlab/dynare_simul.cc
new file mode 100644
index 0000000000000000000000000000000000000000..192c8114508b567b895b8059bb60054d7f3a0c59
--- /dev/null
+++ b/dynare++/extern/matlab/dynare_simul.cc
@@ -0,0 +1,140 @@
+// Copyright (C) 2005-2011, Ondra Kamenik
+
+// This is the mexFunction providing interface to
+// DecisionRule<>::simulate(). It takes the following input
+// parameters:
+//      order    the order of approximation, needs order+1 derivatives
+//      nstat
+//      npred
+//      nboth
+//      nforw
+//      nexog
+//      ystart   starting value (full vector of endogenous)
+//      shocks   matrix of shocks (nexog x number of period)
+//      vcov     covariance matrix of shocks (nexog x nexog)
+//      seed     integer seed
+//      ysteady  full vector of decision rule's steady
+//      ...      order+1 matrices of derivatives
+
+// output:
+//      res      simulated results
+
+#include "dynmex.h"
+#include "mex.h"
+
+#include "decision_rule.hh"
+#include "fs_tensor.hh"
+#include "SylvException.hh"
+
+extern "C" {
+  void
+  mexFunction(int nlhs, mxArray *plhs[],
+              int nhrs, const mxArray *prhs[])
+  {
+    if (nhrs < 12 || nlhs != 2)
+      DYN_MEX_FUNC_ERR_MSG_TXT("dynare_simul_ must have at least 12 input parameters and exactly 2 output arguments.\n");
+
+    int order = (int) mxGetScalar(prhs[0]);
+    if (nhrs != 12 + order)
+      DYN_MEX_FUNC_ERR_MSG_TXT("dynare_simul_ must have exactly 11+order input parameters.\n");
+
+    int nstat = (int) mxGetScalar(prhs[1]);
+    int npred = (int) mxGetScalar(prhs[2]);
+    int nboth = (int) mxGetScalar(prhs[3]);
+    int nforw = (int) mxGetScalar(prhs[4]);
+    int nexog = (int) mxGetScalar(prhs[5]);
+
+    const mxArray *const ystart = prhs[6];
+    const mxArray *const shocks = prhs[7];
+    const mxArray *const vcov = prhs[8];
+    int seed = (int) mxGetScalar(prhs[9]);
+    const mxArray *const ysteady = prhs[10];
+    const mwSize *const ystart_dim = mxGetDimensions(ystart);
+    const mwSize *const shocks_dim = mxGetDimensions(shocks);
+    const mwSize *const vcov_dim = mxGetDimensions(vcov);
+    const mwSize *const ysteady_dim = mxGetDimensions(ysteady);
+
+    int ny = nstat + npred + nboth + nforw;
+    if (ny != (int) ystart_dim[0])
+      DYN_MEX_FUNC_ERR_MSG_TXT("ystart has wrong number of rows.\n");
+    if (1 != ystart_dim[1])
+      DYN_MEX_FUNC_ERR_MSG_TXT("ystart has wrong number of cols.\n");
+    int nper = shocks_dim[1];
+    if (nexog != (int) shocks_dim[0])
+      DYN_MEX_FUNC_ERR_MSG_TXT("shocks has a wrong number of rows.\n");
+    if (nexog != (int) vcov_dim[0])
+      DYN_MEX_FUNC_ERR_MSG_TXT("vcov has a wrong number of rows.\n");
+    if (nexog != (int) vcov_dim[1])
+      DYN_MEX_FUNC_ERR_MSG_TXT("vcov has a wrong number of cols.\n");
+    if (ny != (int) ysteady_dim[0])
+      DYN_MEX_FUNC_ERR_MSG_TXT("ysteady has wrong number of rows.\n");
+    if (1 != ysteady_dim[1])
+      DYN_MEX_FUNC_ERR_MSG_TXT("ysteady has wrong number of cols.\n");
+
+    mxArray *res = mxCreateDoubleMatrix(ny, nper, mxREAL);
+
+    try
+      {
+        // initialize tensor library
+        tls.init(order, npred+nboth+nexog);
+
+        // form the polynomial
+        UTensorPolynomial pol(ny, npred+nboth+nexog);
+        for (int dim = 0; dim <= order; dim++)
+          {
+            const mxArray *gk = prhs[11+dim];
+            const mwSize *const gk_dim = mxGetDimensions(gk);
+            FFSTensor ft(ny, npred+nboth+nexog, dim);
+            if (ft.ncols() != (int) gk_dim[1])
+              {
+                char buf[1000];
+                sprintf(buf, "Wrong number of columns for folded tensor: got %d but I want %d\n",
+                        (int) gk_dim[1], ft.ncols());
+                DYN_MEX_FUNC_ERR_MSG_TXT(buf);
+              }
+            if (ft.nrows() != (int) gk_dim[0])
+              {
+                char buf[1000];
+                sprintf(buf, "Wrong number of rows for folded tensor: got %d but I want %d\n",
+                        (int) gk_dim[0], ft.nrows());
+                DYN_MEX_FUNC_ERR_MSG_TXT(buf);
+              }
+            ft.zeros();
+            ConstTwoDMatrix gk_mat(ft.nrows(), ft.ncols(), mxGetPr(gk));
+            ft.add(1.0, gk_mat);
+            UFSTensor *ut = new UFSTensor(ft);
+            pol.insert(ut);
+          }
+        // form the decision rule
+        UnfoldDecisionRule
+          dr(pol, PartitionY(nstat, npred, nboth, nforw),
+             nexog, ConstVector(mxGetPr(ysteady), ny));
+        // form the shock realization
+        TwoDMatrix shocks_mat(nexog, nper, (const double *)mxGetPr(shocks));
+        TwoDMatrix vcov_mat(nexog, nexog, (const double *)mxGetPr(vcov));
+        GenShockRealization sr(vcov_mat, shocks_mat, seed);
+        // simulate and copy the results
+        Vector ystart_vec((const double *)mxGetPr(ystart), ny);
+        TwoDMatrix *res_mat
+          = dr.simulate(DecisionRule::horner, nper,
+                        ystart_vec, sr);
+        TwoDMatrix res_tmp_mat(ny, nper, mxGetPr(res));
+        res_tmp_mat = (const TwoDMatrix &) (*res_mat);
+        delete res_mat;
+        plhs[1] = res;
+      }
+    catch (const KordException &e)
+      {
+        DYN_MEX_FUNC_ERR_MSG_TXT("Caugth Kord exception.");
+      }
+    catch (const TLException &e)
+      {
+        DYN_MEX_FUNC_ERR_MSG_TXT("Caugth TL exception.");
+      }
+    catch (SylvException &e)
+      {
+        DYN_MEX_FUNC_ERR_MSG_TXT("Caught Sylv exception.");
+      }
+    plhs[0] = mxCreateDoubleScalar(0);
+  }
+};
diff --git a/dynare++/extern/matlab/dynare_simul.cpp b/dynare++/extern/matlab/dynare_simul.cpp
deleted file mode 100644
index 03ea0d397e70a6c767dba9e7e3ce3f3eeb7511b2..0000000000000000000000000000000000000000
--- a/dynare++/extern/matlab/dynare_simul.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright (C) 2005-2011, Ondra Kamenik
-
-// This is the mexFunction providing interface to
-// DecisionRule<>::simulate(). It takes the following input
-// parameters:
-//      order    the order of approximation, needs order+1 derivatives
-//      nstat
-//      npred
-//      nboth
-//      nforw
-//      nexog
-//      ystart   starting value (full vector of endogenous)
-//      shocks   matrix of shocks (nexog x number of period)
-//      vcov     covariance matrix of shocks (nexog x nexog)
-//      seed     integer seed
-//      ysteady  full vector of decision rule's steady
-//      ...      order+1 matrices of derivatives
-
-// output:
-//      res      simulated results
-
-#include "dynmex.h"
-#include "mex.h"
-
-#include "decision_rule.hh"
-#include "fs_tensor.hh"
-#include "SylvException.h"
-
-extern "C" {
-	void mexFunction(int nlhs, mxArray* plhs[],
-					 int nhrs, const mxArray* prhs[])
-	{
-		if (nhrs < 12 || nlhs != 2)
-                  DYN_MEX_FUNC_ERR_MSG_TXT("dynare_simul_ must have at least 12 input parameters and exactly 2 output arguments.\n");
-
-		int order = (int)mxGetScalar(prhs[0]);
-		if (nhrs != 12 + order)
-                  DYN_MEX_FUNC_ERR_MSG_TXT("dynare_simul_ must have exactly 11+order input parameters.\n");
-
-		int nstat = (int)mxGetScalar(prhs[1]);
-		int npred = (int)mxGetScalar(prhs[2]);
-		int nboth = (int)mxGetScalar(prhs[3]);
-		int nforw = (int)mxGetScalar(prhs[4]);
-		int nexog = (int)mxGetScalar(prhs[5]);
-
-		const mxArray* const ystart = prhs[6];
-		const mxArray* const shocks = prhs[7];
-		const mxArray* const vcov = prhs[8];
-		int seed = (int)mxGetScalar(prhs[9]);
-		const mxArray* const ysteady = prhs[10];
-		const mwSize* const ystart_dim = mxGetDimensions(ystart);
-		const mwSize* const shocks_dim = mxGetDimensions(shocks);
-		const mwSize* const vcov_dim = mxGetDimensions(vcov);
-		const mwSize* const ysteady_dim = mxGetDimensions(ysteady);
-
-		int ny = nstat + npred + nboth + nforw;
-		if (ny != (int) ystart_dim[0])
-			DYN_MEX_FUNC_ERR_MSG_TXT("ystart has wrong number of rows.\n");
-		if (1 != ystart_dim[1])
-			DYN_MEX_FUNC_ERR_MSG_TXT("ystart has wrong number of cols.\n");
-		int nper = shocks_dim[1];
-		if (nexog != (int) shocks_dim[0])
-			DYN_MEX_FUNC_ERR_MSG_TXT("shocks has a wrong number of rows.\n");
-		if (nexog != (int) vcov_dim[0])
-			DYN_MEX_FUNC_ERR_MSG_TXT("vcov has a wrong number of rows.\n");
-		if (nexog != (int) vcov_dim[1])
-			DYN_MEX_FUNC_ERR_MSG_TXT("vcov has a wrong number of cols.\n");
-		if (ny != (int) ysteady_dim[0])
-			DYN_MEX_FUNC_ERR_MSG_TXT("ysteady has wrong number of rows.\n");
-		if (1 != ysteady_dim[1])
-			DYN_MEX_FUNC_ERR_MSG_TXT("ysteady has wrong number of cols.\n");
-
-		mxArray* res = mxCreateDoubleMatrix(ny, nper, mxREAL);
-
-		try {
-			// initialize tensor library
-			tls.init(order, npred+nboth+nexog);
-
-			// form the polynomial
-			UTensorPolynomial pol(ny, npred+nboth+nexog);
-			for (int dim = 0; dim <= order; dim++) {
-				const mxArray* gk = prhs[11+dim];
-				const mwSize* const gk_dim = mxGetDimensions(gk);
-				FFSTensor ft(ny, npred+nboth+nexog, dim);
-				if (ft.ncols() != (int) gk_dim[1]) {
-					char buf[1000];
-					sprintf(buf, "Wrong number of columns for folded tensor: got %d but I want %d\n",
-						(int) gk_dim[1], ft.ncols());
-					DYN_MEX_FUNC_ERR_MSG_TXT(buf);
-				}
-				if (ft.nrows() != (int) gk_dim[0]) {
-					char buf[1000];
-					sprintf(buf, "Wrong number of rows for folded tensor: got %d but I want %d\n",
-						(int) gk_dim[0], ft.nrows());
-					DYN_MEX_FUNC_ERR_MSG_TXT(buf);
-				}
-				ft.zeros();
-				ConstTwoDMatrix gk_mat(ft.nrows(), ft.ncols(), mxGetPr(gk));
-				ft.add(1.0, gk_mat);
-				UFSTensor* ut = new UFSTensor(ft);
-				pol.insert(ut);
-			}
-			// form the decision rule
-			UnfoldDecisionRule
-				dr(pol, PartitionY(nstat, npred, nboth, nforw),
-				   nexog, ConstVector(mxGetPr(ysteady), ny));
-			// form the shock realization
-			TwoDMatrix shocks_mat(nexog, nper, (const double*)mxGetPr(shocks));
-			TwoDMatrix vcov_mat(nexog, nexog, (const double*)mxGetPr(vcov));
-			GenShockRealization sr(vcov_mat, shocks_mat, seed);
-			// simulate and copy the results
-			Vector ystart_vec((const double*)mxGetPr(ystart), ny);
-			TwoDMatrix* res_mat =
-				dr.simulate(DecisionRule::horner, nper,
-							ystart_vec, sr);
-			TwoDMatrix res_tmp_mat(ny, nper, mxGetPr(res));
-			res_tmp_mat = (const TwoDMatrix&)(*res_mat);
-			delete res_mat;
-			plhs[1] = res;
-		} catch (const KordException& e) {
-			DYN_MEX_FUNC_ERR_MSG_TXT("Caugth Kord exception.");
-		} catch (const TLException& e) {
-			DYN_MEX_FUNC_ERR_MSG_TXT("Caugth TL exception.");
-		} catch (SylvException& e) {
-			DYN_MEX_FUNC_ERR_MSG_TXT("Caught Sylv exception.");
-		}
-                plhs[0] = mxCreateDoubleScalar(0);
-	}
-};
diff --git a/dynare++/integ/cc/quasi_mcarlo.hh b/dynare++/integ/cc/quasi_mcarlo.hh
index fa9f97ed1d38c76900ee625258db219db2f8af76..5385b688651e97ecd39d65b3ca98e9dc414aefd2 100644
--- a/dynare++/integ/cc/quasi_mcarlo.hh
+++ b/dynare++/integ/cc/quasi_mcarlo.hh
@@ -28,7 +28,7 @@
 #include "int_sequence.hh"
 #include "quadrature.hh"
 
-#include "Vector.h"
+#include "Vector.hh"
 
 #include <vector>
 
diff --git a/dynare++/integ/cc/vector_function.hh b/dynare++/integ/cc/vector_function.hh
index 7ec856b82f8443eff1bc7ab448c92e2b25b19ea2..bcef366af228be605c7e050839d83c8486e255fe 100644
--- a/dynare++/integ/cc/vector_function.hh
+++ b/dynare++/integ/cc/vector_function.hh
@@ -16,8 +16,8 @@
 #ifndef VECTOR_FUNCTION_H
 #define VECTOR_FUNCTION_H
 
-#include "Vector.h"
-#include "GeneralMatrix.h"
+#include "Vector.hh"
+#include "GeneralMatrix.hh"
 
 #include <vector>
 
diff --git a/dynare++/integ/src/quadrature-points.cc b/dynare++/integ/src/quadrature-points.cc
index 7d8358aa604726fdbdd33740653b86b4bf2b20e7..56a4b7052700e4b78cbabec1d2f31f07d7f5852a 100644
--- a/dynare++/integ/src/quadrature-points.cc
+++ b/dynare++/integ/src/quadrature-points.cc
@@ -1,12 +1,12 @@
 // Copyright (C) 2008-2011, Ondra Kamenik
 
-#include "parser/cc/matrix_parser.h"
-#include "utils/cc/memory_file.h"
-#include "utils/cc/exception.h"
-#include "sylv/cc/GeneralMatrix.h"
-#include "sylv/cc/Vector.h"
-#include "sylv/cc/SymSchurDecomp.h"
-#include "sylv/cc/SylvException.h"
+#include "parser/cc/matrix_parser.hh"
+#include "utils/cc/memory_file.hh"
+#include "utils/cc/exception.hh"
+#include "sylv/cc/GeneralMatrix.hh"
+#include "sylv/cc/Vector.hh"
+#include "sylv/cc/SymSchurDecomp.hh"
+#include "sylv/cc/SylvException.hh"
 #include "integ/cc/quadrature.hh"
 #include "integ/cc/smolyak.hh"
 #include "integ/cc/product.hh"
diff --git a/dynare++/integ/testing/tests.cc b/dynare++/integ/testing/tests.cc
index d10e06393cc9ed6802621b9209edee7f34458318..76e2db514a6eca93aa3fcbf8c5d140d9ff144efe 100644
--- a/dynare++/integ/testing/tests.cc
+++ b/dynare++/integ/testing/tests.cc
@@ -1,18 +1,18 @@
 /* $Id: tests.cpp 431 2005-08-16 15:41:01Z kamenik $ */
 /* Copyright 2005, Ondra Kamenik */
 
-#include "GeneralMatrix.h"
+#include "GeneralMatrix.hh"
 #include <dynlapack.h>
-#include "SylvException.h"
+#include "SylvException.hh"
 
-#include "rfs_tensor.h"
-#include "normal_moments.h"
+#include "rfs_tensor.hh"
+#include "normal_moments.hh"
 
-#include "vector_function.h"
-#include "quadrature.h"
-#include "smolyak.h"
-#include "product.h"
-#include "quasi_mcarlo.h"
+#include "vector_function.hh"
+#include "quadrature.hh"
+#include "smolyak.hh"
+#include "product.hh"
+#include "quasi_mcarlo.hh"
 
 #include <cstdio>
 #include <cstring>
diff --git a/dynare++/kord/decision_rule.cc b/dynare++/kord/decision_rule.cc
index 3afd8072818c52d8559167d2e5dc544919511570..1287274fd7b686870b45d62653217224430ce454 100644
--- a/dynare++/kord/decision_rule.cc
+++ b/dynare++/kord/decision_rule.cc
@@ -4,7 +4,7 @@
 #include "decision_rule.hh"
 #include "dynamic_model.hh"
 
-#include "SymSchurDecomp.h"
+#include "SymSchurDecomp.hh"
 
 #include <dynlapack.h>
 
diff --git a/dynare++/kord/dynamic_model.hh b/dynare++/kord/dynamic_model.hh
index 279985f3f2aa60f447d961b8133be2917eff0f62..8cd11c1dd555b604311de2017a1fce9e6b04dd3a 100644
--- a/dynare++/kord/dynamic_model.hh
+++ b/dynare++/kord/dynamic_model.hh
@@ -13,7 +13,7 @@
 #include "t_container.hh"
 #include "sparse_tensor.hh"
 
-#include "Vector.h"
+#include "Vector.hh"
 
 /* The class is a virtual pure class which provides an access to names
    of the variables. */
diff --git a/dynare++/kord/global_check.cc b/dynare++/kord/global_check.cc
index d0a5556ef194d01198db5240bdfbda018ee7ad70..f8b90b0c8e21c2fa196eebefd2bd034389dfa6f7 100644
--- a/dynare++/kord/global_check.cc
+++ b/dynare++/kord/global_check.cc
@@ -1,6 +1,6 @@
 // Copyright 2005, Ondra Kamenik
 
-#include "SymSchurDecomp.h"
+#include "SymSchurDecomp.hh"
 
 #include "global_check.hh"
 
diff --git a/dynare++/kord/korder.hh b/dynare++/kord/korder.hh
index 20e7a25417532008103f67645a7cd77d972b0691..5b0b3741b99b8034e2baad94adc8f6224dc9fce9 100644
--- a/dynare++/kord/korder.hh
+++ b/dynare++/kord/korder.hh
@@ -36,7 +36,7 @@
 #include "journal.hh"
 
 #include "kord_exception.hh"
-#include "GeneralSylvester.h"
+#include "GeneralSylvester.hh"
 
 #include <dynlapack.h>
 
diff --git a/dynare++/kord/tests.cc b/dynare++/kord/tests.cc
index 8e782035d8871f2b2a0ea7b3c7e02a0bcdd564ef..fa60c6040dcdcc6beab1ddcb08df19e3dc341912 100644
--- a/dynare++/kord/tests.cc
+++ b/dynare++/kord/tests.cc
@@ -3,7 +3,7 @@
 
 #include <cstdlib>
 #include "korder.hh"
-#include "SylvException.h"
+#include "SylvException.hh"
 
 struct Rand
 {
diff --git a/dynare++/parser/cc/Makefile.am b/dynare++/parser/cc/Makefile.am
index a63168651cd4785804fd636e29b2c8cc6ed2aa53..d099909f243e5a79c46eade9e72542750821c2e8 100644
--- a/dynare++/parser/cc/Makefile.am
+++ b/dynare++/parser/cc/Makefile.am
@@ -3,40 +3,40 @@ noinst_LIBRARIES = libparser.a
 GENERATED_FILES = assign_tab.cc csv_tab.cc formula_tab.cc matrix_tab.cc namelist_tab.cc assign_tab.hh csv_tab.hh formula_tab.hh matrix_tab.hh namelist_tab.hh assign_ll.cc csv_ll.cc formula_ll.cc matrix_ll.cc namelist_ll.cc
 
 libparser_a_SOURCES = \
-	location.h \
-	namelist.h \
-	atom_assignings.cpp \
-	atom_assignings.h \
-	atom_substitutions.cpp \
-	atom_substitutions.h \
-	csv_parser.cpp \
-	csv_parser.h \
-	dynamic_atoms.cpp \
-	dynamic_atoms.h \
-	fine_atoms.cpp \
-	fine_atoms.h \
-	formula_parser.cpp \
-	formula_parser.h \
-	matrix_parser.cpp \
-	matrix_parser.h \
-	parser_exception.cpp \
-	parser_exception.h \
-	static_atoms.cpp \
-	static_atoms.h \
-	static_fine_atoms.cpp \
-	static_fine_atoms.h \
-	tree.cpp \
-	tree.h \
+	location.hh \
+	namelist.hh \
+	atom_assignings.cc \
+	atom_assignings.hh \
+	atom_substitutions.cc \
+	atom_substitutions.hh \
+	csv_parser.cc \
+	csv_parser.hh \
+	dynamic_atoms.cc \
+	dynamic_atoms.hh \
+	fine_atoms.cc \
+	fine_atoms.hh \
+	formula_parser.cc \
+	formula_parser.hh \
+	matrix_parser.cc \
+	matrix_parser.hh \
+	parser_exception.cc \
+	parser_exception.hh \
+	static_atoms.cc \
+	static_atoms.hh \
+	static_fine_atoms.cc \
+	static_fine_atoms.hh \
+	tree.cc \
+	tree.hh \
 	$(GENERATED_FILES)
 
 libparser_a_CPPFLAGS = -I../.. $(BOOST_CPPFLAGS)
 
 BUILT_SOURCES = $(GENERATED_FILES)
 
-EXTRA_DIST = assign.y csv.y formula.y matrix.y namelist.y assign.lex csv.lex formula.lex matrix.lex namelist.lex
+EXTRA_DIST = assign.yy csv.yy formula.yy matrix.yy namelist.yy assign.ll csv.ll formula.ll matrix.ll namelist.ll
 
-%_tab.cc %_tab.hh: %.y
+%_tab.cc %_tab.hh: %.yy
 	$(YACC) -d -o$*_tab.cc $<
 
-%_ll.cc: %.lex
+%_ll.cc: %.ll
 	$(LEX) -i -o$@ $<
diff --git a/dynare++/parser/cc/assign.lex b/dynare++/parser/cc/assign.ll
similarity index 97%
rename from dynare++/parser/cc/assign.lex
rename to dynare++/parser/cc/assign.ll
index 2b74f43448d8cc974e31f7ff50359930d3774e0e..e5ef5706c4d8c821446b895e1e776f368334c042 100644
--- a/dynare++/parser/cc/assign.lex
+++ b/dynare++/parser/cc/assign.ll
@@ -1,5 +1,5 @@
 %{
-#include "location.h"
+#include "location.hh"
 #include "assign_tab.hh"
 
 	extern YYLTYPE asgn_lloc;
diff --git a/dynare++/parser/cc/assign.y b/dynare++/parser/cc/assign.yy
similarity index 94%
rename from dynare++/parser/cc/assign.y
rename to dynare++/parser/cc/assign.yy
index 83b30218ef48b6f187024da4c74bef80b232a793..3f1c8aeb5061cb960c71fdbece2fa1ef785ea07d 100644
--- a/dynare++/parser/cc/assign.y
+++ b/dynare++/parser/cc/assign.yy
@@ -1,8 +1,8 @@
 %{
 /* Copyright (C) 2006-2011, Ondra Kamenik */
 
-#include "location.h"
-#include "atom_assignings.h"
+#include "location.hh"
+#include "atom_assignings.hh"
 #include "assign_tab.hh"
 
 #include <stdio.h>
diff --git a/dynare++/parser/cc/atom_assignings.cc b/dynare++/parser/cc/atom_assignings.cc
new file mode 100644
index 0000000000000000000000000000000000000000..b1b51f65c0c6e3bc34d07592feeda13df30c0390
--- /dev/null
+++ b/dynare++/parser/cc/atom_assignings.cc
@@ -0,0 +1,252 @@
+// Copyright (C) 2006, Ondra Kamenik
+
+// $Id: atom_assignings.cpp 92 2007-04-19 11:38:21Z ondra $
+
+#include "atom_assignings.hh"
+#include "location.hh"
+#include "parser_exception.hh"
+
+#include "utils/cc/exception.hh"
+
+#include <limits>
+#include <iostream>
+
+using namespace ogp;
+
+AtomAssignings::AtomAssignings(const AtomAssignings &aa, ogp::StaticAtoms &a)
+  : atoms(a), expr(aa.expr, atoms), left_names(aa.left_names),
+    order(aa.order)
+{
+  // fill the lname2expr
+  for (Tvarintmap::const_iterator it = aa.lname2expr.begin();
+       it != aa.lname2expr.end(); ++it)
+    lname2expr.insert(Tvarintmap::value_type(left_names.query((*it).first), (*it).second));
+}
+
+/** A global symbol for passing info to the AtomAssignings from
+ * asgn_parse(). */
+AtomAssignings *aparser;
+
+/** The declaration of functions defined in asgn_ll.cc and asgn_tab.cc
+ * generated from assign.lex assign.y */
+void *asgn__scan_buffer(char *, size_t);
+void asgn__destroy_buffer(void *);
+void asgn_parse();
+extern location_type asgn_lloc;
+
+void
+AtomAssignings::parse(int length, const char *stream)
+{
+  char *buffer = new char[length+2];
+  strncpy(buffer, stream, length);
+  buffer[length] = '\0';
+  buffer[length+1] = '\0';
+  asgn_lloc.off = 0;
+  asgn_lloc.ll = 0;
+  void *p = asgn__scan_buffer(buffer, (unsigned int) length+2);
+  aparser = this;
+  asgn_parse();
+  delete [] buffer;
+  asgn__destroy_buffer(p);
+}
+
+void
+AtomAssignings::error(const char *mes)
+{
+  throw ParserException(mes, asgn_lloc.off);
+}
+
+void
+AtomAssignings::add_assignment_to_double(const char *name, double val)
+{
+  // if left hand side is a registered atom, insert it to tree
+  int t;
+  try
+    {
+      if (atoms.check(name))
+        t = expr.add_nulary(name);
+      else
+        t = -1;
+    }
+  catch (const ParserException &e)
+    {
+      t = -1;
+    }
+  // register left hand side in order
+  order.push_back(t);
+
+  // add the double to the tree
+  char tmp[100];
+  sprintf(tmp, "%30.25g", val);
+  try
+    {
+      expr.parse(strlen(tmp), tmp);
+    }
+  catch (const ParserException &e)
+    {
+      // should never happen
+      throw ParserException(string("Error parsing double ")+tmp+": "+e.message(), 0);
+    }
+
+  // register name of the left hand side and put to lname2expr
+  const char *ss = left_names.insert(name);
+  lname2expr.insert(Tvarintmap::value_type(ss, order.size()-1));
+}
+
+void
+AtomAssignings::add_assignment(int asgn_off, const char *str, int name_len,
+                               int right_off, int right_len)
+{
+  // the order of doing things here is important: since the
+  // FormulaParser requires that all references from the i-th tree
+  // refere to trees with index lass than i, so to capture also a
+  // nulary term for the left hand side, it must be inserted to the
+  // expression tree before the expression is parsed.
+
+  // find the name in the atoms, make copy of name to be able to put
+  // '\0' at the end
+  char *buf = new char[name_len+1];
+  strncpy(buf, str, name_len);
+  buf[name_len] = '\0';
+  // if left hand side is a registered atom, insert it to tree
+  int t;
+  try
+    {
+      t = atoms.check(buf);
+      if (t == -1)
+        t = expr.add_nulary(buf);
+    }
+  catch (const ParserException &e)
+    {
+      atoms.register_name(buf);
+      t = expr.add_nulary(buf);
+    }
+  // register left hand side in order
+  order.push_back(t);
+
+  // parse expression on the right
+  try
+    {
+      expr.parse(right_len, str+right_off);
+    }
+  catch (const ParserException &e)
+    {
+      throw ParserException(e, asgn_off+right_off);
+    }
+
+  // register name of the left hand side and put to lname2expr
+  const char *ss = left_names.insert(buf);
+  if (lname2expr.find(ss) != lname2expr.end())
+    {
+      // Prevent the occurrence of #415
+      std::cerr << "Changing the value of " << ss << " is not supported. Aborting." << std::endl;
+      exit(EXIT_FAILURE);
+    }
+  lname2expr[ss] = order.size()-1;
+
+  // delete name
+  delete [] buf;
+}
+
+void
+AtomAssignings::apply_subst(const AtomSubstitutions::Toldnamemap &mm)
+{
+  // go through all old variables and see what are their derived new
+  // variables
+  for (AtomSubstitutions::Toldnamemap::const_iterator it = mm.begin();
+       it != mm.end(); ++it)
+    {
+      const char *oldname = (*it).first;
+      const AtomSubstitutions::Tshiftnameset &sset = (*it).second;
+      if (!sset.empty())
+        {
+          int told = atoms.index(oldname);
+          if (told < 0 && !atoms.get_name_storage().query(oldname))
+            atoms.register_name(oldname);
+          if (told == -1)
+            told = expr.add_nulary(oldname);
+          // at least one substitution here, so make an expression
+          expr.add_formula(told);
+          // say that this expression is not assigned to any atom
+          order.push_back(-1);
+          // now go through all new names derived from the old name and
+          // reference to the newly added formula
+          for (AtomSubstitutions::Tshiftnameset::const_iterator itt = sset.begin();
+               itt != sset.end(); ++itt)
+            {
+              const char *newname = (*itt).first;
+              const char *nn = left_names.insert(newname);
+              lname2expr.insert(Tvarintmap::value_type(nn, expr.nformulas()-1));
+            }
+        }
+    }
+}
+
+void
+AtomAssignings::print() const
+{
+  printf("Atom Assignings\nExpressions:\n");
+  expr.print();
+  printf("Left names:\n");
+  for (Tvarintmap::const_iterator it = lname2expr.begin();
+       it != lname2expr.end(); ++it)
+    printf("%s ==> %d (t=%d)\n", (*it).first, expr.formula((*it).second), order[(*it).second]);
+}
+
+void
+AtomAsgnEvaluator::setValues(EvalTree &et) const
+{
+  // set values of constants
+  aa.atoms.setValues(et);
+
+  // set values of variables to NaN or to user set values
+  double nan = std::numeric_limits<double>::quiet_NaN();
+  for (int i = 0; i < aa.atoms.nvar(); i++)
+    {
+      const char *ss = aa.atoms.name(i);
+      int t = aa.atoms.index(ss);
+      if (t >= 0)
+        {
+          Tusrvalmap::const_iterator it = user_values.find(t);
+          if (it == user_values.end())
+            et.set_nulary(t, nan);
+          else
+            et.set_nulary(t, (*it).second);
+        }
+    }
+}
+
+void
+AtomAsgnEvaluator::set_user_value(const char *name, double val)
+{
+  int t = aa.atoms.index(name);
+  if (t >= 0)
+    {
+      Tusrvalmap::iterator it = user_values.find(t);
+      if (it == user_values.end())
+        user_values.insert(Tusrvalmap::value_type(t, val));
+      else
+        (*it).second = val;
+    }
+}
+
+void
+AtomAsgnEvaluator::load(int i, double res)
+{
+  // set the value
+  operator[](i) = res;
+  // if i-th expression is atom, set its value to this EvalTree
+  int t = aa.order[i];
+  if (t >= 0)
+    etree.set_nulary(t, res);
+}
+
+double
+AtomAsgnEvaluator::get_value(const char *name) const
+{
+  AtomAssignings::Tvarintmap::const_iterator it = aa.lname2expr.find(name);
+  if (it == aa.lname2expr.end())
+    return std::numeric_limits<double>::quiet_NaN();
+  else
+    return operator[]((*it).second);
+}
diff --git a/dynare++/parser/cc/atom_assignings.cpp b/dynare++/parser/cc/atom_assignings.cpp
deleted file mode 100644
index 7b688f259a918b4218d982e556ab3ecb77629d22..0000000000000000000000000000000000000000
--- a/dynare++/parser/cc/atom_assignings.cpp
+++ /dev/null
@@ -1,225 +0,0 @@
-// Copyright (C) 2006, Ondra Kamenik
-
-// $Id: atom_assignings.cpp 92 2007-04-19 11:38:21Z ondra $
-
-#include "atom_assignings.h"
-#include "location.h"
-#include "parser_exception.h"
-
-#include "utils/cc/exception.h"
-
-#include <limits>
-#include <iostream>
-
-using namespace ogp;
-
-AtomAssignings::AtomAssignings(const AtomAssignings& aa, ogp::StaticAtoms& a)
-	: atoms(a), expr(aa.expr, atoms), left_names(aa.left_names),
-	  order(aa.order)
-{
-	// fill the lname2expr
-	for (Tvarintmap::const_iterator it = aa.lname2expr.begin();
-		 it != aa.lname2expr.end(); ++it)
-		lname2expr.insert(Tvarintmap::value_type(left_names.query((*it).first), (*it).second));
-}
-
-/** A global symbol for passing info to the AtomAssignings from
- * asgn_parse(). */
-AtomAssignings* aparser;
-
-/** The declaration of functions defined in asgn_ll.cc and asgn_tab.cc
- * generated from assign.lex assign.y */
-void* asgn__scan_buffer(char*, size_t);
-void asgn__destroy_buffer(void*);
-void asgn_parse();
-extern location_type asgn_lloc;
-
-void AtomAssignings::parse(int length, const char* stream)
-{
-	char* buffer = new char[length+2];
-	strncpy(buffer, stream, length);
-	buffer[length] = '\0';
-	buffer[length+1] = '\0';
-	asgn_lloc.off = 0;
-	asgn_lloc.ll = 0;
-	void* p = asgn__scan_buffer(buffer, (unsigned int)length+2);
-	aparser = this;
-	asgn_parse();
-	delete [] buffer;
-	asgn__destroy_buffer(p);
-}
-
-void AtomAssignings::error(const char* mes)
-{
-	throw ParserException(mes, asgn_lloc.off);
-}
-
-void AtomAssignings::add_assignment_to_double(const char* name, double val)
-{
-	// if left hand side is a registered atom, insert it to tree
-	int t;
-	try {
-		if (atoms.check(name))
-			t = expr.add_nulary(name);
-		else
-			t = -1;
-	} catch (const ParserException& e) {
-		t = -1;
-	}
-	// register left hand side in order
-	order.push_back(t);
-
-	// add the double to the tree
-	char tmp[100];
-	sprintf(tmp, "%30.25g", val);
-	try {
-		expr.parse(strlen(tmp), tmp);
-	} catch (const ParserException& e) {
-		// should never happen
-		throw ParserException(string("Error parsing double ")+tmp+": "+e.message(), 0);
-	}
-
-	// register name of the left hand side and put to lname2expr
-	const char* ss = left_names.insert(name);
-	lname2expr.insert(Tvarintmap::value_type(ss, order.size()-1));
-}
-
-void AtomAssignings::add_assignment(int asgn_off, const char* str, int name_len,
-									int right_off, int right_len)
-{
-	// the order of doing things here is important: since the
-	// FormulaParser requires that all references from the i-th tree
-	// refere to trees with index lass than i, so to capture also a
-	// nulary term for the left hand side, it must be inserted to the
-	// expression tree before the expression is parsed.
-
-	// find the name in the atoms, make copy of name to be able to put
-	// '\0' at the end
-	char* buf = new char[name_len+1];
-	strncpy(buf, str, name_len);
-	buf[name_len] = '\0';
-	// if left hand side is a registered atom, insert it to tree
-	int t;
-	try {
-		t = atoms.check(buf);
-		if (t == -1)
-			t = expr.add_nulary(buf);
-	} catch (const ParserException& e) {
-		atoms.register_name(buf);
-		t = expr.add_nulary(buf);
-	}
-	// register left hand side in order
-	order.push_back(t);
-
-	// parse expression on the right
-	try {
-		expr.parse(right_len, str+right_off);
-	} catch (const ParserException& e) {
-		throw ParserException(e, asgn_off+right_off);
-	}
-
-	// register name of the left hand side and put to lname2expr
-	const char* ss = left_names.insert(buf);
-	if (lname2expr.find(ss) != lname2expr.end()) {
-		// Prevent the occurrence of #415
-		std::cerr << "Changing the value of " << ss << " is not supported. Aborting." << std::endl;
-		exit(EXIT_FAILURE);
-	}
-	lname2expr[ss] = order.size()-1;
-
-	// delete name
-	delete [] buf;
-}
-
-void AtomAssignings::apply_subst(const AtomSubstitutions::Toldnamemap& mm)
-{
-	// go through all old variables and see what are their derived new
-	// variables
-	for (AtomSubstitutions::Toldnamemap::const_iterator it = mm.begin();
-		 it != mm.end(); ++it) {
-		const char* oldname = (*it).first;
-		const AtomSubstitutions::Tshiftnameset& sset = (*it).second;
-		if (! sset.empty()) {
-			int told = atoms.index(oldname);
-			if (told < 0 && ! atoms.get_name_storage().query(oldname))
-				atoms.register_name(oldname);
-			if (told == -1)
-				told = expr.add_nulary(oldname);
-			// at least one substitution here, so make an expression
-			expr.add_formula(told);
-			// say that this expression is not assigned to any atom
-			order.push_back(-1);
-			// now go through all new names derived from the old name and
-			// reference to the newly added formula
-			for (AtomSubstitutions::Tshiftnameset::const_iterator itt = sset.begin();
-				 itt != sset.end(); ++itt) {
-				const char* newname = (*itt).first;
-				const char* nn = left_names.insert(newname);
-				lname2expr.insert(Tvarintmap::value_type(nn, expr.nformulas()-1));
-			}
-		}
-	}
-}
-
-void AtomAssignings::print() const
-{
-	printf("Atom Assignings\nExpressions:\n");
-	expr.print();
-	printf("Left names:\n");
-	for (Tvarintmap::const_iterator it = lname2expr.begin();
-		 it != lname2expr.end(); ++it)
-		printf("%s ==> %d (t=%d)\n", (*it).first, expr.formula((*it).second), order[(*it).second]);
-}
-
-void AtomAsgnEvaluator::setValues(EvalTree& et) const
-{
-	// set values of constants
-	aa.atoms.setValues(et);
-
-	// set values of variables to NaN or to user set values
-	double nan = std::numeric_limits<double>::quiet_NaN();
-	for (int i = 0; i < aa.atoms.nvar(); i++) {
-		const char* ss = aa.atoms.name(i);
-		int t = aa.atoms.index(ss);
-		if (t >= 0) {
-			Tusrvalmap::const_iterator it = user_values.find(t);
-			if (it == user_values.end())
-				et.set_nulary(t, nan);
-			else
-				et.set_nulary(t, (*it).second);
-		}
-	}
-}
-
-void AtomAsgnEvaluator::set_user_value(const char* name, double val)
-{
-	int t = aa.atoms.index(name);
-	if (t >= 0) {
-		Tusrvalmap::iterator it = user_values.find(t);
-		if (it == user_values.end())
-			user_values.insert(Tusrvalmap::value_type(t, val));
-		else
-			(*it).second = val;
-	}
-}
-
-void AtomAsgnEvaluator::load(int i, double res)
-{
-	// set the value
-	operator[](i) = res;
-	// if i-th expression is atom, set its value to this EvalTree
-	int t = aa.order[i];
-	if (t >= 0)
-		etree.set_nulary(t, res);
-}
-
-double AtomAsgnEvaluator::get_value(const char* name) const
-{
-	AtomAssignings::Tvarintmap::const_iterator it = aa.lname2expr.find(name);
-	if (it == aa.lname2expr.end())
-		return std::numeric_limits<double>::quiet_NaN();
-	else
-		return operator[]((*it).second);
-}
-
-
diff --git a/dynare++/parser/cc/atom_assignings.h b/dynare++/parser/cc/atom_assignings.hh
similarity index 98%
rename from dynare++/parser/cc/atom_assignings.h
rename to dynare++/parser/cc/atom_assignings.hh
index 14f11b2cbf247d1df5e7d3193ab0e3bbd5b0f0f3..c4c253b1af90cab2ef4351fa288d5277514c220b 100644
--- a/dynare++/parser/cc/atom_assignings.h
+++ b/dynare++/parser/cc/atom_assignings.hh
@@ -5,9 +5,9 @@
 #ifndef OGP_ATOM_ASSIGNINGS_H
 #define OGP_ATOM_ASSIGNINGS_H
 
-#include "static_atoms.h"
-#include "formula_parser.h"
-#include "atom_substitutions.h"
+#include "static_atoms.hh"
+#include "formula_parser.hh"
+#include "atom_substitutions.hh"
 
 #include <vector>
 #include <map>
diff --git a/dynare++/parser/cc/atom_substitutions.cc b/dynare++/parser/cc/atom_substitutions.cc
new file mode 100644
index 0000000000000000000000000000000000000000..6c556ea71f191a35bb718ad7b239505a32007b63
--- /dev/null
+++ b/dynare++/parser/cc/atom_substitutions.cc
@@ -0,0 +1,300 @@
+// Copyright (C) 2006, Ondra Kamenik
+
+// $Id: atom_substitutions.cpp 42 2007-01-22 21:53:24Z ondra $
+
+#include "atom_substitutions.hh"
+#include "utils/cc/exception.hh"
+
+using namespace ogp;
+
+AtomSubstitutions::AtomSubstitutions(const AtomSubstitutions &as, const FineAtoms &oa,
+                                     FineAtoms &na)
+  : old_atoms(oa), new_atoms(na)
+{
+  const NameStorage &ns = na.get_name_storage();
+
+  // fill new2old
+  for (Tshiftmap::const_iterator it = as.new2old.begin();
+       it != as.new2old.end(); ++it)
+    new2old.insert(Tshiftmap::value_type(ns.query((*it).first),
+                                         Tshiftname(ns.query((*it).second.first),
+                                                    (*it).second.second)));
+  // fill old2new
+  for (Toldnamemap::const_iterator it = as.old2new.begin();
+       it != as.old2new.end(); ++it)
+    {
+      Tshiftnameset sset;
+      for (Tshiftnameset::const_iterator itt = (*it).second.begin();
+           itt != (*it).second.end(); ++itt)
+        sset.insert(Tshiftname(ns.query((*itt).first), (*itt).second));
+      old2new.insert(Toldnamemap::value_type(ns.query((*it).first), sset));
+    }
+}
+
+void
+AtomSubstitutions::add_substitution(const char *newname, const char *oldname, int tshift)
+{
+  // make sure the storage is from the new_atoms
+  newname = new_atoms.get_name_storage().query(newname);
+  oldname = new_atoms.get_name_storage().query(oldname);
+  if (newname == NULL || oldname == NULL)
+    throw ogu::Exception(__FILE__, __LINE__,
+                         "Bad newname or oldname in AtomSubstitutions::add_substitution");
+
+  // insert to new2old map
+  new2old.insert(Tshiftmap::value_type(newname, Tshiftname(oldname, tshift)));
+  // insert to old2new map
+  Toldnamemap::iterator it = old2new.find(oldname);
+  if (it != old2new.end())
+    (*it).second.insert(Tshiftname(newname, -tshift));
+  else
+    {
+      Tshiftnameset snset;
+      snset.insert(Tshiftname(newname, -tshift));
+      old2new.insert(Toldnamemap::value_type(oldname, snset));
+    }
+
+  // put to info
+  info.num_substs++;
+}
+
+void
+AtomSubstitutions::substitutions_finished(VarOrdering::ord_type ot)
+{
+  // create an external ordering of new_atoms from old_atoms
+  const vector<const char *> &oa_ext = old_atoms.get_allvar();
+  vector<const char *> na_ext;
+  for (unsigned int i = 0; i < oa_ext.size(); i++)
+    {
+      const char *oname = oa_ext[i];
+      // add the old name itself
+      na_ext.push_back(oname);
+      // add all new names derived from the old name
+      Toldnamemap::const_iterator it = old2new.find(oname);
+      if (it != old2new.end())
+        for (Tshiftnameset::const_iterator itt = (*it).second.begin();
+             itt != (*it).second.end(); ++itt)
+          na_ext.push_back((*itt).first);
+    }
+
+  // call parsing finished for the new_atoms
+  new_atoms.parsing_finished(ot, na_ext);
+}
+
+const char *
+AtomSubstitutions::get_new4old(const char *oldname, int tshift) const
+{
+  Toldnamemap::const_iterator it = old2new.find(oldname);
+  if (it != old2new.end())
+    {
+      const Tshiftnameset &sset = (*it).second;
+      for (Tshiftnameset::const_iterator itt = sset.begin();
+           itt != sset.end(); ++itt)
+        if ((*itt).second == -tshift)
+          return (*itt).first;
+    }
+  return NULL;
+}
+
+void
+AtomSubstitutions::print() const
+{
+  printf("Atom Substitutions:\nOld ==> New:\n");
+  for (Toldnamemap::const_iterator it = old2new.begin(); it != old2new.end(); ++it)
+    for (Tshiftnameset::const_iterator itt = (*it).second.begin();
+         itt != (*it).second.end(); ++itt)
+      printf("    %s ==> [%s, %d]\n", (*it).first, (*itt).first, (*itt).second);
+
+  printf("Old <== New:\n");
+  for (Tshiftmap::const_iterator it = new2old.begin(); it != new2old.end(); ++it)
+    printf("    [%s, %d] <== %s\n", (*it).second.first, (*it).second.second, (*it).first);
+}
+
+void
+SAtoms::substituteAllLagsAndLeads(FormulaParser &fp, AtomSubstitutions &as)
+{
+  const char *name;
+
+  int mlead, mlag;
+  endovarspan(mlead, mlag);
+
+  // substitute all endo lagged more than 1
+  while (NULL != (name = findEndoWithLeadInInterval(mlag, -2)))
+    makeAuxVariables(name, -1, -2, mlag, fp, as);
+  // substitute all endo leaded more than 1
+  while (NULL != (name = findEndoWithLeadInInterval(2, mlead)))
+    makeAuxVariables(name, 1, 2, mlead, fp, as);
+
+  exovarspan(mlead, mlag);
+
+  // substitute all lagged exo
+  while (NULL != (name = findExoWithLeadInInterval(mlag, -1)))
+    makeAuxVariables(name, -1, -1, mlag, fp, as);
+  // substitute all leaded exo
+  while (NULL != (name = findExoWithLeadInInterval(1, mlead)))
+    makeAuxVariables(name, 1, 1, mlead, fp, as);
+
+  // notify that substitution have been finished
+  as.substitutions_finished(order_type);
+}
+
+void
+SAtoms::substituteAllLagsAndExo1Leads(FormulaParser &fp, AtomSubstitutions &as)
+{
+  const char *name;
+
+  int mlead, mlag;
+  endovarspan(mlead, mlag);
+
+  // substitute all endo lagged more than 1
+  while (NULL != (name = findEndoWithLeadInInterval(mlag, -2)))
+    makeAuxVariables(name, -1, -2, mlag, fp, as);
+
+  exovarspan(mlead, mlag);
+
+  // substitute all lagged exo
+  while (NULL != (name = findExoWithLeadInInterval(mlag, -1)))
+    makeAuxVariables(name, -1, -1, mlag, fp, as);
+  // substitute all leaded exo by 1
+  while (NULL != (name = findExoWithLeadInInterval(1, 1)))
+    makeAuxVariables(name, 1, 1, 1, fp, as);
+
+  // notify that substitution have been finished
+  as.substitutions_finished(order_type);
+}
+
+const char *
+SAtoms::findNameWithLeadInInterval(const vector<const char *> &names,
+                                   int ll1, int ll2) const
+{
+  for (unsigned int i = 0; i < names.size(); i++)
+    {
+      const char *name = names[i];
+      DynamicAtoms::Tvarmap::const_iterator it = vars.find(name);
+      if (it != vars.end())
+        {
+          const DynamicAtoms::Tlagmap &lmap = (*it).second;
+          for (DynamicAtoms::Tlagmap::const_iterator itt = lmap.begin();
+               itt != lmap.end(); ++itt)
+            if ((*itt).first >= ll1 && (*itt).first <= ll2)
+              return name;
+        }
+    }
+
+  // nothing found
+  return NULL;
+}
+
+void
+SAtoms::attemptAuxName(const char *str, int ll, string &out) const
+{
+  char c = (ll >= 0) ? ((ll == 0) ? 'e' : 'p') : 'm';
+  char absll[100];
+  sprintf(absll, "%d", std::abs(ll));
+  int iter = 1;
+  do
+    {
+      out = string(str) + '_';
+      for (int i = 0; i < iter; i++)
+        out += c;
+      if (ll != 0)
+        out += absll;
+      iter++;
+    }
+  while (varnames.query(out.c_str()));
+}
+
+void
+SAtoms::makeAuxVariables(const char *name, int step, int start, int limit_lead,
+                         FormulaParser &fp, AtomSubstitutions &as)
+{
+  if (!(step == 1 || step == -1))
+    throw ogu::Exception(__FILE__, __LINE__,
+                         "Wrong value of step in SAtoms::makeAuxVariables");
+  if (step*start > step*limit_lead)
+    throw ogu::Exception(__FILE__, __LINE__,
+                         "Wrong value of start in SAtoms::makeAuxVariables");
+
+  // make sure that we do not go further than necessary, this is
+  // that the limit lead is not behind maxlead or minlag
+  int mlead, mlag;
+  varspan(name, mlead, mlag);
+  if (step == -1)
+    limit_lead = std::max(limit_lead, mlag);
+  else
+    limit_lead = std::min(limit_lead, mlead);
+
+  // Comment to comments: name="a"; start=-3; step=-1;
+
+  char tmp[500];
+
+  // recover tree index of a previous atom, i.e. set tprev to a tree
+  // index of atom "a(-2)"
+  int tprev = index(name, start-step);
+  if (tprev == -1)
+    {
+      sprintf(tmp, "%s(%d)", name, start-step);
+      tprev = fp.add_nulary(tmp);
+    }
+
+  int ll = start;
+  do
+    {
+      // either create atom "a_m2(0)" with tree index taux and add
+      // equation "a_m2(0)=a(-2)"
+      // or
+      // check if "a_m2(0)" has not been already created (with
+      // different step), in this case do not add equation "a_m2(0)
+      // = a(-2)"
+      const char *newname;
+      string newname_str;
+      int taux;
+      if (NULL == (newname = as.get_new4old(name, ll-step)))
+        {
+          attemptAuxName(name, ll-step, newname_str);
+          newname = newname_str.c_str();
+          register_uniq_endo(newname);
+          newname = varnames.query(newname);
+          sprintf(tmp, "%s(0)", newname);
+          taux = fp.add_nulary(tmp);
+          // add to substitutions
+          as.add_substitution(newname, name, ll-step);
+
+          // add equation "a_m2(0) = a(-2)", this is taux = tprev
+          fp.add_formula(fp.add_binary(MINUS, taux, tprev));
+        }
+      else
+        {
+          // example: exogenous EPS and occurrence at both EPS(-1)
+          // EPS(+1)
+          // first call makeAuxVariables("EPS",1,1,...) will make endo EPS_p0 = EPS
+          // second call makeAuxVariables("EPS",-1,-1,...) will use this EPS_p0
+          //             to substitute for EPS(-1)
+          taux = index(newname, 0);
+          if (taux < 0)
+            throw ogu::Exception(__FILE__, __LINE__,
+                                 "Couldn't find tree index of previously substituted variable");
+        }
+
+      // create atom "a_m2(-1)" or turn "a(-3)" if any to "a_m2(-1)"; tree index t
+      int t = index(name, ll);
+      if (t == -1)
+        {
+          // no "a(-3)", make t <-> a_m2(-1)
+          sprintf(tmp, "%s(%d)", newname, step);
+          t = fp.add_nulary(tmp);
+        }
+      else
+        {
+          // turn a(-3) to a_m2(-1)
+          unassign_variable(name, ll, t);
+          assign_variable(newname, step, t);
+        }
+
+      // next iteration starts with tprev <-> "a_m2(-1)" (this will be made equal to "a_m3(0)")
+      tprev = t;
+
+      ll += step;
+    }
+  while (step*ll <= step*limit_lead);
+}
diff --git a/dynare++/parser/cc/atom_substitutions.cpp b/dynare++/parser/cc/atom_substitutions.cpp
deleted file mode 100644
index e6fd79ba38c34dc57514a9f4c54f34bc2e701506..0000000000000000000000000000000000000000
--- a/dynare++/parser/cc/atom_substitutions.cpp
+++ /dev/null
@@ -1,275 +0,0 @@
-// Copyright (C) 2006, Ondra Kamenik
-
-// $Id: atom_substitutions.cpp 42 2007-01-22 21:53:24Z ondra $
-
-#include "atom_substitutions.h"
-#include "utils/cc/exception.h"
-
-using namespace ogp;
-
-AtomSubstitutions::AtomSubstitutions(const AtomSubstitutions& as, const FineAtoms& oa,
-									 FineAtoms& na)
-	: old_atoms(oa), new_atoms(na)
-{
-	const NameStorage& ns = na.get_name_storage();
-
-	// fill new2old
-	for (Tshiftmap::const_iterator it = as.new2old.begin();
-		 it != as.new2old.end(); ++it)
-		new2old.insert(Tshiftmap::value_type(ns.query((*it).first),
-											 Tshiftname(ns.query((*it).second.first),
-														(*it).second.second)));
-	// fill old2new
-	for (Toldnamemap::const_iterator it = as.old2new.begin();
-		 it != as.old2new.end(); ++it) {
-		Tshiftnameset sset;
-		for (Tshiftnameset::const_iterator itt = (*it).second.begin();
-			 itt != (*it).second.end(); ++itt)
-			sset.insert(Tshiftname(ns.query((*itt).first), (*itt).second));
-		old2new.insert(Toldnamemap::value_type(ns.query((*it).first), sset));
-	}
-}
-
-
-void AtomSubstitutions::add_substitution(const char* newname, const char* oldname, int tshift)
-{
-	// make sure the storage is from the new_atoms
-	newname = new_atoms.get_name_storage().query(newname);
-	oldname = new_atoms.get_name_storage().query(oldname);
-	if (newname == NULL || oldname == NULL)
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "Bad newname or oldname in AtomSubstitutions::add_substitution");
-
-	// insert to new2old map
-	new2old.insert(Tshiftmap::value_type(newname, Tshiftname(oldname, tshift)));
-	// insert to old2new map
-	Toldnamemap::iterator it = old2new.find(oldname);
-	if (it != old2new.end())
-		(*it).second.insert(Tshiftname(newname, -tshift));
-	else {
-		Tshiftnameset snset;
-		snset.insert(Tshiftname(newname, -tshift));
-		old2new.insert(Toldnamemap::value_type(oldname, snset));
-	}
-
-	// put to info
-	info.num_substs++;
-}
-
-void AtomSubstitutions::substitutions_finished(VarOrdering::ord_type ot)
-{
-	// create an external ordering of new_atoms from old_atoms
-	const vector<const char*>& oa_ext = old_atoms.get_allvar();
-	vector<const char*> na_ext;
-	for (unsigned int i = 0; i < oa_ext.size(); i++) {
-		const char* oname = oa_ext[i];
-		// add the old name itself
-		na_ext.push_back(oname);
-		// add all new names derived from the old name
-		Toldnamemap::const_iterator it = old2new.find(oname);
-		if (it != old2new.end())
-			for (Tshiftnameset::const_iterator itt = (*it).second.begin();
-				 itt != (*it).second.end(); ++itt)
-				na_ext.push_back((*itt).first);
-	}
-
-	// call parsing finished for the new_atoms
-	new_atoms.parsing_finished(ot, na_ext);
-}
-
-const char* AtomSubstitutions::get_new4old(const char* oldname, int tshift) const
-{
-	Toldnamemap::const_iterator it = old2new.find(oldname);
-	if (it != old2new.end()) {
-		const Tshiftnameset& sset = (*it).second;
-		for (Tshiftnameset::const_iterator itt = sset.begin();
-			 itt != sset.end(); ++itt)
-			if ((*itt).second == - tshift)
-				return (*itt).first;
-	}
-	return NULL;
-}
-
-void AtomSubstitutions::print() const
-{
-	printf("Atom Substitutions:\nOld ==> New:\n");
-	for (Toldnamemap::const_iterator it = old2new.begin(); it != old2new.end(); ++it)
-		for (Tshiftnameset::const_iterator itt = (*it).second.begin();
-			 itt != (*it).second.end(); ++itt)
-			printf("    %s ==> [%s, %d]\n", (*it).first, (*itt).first, (*itt).second);
-
-	printf("Old <== New:\n");
-	for (Tshiftmap::const_iterator it = new2old.begin(); it != new2old.end(); ++it)
-		printf("    [%s, %d] <== %s\n", (*it).second.first, (*it).second.second, (*it).first);
-}
-
-void SAtoms::substituteAllLagsAndLeads(FormulaParser& fp, AtomSubstitutions& as)
-{
-	const char* name;
-
-	int mlead, mlag;
-	endovarspan(mlead, mlag);
-
-	// substitute all endo lagged more than 1
-	while (NULL != (name = findEndoWithLeadInInterval(mlag, -2)))
-		makeAuxVariables(name, -1, -2, mlag, fp, as);
-	// substitute all endo leaded more than 1
-	while (NULL != (name = findEndoWithLeadInInterval(2, mlead)))
-		makeAuxVariables(name, 1, 2, mlead, fp, as);
-
-	exovarspan(mlead, mlag);
-	
-	// substitute all lagged exo
-	while (NULL != (name = findExoWithLeadInInterval(mlag, -1)))
-		makeAuxVariables(name, -1, -1, mlag, fp, as);
-	// substitute all leaded exo
-	while (NULL != (name = findExoWithLeadInInterval(1, mlead)))
-		makeAuxVariables(name, 1, 1, mlead, fp, as);
-
-	// notify that substitution have been finished
-	as.substitutions_finished(order_type);
-}
-
-void SAtoms::substituteAllLagsAndExo1Leads(FormulaParser& fp, AtomSubstitutions& as)
-{
-	const char* name;
-
-	int mlead, mlag;
-	endovarspan(mlead, mlag);
-
-	// substitute all endo lagged more than 1
-	while (NULL != (name = findEndoWithLeadInInterval(mlag, -2)))
-		makeAuxVariables(name, -1, -2, mlag, fp, as);
-
-	exovarspan(mlead, mlag);
-	
-	// substitute all lagged exo
-	while (NULL != (name = findExoWithLeadInInterval(mlag, -1)))
-		makeAuxVariables(name, -1, -1, mlag, fp, as);
-	// substitute all leaded exo by 1
-	while (NULL != (name = findExoWithLeadInInterval(1,1)))
-		makeAuxVariables(name, 1, 1, 1, fp, as);
-
-	// notify that substitution have been finished
-	as.substitutions_finished(order_type);
-}
-
-const char* SAtoms::findNameWithLeadInInterval(const vector<const char*>& names,
-											   int ll1, int ll2) const
-{
-	for (unsigned int i = 0; i < names.size(); i++) {
-		const char* name = names[i];
-		DynamicAtoms::Tvarmap::const_iterator it = vars.find(name);
-		if (it != vars.end()) {
-			const DynamicAtoms::Tlagmap& lmap = (*it).second;
-			for (DynamicAtoms::Tlagmap::const_iterator itt = lmap.begin();
-				 itt != lmap.end(); ++itt)
-				if ((*itt).first >= ll1 && (*itt).first <= ll2)
-					return name;
-		}
-	}
-
-	// nothing found
-	return NULL;
-}
-
-void SAtoms::attemptAuxName(const char* str, int ll, string& out) const
-{
-	char c = (ll >= 0)? ((ll == 0)? 'e' : 'p' ) : 'm';
-	char absll[100];
-	sprintf(absll, "%d", std::abs(ll));
-	int iter = 1;
-	do {
-		out = string(str) + '_';
-		for (int i = 0; i < iter; i++)
-			out += c;
-		if (ll != 0)
-			out += absll;
-		iter++;
-	} while (varnames.query(out.c_str()));
-}
-
-void SAtoms::makeAuxVariables(const char* name, int step, int start, int limit_lead,
-							  FormulaParser& fp, AtomSubstitutions& as)
-{
-	if (! (step == 1 || step == -1))
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "Wrong value of step in SAtoms::makeAuxVariables");
-	if (step*start > step*limit_lead)
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "Wrong value of start in SAtoms::makeAuxVariables");
-
-	// make sure that we do not go further than necessary, this is
-	// that the limit lead is not behind maxlead or minlag
-	int mlead, mlag;
-	varspan(name, mlead, mlag);
-	if (step == -1)
-		limit_lead = std::max(limit_lead, mlag);
-	else
-		limit_lead = std::min(limit_lead, mlead);
-
-	// Comment to comments: name="a"; start=-3; step=-1;
-
-	char tmp[500];
-
-	// recover tree index of a previous atom, i.e. set tprev to a tree
-	// index of atom "a(-2)"
-	int tprev = index(name, start-step);
-	if (tprev == -1) {
-		sprintf(tmp, "%s(%d)", name, start-step);
-		tprev = fp.add_nulary(tmp);
-	}
-
-	int ll = start;
-	do {
-		// either create atom "a_m2(0)" with tree index taux and add
-		// equation "a_m2(0)=a(-2)"
-		// or 
-        // check if "a_m2(0)" has not been already created (with
-        // different step), in this case do not add equation "a_m2(0)
-        // = a(-2)"
-		const char* newname;
-		string newname_str;
-		int taux;
-		if (NULL == (newname=as.get_new4old(name, ll-step))) {
-			attemptAuxName(name, ll-step, newname_str);
-			newname = newname_str.c_str();
-			register_uniq_endo(newname);
-			newname = varnames.query(newname);
-			sprintf(tmp, "%s(0)", newname);
-			taux = fp.add_nulary(tmp);
-			// add to substitutions
-			as.add_substitution(newname, name, ll-step);
-
-			// add equation "a_m2(0) = a(-2)", this is taux = tprev
-			fp.add_formula(fp.add_binary(MINUS, taux, tprev));
-		} else {
-			// example: exogenous EPS and occurrence at both EPS(-1)
-			// EPS(+1)
-            // first call makeAuxVariables("EPS",1,1,...) will make endo EPS_p0 = EPS
-            // second call makeAuxVariables("EPS",-1,-1,...) will use this EPS_p0
-			//             to substitute for EPS(-1)
-			taux = index(newname, 0);
-			if (taux < 0)
-				throw ogu::Exception(__FILE__,__LINE__,
-									 "Couldn't find tree index of previously substituted variable");
-		}
-			
-		// create atom "a_m2(-1)" or turn "a(-3)" if any to "a_m2(-1)"; tree index t
-		int t = index(name, ll);
-		if (t == -1) {
-			// no "a(-3)", make t <-> a_m2(-1)
-			sprintf(tmp, "%s(%d)", newname, step);
-			t = fp.add_nulary(tmp);
-		} else {
-			// turn a(-3) to a_m2(-1)
-			unassign_variable(name, ll, t);
-			assign_variable(newname, step, t);
-		}
-
-		// next iteration starts with tprev <-> "a_m2(-1)" (this will be made equal to "a_m3(0)")
-		tprev = t;
-		
-		ll += step;
-	} while (step*ll <= step*limit_lead);
-}
diff --git a/dynare++/parser/cc/atom_substitutions.h b/dynare++/parser/cc/atom_substitutions.hh
similarity index 99%
rename from dynare++/parser/cc/atom_substitutions.h
rename to dynare++/parser/cc/atom_substitutions.hh
index a0e060960d7e3abbdfd73c82bc67ed391d4d99a3..9e44ae4e8171a4a7c6895ec149b0ed4756beae89 100644
--- a/dynare++/parser/cc/atom_substitutions.h
+++ b/dynare++/parser/cc/atom_substitutions.hh
@@ -5,7 +5,7 @@
 #ifndef OGP_ATOM_SUBSTITUTIONS_H
 #define OGP_ATOM_SUBSTITUTIONS_H
 
-#include "fine_atoms.h"
+#include "fine_atoms.hh"
 
 #include <string>
 
diff --git a/dynare++/parser/cc/csv.lex b/dynare++/parser/cc/csv.ll
similarity index 95%
rename from dynare++/parser/cc/csv.lex
rename to dynare++/parser/cc/csv.ll
index a81a277d57a7cb46370517822157dc0b5af6f70c..86adee640e0e31425dad767cbb946cb5f3e3e8d9 100644
--- a/dynare++/parser/cc/csv.lex
+++ b/dynare++/parser/cc/csv.ll
@@ -1,7 +1,7 @@
 %{
 // Copyright (C) 2007-2011, Ondra Kamenik
 
-#include "location.h"
+#include "location.hh"
 #include "csv_tab.hh"
 
 	extern YYLTYPE csv_lloc;
diff --git a/dynare++/parser/cc/csv.y b/dynare++/parser/cc/csv.yy
similarity index 93%
rename from dynare++/parser/cc/csv.y
rename to dynare++/parser/cc/csv.yy
index c0dcfeba5994232bd0f37adae140bfed54d07ba5..09f458ee38c998ada521f7789cb5047ae3fa7277 100644
--- a/dynare++/parser/cc/csv.y
+++ b/dynare++/parser/cc/csv.yy
@@ -1,6 +1,6 @@
 %{
-#include "location.h"
-#include "csv_parser.h"
+#include "location.hh"
+#include "csv_parser.hh"
 #include "csv_tab.hh"
 
 	void csv_error(const char*);
diff --git a/dynare++/parser/cc/csv_parser.cc b/dynare++/parser/cc/csv_parser.cc
new file mode 100644
index 0000000000000000000000000000000000000000..96f6eaf5db405d70034c90fe22b48972f4820bc4
--- /dev/null
+++ b/dynare++/parser/cc/csv_parser.cc
@@ -0,0 +1,44 @@
+#include "csv_parser.hh"
+#include "parser_exception.hh"
+#include "location.hh"
+#include "csv_tab.hh"
+#include <cstring>
+
+using namespace ogp;
+
+/** A global symbol for passing info to the CSVParser from
+ * csv_parse(). */
+CSVParser *csv_parser;
+
+/** The declaration of functions defined in csv_ll.cc and
+ * csv_tab.cc generated from csv.lex and csv.y. */
+void *csv__scan_buffer(char *, unsigned int);
+void csv__destroy_buffer(void *);
+int csv_parse();
+
+extern ogp::location_type csv_lloc;
+
+void
+CSVParser::csv_error(const char *mes)
+{
+  throw ParserException(mes, csv_lloc.off);
+}
+
+void
+CSVParser::csv_parse(int length, const char *str)
+{
+  // allocate temporary buffer and parse
+  char *buffer = new char[length+2];
+  strncpy(buffer, str, length);
+  buffer[length] = '\0';
+  buffer[length+1] = '\0';
+  csv_lloc.off = 0;
+  csv_lloc.ll = 0;
+  parsed_string = buffer;
+  void *p = csv__scan_buffer(buffer, (unsigned int) length+2);
+  csv_parser = this;
+  ::csv_parse();
+  delete [] buffer;
+  csv__destroy_buffer(p);
+  parsed_string = NULL;
+}
diff --git a/dynare++/parser/cc/csv_parser.cpp b/dynare++/parser/cc/csv_parser.cpp
deleted file mode 100644
index 93f6c3374847cf2806e8c759ff1db361c5a7783f..0000000000000000000000000000000000000000
--- a/dynare++/parser/cc/csv_parser.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-#include "csv_parser.h"
-#include "parser_exception.h"
-#include "location.h"
-#include "csv_tab.hh"
-#include <cstring>
-
-using namespace ogp;
-
-/** A global symbol for passing info to the CSVParser from
- * csv_parse(). */
-CSVParser* csv_parser;
-
-/** The declaration of functions defined in csv_ll.cc and
- * csv_tab.cc generated from csv.lex and csv.y. */
-void* csv__scan_buffer(char*, unsigned int);
-void csv__destroy_buffer(void*);
-int csv_parse();
-
-extern ogp::location_type csv_lloc;
-
-void CSVParser::csv_error(const char* mes)
-{
-	throw ParserException(mes, csv_lloc.off);
-}
-
-void CSVParser::csv_parse(int length, const char* str)
-{
-	// allocate temporary buffer and parse
-	char* buffer = new char[length+2];
-	strncpy(buffer, str, length);
-	buffer[length] = '\0';
-	buffer[length+1] = '\0';
-	csv_lloc.off = 0;
-	csv_lloc.ll = 0;
-	parsed_string = buffer;
-	void* p = csv__scan_buffer(buffer, (unsigned int)length+2);
-	csv_parser = this;
-	::csv_parse();
-	delete [] buffer;
-	csv__destroy_buffer(p);
-	parsed_string = NULL;
-}
diff --git a/dynare++/parser/cc/csv_parser.h b/dynare++/parser/cc/csv_parser.hh
similarity index 100%
rename from dynare++/parser/cc/csv_parser.h
rename to dynare++/parser/cc/csv_parser.hh
diff --git a/dynare++/parser/cc/dynamic_atoms.cc b/dynare++/parser/cc/dynamic_atoms.cc
new file mode 100644
index 0000000000000000000000000000000000000000..d8f4241096dd354f9776016876abfb2ddda45f0a
--- /dev/null
+++ b/dynare++/parser/cc/dynamic_atoms.cc
@@ -0,0 +1,710 @@
+// Copyright (C) 2005, Ondra Kamenik
+
+// $Id: dynamic_atoms.cpp 1362 2007-07-10 11:50:18Z kamenik $
+
+#include "utils/cc/exception.hh"
+#include "dynamic_atoms.hh"
+
+#include <cstring>
+#include <climits>
+
+using namespace ogp;
+
+NameStorage::NameStorage(const NameStorage &stor)
+{
+  for (unsigned int i = 0; i < stor.name_store.size(); i++)
+    {
+      char *str = new char[strlen(stor.name_store[i])+1];
+      strcpy(str, stor.name_store[i]);
+      name_store.push_back(str);
+      name_set.insert(str);
+    }
+}
+
+NameStorage::~NameStorage()
+{
+  while (name_store.size() > 0)
+    {
+      delete [] name_store.back();
+      name_store.pop_back();
+    }
+}
+
+const char *
+NameStorage::query(const char *name) const
+{
+  set<const char *, ltstr>::const_iterator it = name_set.find(name);
+  if (it == name_set.end())
+    return NULL;
+  else
+    return (*it);
+}
+
+const char *
+NameStorage::insert(const char *name)
+{
+  set<const char *, ltstr>::const_iterator it = name_set.find(name);
+  if (it == name_set.end())
+    {
+      char *str = new char[strlen(name)+1];
+      strcpy(str, name);
+      name_store.push_back(str);
+      name_set.insert(str);
+      return str;
+    }
+  else
+    {
+      return (*it);
+    }
+}
+
+void
+NameStorage::print() const
+{
+  for (unsigned int i = 0; i < name_store.size(); i++)
+    printf("%s\n", name_store[i]);
+}
+
+void
+Constants::import_constants(const Constants &c, OperationTree &otree, Tintintmap &tmap)
+{
+  for (Tconstantmap::const_iterator it = c.cmap.begin();
+       it != c.cmap.end(); ++it)
+    {
+      int told = (*it).first;
+      int tnew = otree.add_nulary();
+      tmap.insert(Tintintmap::value_type(told, tnew));
+      add_constant(tnew, (*it).second);
+    }
+}
+
+void
+Constants::setValues(EvalTree &et) const
+{
+  Tconstantmap::const_iterator it;
+  for (it = cmap.begin(); it != cmap.end(); ++it)
+    et.set_nulary((*it).first, (*it).second);
+}
+
+void
+Constants::add_constant(int t, double val)
+{
+  cmap.insert(Tconstantmap::value_type(t, val));
+  cinvmap.insert(Tconstantinvmap::value_type(val, t));
+}
+
+bool
+Constants::is_constant(int t) const
+{
+  if (t < OperationTree::num_constants)
+    return true;
+  Tconstantmap::const_iterator it = cmap.find(t);
+  return (it != cmap.end());
+}
+
+double
+Constants::get_constant_value(int t) const
+{
+  Tconstantmap::const_iterator it = cmap.find(t);
+  if (it != cmap.end())
+    return (*it).second;
+  else
+    {
+      throw ogu::Exception(__FILE__, __LINE__,
+                           "Tree index is not constant in Constants::get_constant_value");
+      return 0;
+    }
+}
+
+int
+Constants::check(const char *str) const
+{
+  double d;
+  sscanf(str, "%lf", &d);
+  Tconstantinvmap::const_iterator it = cinvmap.find(d);
+  if (it != cinvmap.end())
+    return (*it).second;
+  else
+    return -1;
+}
+
+void
+Constants::print() const
+{
+  Tconstantmap::const_iterator it;
+  for (it = cmap.begin(); it != cmap.end(); ++it)
+    printf("$%d:  %8.4g\n", (*it).first, (*it).second);
+}
+
+DynamicAtoms::DynamicAtoms()
+  : nv(0), minlag(INT_MAX), maxlead(INT_MIN)
+{
+}
+
+DynamicAtoms::DynamicAtoms(const DynamicAtoms &da)
+  : Constants(da),
+    varnames(da.varnames), vars(), indices(),
+    nv(da.nv), minlag(da.minlag), maxlead(da.maxlead)
+{
+  // copy vars
+  for (Tvarmap::const_iterator it = da.vars.begin();
+       it != da.vars.end(); ++it)
+    vars.insert(Tvarmap::value_type(varnames.query((*it).first),
+                                    (*it).second));
+  // copy indices
+  for (Tindexmap::const_iterator it = da.indices.begin();
+       it != da.indices.end(); ++it)
+    indices.insert(Tindexmap::value_type((*it).first,
+                                         varnames.query((*it).second)));
+}
+
+int
+DynamicAtoms::check(const char *name) const
+{
+  if (is_string_constant(name))
+    return Constants::check(name);
+
+  return check_variable(name);
+}
+
+int
+DynamicAtoms::check_variable(const char *name) const
+{
+  string str;
+  int ll;
+  parse_variable(name, str, ll);
+  Tvarmap::const_iterator it = vars.find(str.c_str());
+
+  if (it != vars.end())
+    {
+      const Tlagmap &lmap = (*it).second;
+      Tlagmap::const_iterator itt = lmap.find(ll);
+      if (itt != lmap.end())
+        return (*itt).second;
+    }
+  return -1;
+}
+
+void
+DynamicAtoms::assign(const char *name, int t)
+{
+  if (is_string_constant(name))
+    assign_constant(name, t);
+  else
+    assign_variable(name, t);
+}
+
+void
+DynamicAtoms::assign_constant(const char *name, int t)
+{
+  double val;
+  sscanf(name, "%lf", &val);
+  add_constant(t, val);
+}
+
+// parse the name and then call assing_variable(varname, ll, t)
+
+void
+DynamicAtoms::assign_variable(const char *name, int t)
+{
+  int ll;
+  string str;
+  parse_variable(name, str, ll);
+  // here str is just name without lead/lag
+  const char *ss = varnames.insert(str.c_str());
+
+  assign_variable(ss, ll, t);
+}
+
+void
+DynamicAtoms::assign_variable(const char *varname, int ll, int t)
+{
+  if (indices.end() != indices.find(t))
+    throw ogu::Exception(__FILE__, __LINE__,
+                         "Attempt to assign already allocated tree index");
+
+  Tvarmap::iterator it = vars.find(varname);
+  if (it != vars.end())
+    {
+      Tlagmap &lmap = (*it).second;
+      if (lmap.end() != lmap.find(ll))
+        throw ogu::Exception(__FILE__, __LINE__,
+                             "Attempt to assign already allocated variable");
+      lmap.insert(Tlagmap::value_type(ll, t));
+    }
+  else
+    {
+      Tlagmap lmap;
+      lmap.insert(Tlagmap::value_type(ll, t));
+      vars.insert(Tvarmap::value_type(varname, lmap));
+    }
+  indices.insert(Tindexmap::value_type(t, varname));
+
+  nv++;
+  if (ll < minlag)
+    minlag = ll;
+  if (ll > maxlead)
+    maxlead = ll;
+}
+
+void
+DynamicAtoms::unassign_variable(const char *varname, int ll, int t)
+{
+  Tvarmap::iterator it = vars.find(varname);
+  if (it != vars.end())
+    {
+      Tlagmap &lmap = (*it).second;
+      Tlagmap::iterator itt = lmap.find(ll);
+      if (itt != lmap.end())
+        {
+          if ((*itt).second == t)
+            {
+              // erase it from the lagmap; if it becomes empty,
+              // erase the lagmap from varmap
+              lmap.erase(itt);
+              if (lmap.size() == 0)
+                vars.erase(it);
+              // erase it from the indices
+              Tindexmap::iterator ittt = indices.find(t);
+              if (ittt != indices.end())
+                indices.erase(ittt);
+
+              nv--;
+              if (ll == minlag || ll == maxlead)
+                update_minmaxll();
+            }
+          else
+            throw ogu::Exception(__FILE__, __LINE__,
+                                 "Tree index inconsistent in DynamicAtoms::unassign_variable");
+        }
+      else
+        throw ogu::Exception(__FILE__, __LINE__,
+                             "Lead/lag of the variable not found in DynamicAtoms::unassign_variable");
+    }
+  else
+    throw ogu::Exception(__FILE__, __LINE__,
+                         "Variable not found in DynamicAtoms::unassign_variable");
+}
+
+void
+DynamicAtoms::update_minmaxll()
+{
+  minlag = INT_MAX;
+  maxlead = INT_MIN;
+  for (Tvarmap::const_iterator it = vars.begin(); it != vars.end(); ++it)
+    {
+      const Tlagmap &lmap = (*it).second;
+      for (Tlagmap::const_iterator itt = lmap.begin(); itt != lmap.end(); ++itt)
+        {
+          int ll = (*itt).first;
+          if (ll < minlag)
+            minlag = ll;
+          if (ll > maxlead)
+            maxlead = ll;
+        }
+    }
+}
+
+vector<int>
+DynamicAtoms::variables() const
+{
+  vector<int> res;
+  for (Tvarmap::const_iterator it = vars.begin();
+       it != vars.end(); ++it)
+    {
+      const Tlagmap &lmap = (*it).second;
+      for (Tlagmap::const_iterator itt = lmap.begin();
+           itt != lmap.end(); ++itt)
+        res.push_back((*itt).second);
+    }
+  return res;
+}
+
+void
+DynamicAtoms::varspan(int t, int &mlead, int &mlag) const
+{
+  Tindexmap::const_iterator it = indices.find(t);
+  if (indices.end() == it)
+    {
+      mlead = INT_MIN;
+      mlag = INT_MAX;
+      return;
+    }
+  varspan((*it).second, mlead, mlag);
+}
+
+void
+DynamicAtoms::varspan(const char *name, int &mlead, int &mlag) const
+{
+  Tvarmap::const_iterator it = vars.find(name);
+  if (vars.end() == it)
+    {
+      mlead = INT_MIN;
+      mlag = INT_MAX;
+      return;
+    }
+  const Tlagmap &lmap = (*it).second;
+  Tlagmap::const_iterator beg = lmap.begin();
+  Tlagmap::const_reverse_iterator end = lmap.rbegin();
+  mlag = (*beg).first;
+  mlead = (*end).first;
+}
+
+void
+DynamicAtoms::varspan(const vector<const char *> &names, int &mlead, int &mlag) const
+{
+  mlead = INT_MIN;
+  mlag = INT_MAX;
+  for (unsigned int i = 0; i < names.size(); i++)
+    {
+      int lag, lead;
+      varspan(names[i], lead, lag);
+      if (lead > mlead)
+        mlead = lead;
+      if (lag < mlag)
+        mlag = lag;
+    }
+}
+
+bool
+DynamicAtoms::is_named_atom(int t) const
+{
+  return (indices.end() != indices.find(t));
+}
+
+int
+DynamicAtoms::index(const char *name, int ll) const
+{
+  Tvarmap::const_iterator it = vars.find(name);
+  if (vars.end() != it)
+    {
+      const Tlagmap &lmap = (*it).second;
+      Tlagmap::const_iterator itt = lmap.find(ll);
+      if (lmap.end() != itt)
+        return (*itt).second;
+    }
+  return -1;
+}
+
+bool
+DynamicAtoms::is_referenced(const char *name) const
+{
+  Tvarmap::const_iterator it = vars.find(name);
+  return it != vars.end();
+}
+
+const DynamicAtoms::Tlagmap &
+DynamicAtoms::lagmap(const char *name) const
+{
+  Tvarmap::const_iterator it = vars.find(name);
+  if (vars.end() == it)
+    throw ogu::Exception(__FILE__, __LINE__,
+                         std::string("Couldn't find the name ")
+                         + name + " in DynamicAtoms::lagmap");
+  return (*it).second;
+}
+
+const char *
+DynamicAtoms::name(int t) const
+{
+  Tindexmap::const_iterator it = indices.find(t);
+  if (indices.end() == it)
+    throw ogu::Exception(__FILE__, __LINE__,
+                         "Couldn't find tree index in DynamicAtoms::name");
+  return (*it).second;
+}
+
+int
+DynamicAtoms::lead(int t) const
+{
+  const char *nam = name(t);
+  const Tlagmap &lmap = lagmap(nam);
+  Tlagmap::const_iterator it = lmap.begin();
+  while (it != lmap.end() && (*it).second != t)
+    ++it;
+  if (lmap.end() == it)
+    throw ogu::Exception(__FILE__, __LINE__,
+                         "Couldn't find the three index in DynamicAtoms::lead");
+  return (*it).first;
+}
+
+void
+DynamicAtoms::print() const
+{
+  printf("names:\n");
+  varnames.print();
+  printf("constants:\n");
+  Constants::print();
+  printf("variables:\n");
+  for (Tvarmap::const_iterator it = vars.begin();
+       it != vars.end(); ++it)
+    {
+      const Tlagmap &lmap = (*it).second;
+      for (Tlagmap::const_iterator itt = lmap.begin();
+           itt != lmap.end(); ++itt)
+        printf("$%d: %s(%d)\n", (*itt).second, (*it).first, (*itt).first);
+    }
+  printf("indices:\n");
+  for (Tindexmap::const_iterator it = indices.begin();
+       it != indices.end(); ++it)
+    printf("t=%d ==> %s\n", (*it).first, (*it).second);
+}
+
+/** Note that the str has been parsed by the lexicographic
+ * analyzer. It can be either a variable or a double. So it is easy to
+ * recognize it by the first character. */
+bool
+DynamicAtoms::is_string_constant(const char *str)
+{
+  return str[0] == '.' || str[0] == '-' || (str[0] >= '0' && str[0] <= '9');
+}
+
+VarOrdering::VarOrdering(const VarOrdering &vo, const vector<const char *> &vnames,
+                         const DynamicAtoms &a)
+  : n_stat(vo.n_stat), n_pred(vo.n_pred), n_both(vo.n_both), n_forw(vo.n_forw),
+    der_atoms(vo.der_atoms), positions(vo.positions),
+    outer2y(vo.outer2y), y2outer(vo.y2outer), varnames(vnames), atoms(a)
+{
+}
+
+bool
+VarOrdering::check(int t) const
+{
+  map<int, int>::const_iterator it = positions.find(t);
+  return it != positions.end();
+}
+
+int
+VarOrdering::get_pos_of(int t) const
+{
+  map<int, int>::const_iterator it = positions.find(t);
+  if (it != positions.end())
+    {
+      return (*it).second;
+    }
+  else
+    {
+      throw ogu::Exception(__FILE__, __LINE__,
+                           "Couldn't find the tree index in VarOrdering::get_pos_of");
+      return -1;
+    }
+}
+
+void
+VarOrdering::do_general(ord_type ordering)
+{
+  // auxiliary vectors for setting der_atoms and map
+  vector<int> pred_minus;
+  vector<int> both_minus;
+  vector<int> stat;
+  vector<int> pred_pad;
+  vector<int> both_pad;
+  vector<int> forw_pad;
+  vector<int> both_plus;
+  vector<int> forw_plus;
+
+  // auxiliary vectors for setting y2outer and outer2y
+  vector<int> y2o_stat;
+  vector<int> y2o_pred;
+  vector<int> y2o_both;
+  vector<int> y2o_forw;
+
+  for (unsigned int i = 0; i < varnames.size(); i++)
+    {
+      const char *ss = varnames[i];
+      int lead;
+      int lag;
+      atoms.varspan(ss, lead, lag);
+      if (lag == 0 && lead == 0)
+        {
+          stat.push_back(atoms.index(ss, 0));
+          y2o_stat.push_back(i);
+        }
+      else if (lag == -1 && lead < 1)
+        {
+          pred_minus.push_back(atoms.index(ss, -1));
+          pred_pad.push_back(atoms.index(ss, 0));
+          y2o_pred.push_back(i);
+        }
+      else if (lag > -1 && lead == 1)
+        {
+          forw_pad.push_back(atoms.index(ss, 0));
+          forw_plus.push_back(atoms.index(ss, 1));
+          y2o_forw.push_back(i);
+        }
+      else if (lag == -1 && lead == 1)
+        {
+          both_minus.push_back(atoms.index(ss, -1));
+          both_pad.push_back(atoms.index(ss, 0));
+          both_plus.push_back(atoms.index(ss, 1));
+          y2o_both.push_back(i);
+        }
+      else
+        {
+          throw ogu::Exception(__FILE__, __LINE__,
+                               "A wrong lag/lead of a variable in VarOrdering::do_pbspbfbf");
+        }
+    }
+
+  // here we fill ords according to ordering
+  vector<int> *ords[8];
+  if (ordering == pbspbfbf)
+    {
+      ords[0] = &pred_minus;
+      ords[1] = &both_minus;
+      ords[2] = &stat;
+      ords[3] = &pred_pad;
+      ords[4] = &both_pad;
+      ords[5] = &forw_pad;
+      ords[6] = &both_plus;
+      ords[7] = &forw_plus;
+    }
+  else if (ordering == bfspbfpb)
+    {
+      ords[0] = &both_plus;
+      ords[1] = &forw_plus;
+      ords[2] = &stat;
+      ords[3] = &pred_pad;
+      ords[4] = &both_pad;
+      ords[5] = &forw_pad;
+      ords[6] = &pred_minus;
+      ords[7] = &both_minus;
+    }
+  else // BEWARE: when implementing a new ordering, check also a
+    {// code below setting y2outer
+      throw ogu::Exception(__FILE__, __LINE__,
+                           "Ordering not implemented in VarOrdering::do_general");
+    }
+
+  // make der_atoms and positions
+  int off = 0;
+  for (unsigned int i = 0; i < 8; i++)
+    for (unsigned int j = 0; j < (ords[i])->size(); j++, off++)
+      if ((*(ords[i]))[j] != -1)
+        {
+          der_atoms.push_back((*(ords[i]))[j]);
+          positions.insert(std::pair<int, int>((*(ords[i]))[j], off));
+        }
+
+  // set integer constants
+  n_stat = stat.size();
+  n_pred = pred_pad.size();
+  n_both = both_pad.size();
+  n_forw = forw_pad.size();
+
+  // make y2outer mapping
+  y2outer.insert(y2outer.end(), y2o_stat.begin(), y2o_stat.end());
+  y2outer.insert(y2outer.end(), y2o_pred.begin(), y2o_pred.end());
+  y2outer.insert(y2outer.end(), y2o_both.begin(), y2o_both.end());
+  y2outer.insert(y2outer.end(), y2o_forw.begin(), y2o_forw.end());
+  // make outer2y mapping
+  outer2y.resize(y2outer.size(), -1);
+  for (unsigned int i = 0; i < y2outer.size(); i++)
+    outer2y[y2outer[i]] = i;
+}
+
+void
+VarOrdering::do_increasing_time()
+{
+  // get maxlead and minlag of the variables
+  int mlag, mlead;
+  atoms.varspan(varnames, mlead, mlag);
+  // setup the matrix of tree indices, if there is no occurrence,
+  // the index is set to -1
+  vector<int> ll_init(varnames.size(), -1);
+  vector<vector<int> > tree_ind(mlead-mlag+1, ll_init);
+  for (unsigned int iv = 0; iv < varnames.size(); iv++)
+    {
+      try
+        {
+          const DynamicAtoms::Tlagmap &lmap = atoms.lagmap(varnames[iv]);
+          for (DynamicAtoms::Tlagmap::const_iterator it = lmap.begin();
+               it != lmap.end(); ++it)
+            {
+              int ll = (*it).first;
+              int t = (*it).second;
+              tree_ind[ll-mlag][iv] = t;
+            }
+        }
+      catch (const ogu::Exception &e)
+        {
+          // ignore the error of not found variable in the tree
+        }
+    }
+
+  // setup der_atoms and positions
+  for (int ll = mlag; ll <= mlead; ll++)
+    for (unsigned int iv = 0; iv < varnames.size(); iv++)
+      {
+        int t = tree_ind[ll-mlag][iv];
+        if (t != -1)
+          {
+            der_atoms.push_back(t);
+            int pos = (ll-mlag)*varnames.size() + iv;
+            positions.insert(map<int, int>::value_type(t, pos));
+          }
+      }
+
+  // set outer2y and y2outer to identities
+  for (unsigned int iv = 0; iv < varnames.size(); iv++)
+    {
+      outer2y.push_back(iv);
+      y2outer.push_back(iv);
+    }
+
+  // set n_stat, n_pred, n_both, and n_forw
+  for (unsigned int iv = 0; iv < varnames.size(); iv++)
+    {
+      int mmlag, mmlead;
+      atoms.varspan(varnames[iv], mmlead, mmlag);
+      if (mmlead == 0 && mmlag == 0)
+        {
+          n_stat++;
+        }
+      else if (mmlead <= 0 && mmlag < 0)
+        {
+          n_pred++;
+        }
+      else if (mmlead > 0 && mmlag >= 0)
+        {
+          n_forw++;
+        }
+      else if (mmlead > 0 && mmlag < 0)
+        {
+          n_both++;
+        }
+      else if (mmlead < mmlag)
+        {
+          // variable does not occur in the tree, cound as static
+          n_stat++;
+        }
+      else
+        {
+          throw ogu::Exception(__FILE__, __LINE__,
+                               "A wrong lag/lead of a variable in VarOrdering::do_increasing_time");
+        }
+    }
+}
+
+void
+VarOrdering::print() const
+{
+  printf("nstat=%d, npred=%d, nboth=%d, nforw=%d\n", n_stat, n_pred, n_both, n_forw);
+  printf("der_atoms:\n");
+  for (unsigned int i = 0; i < der_atoms.size(); i++)
+    printf(" %d", der_atoms[i]);
+  printf("\nmap:\n");
+  for (map<int, int>::const_iterator it = positions.begin(); it != positions.end(); ++it)
+    printf(" [%d->%d]", (*it).first, (*it).second);
+  printf("\ny2outer:\n");
+  for (unsigned int i = 0; i < y2outer.size(); i++)
+    printf(" %d", y2outer[i]);
+  printf("\nouter2y:\n");
+  for (unsigned int i = 0; i < outer2y.size(); i++)
+    printf(" %d", outer2y[i]);
+  printf("\n");
+}
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/dynare++/parser/cc/dynamic_atoms.cpp b/dynare++/parser/cc/dynamic_atoms.cpp
deleted file mode 100644
index ca6b6dcd219158d9faf22f76da01c2c5ea460332..0000000000000000000000000000000000000000
--- a/dynare++/parser/cc/dynamic_atoms.cpp
+++ /dev/null
@@ -1,615 +0,0 @@
-// Copyright (C) 2005, Ondra Kamenik
-
-// $Id: dynamic_atoms.cpp 1362 2007-07-10 11:50:18Z kamenik $
-
-#include "utils/cc/exception.h"
-#include "dynamic_atoms.h"
-
-#include <cstring>
-#include <climits>
-
-using namespace ogp;
-
-NameStorage::NameStorage(const NameStorage& stor)
-{
-	for (unsigned int i = 0; i < stor.name_store.size(); i++) {
-		char* str = new char[strlen(stor.name_store[i])+1];
-		strcpy(str, stor.name_store[i]);
-		name_store.push_back(str);
-		name_set.insert(str);
-	}
-}
-
-NameStorage::~NameStorage()
-{
-	while (name_store.size() > 0) {
-		delete [] name_store.back();
-		name_store.pop_back();
-	}
-}
-
-const char* NameStorage::query(const char* name) const
-{
-	set<const char*, ltstr>::const_iterator it = name_set.find(name);
-	if (it == name_set.end())
-		return NULL;
-	else
-		return (*it);
-}
-
-const char* NameStorage::insert(const char* name)
-{
-	set<const char*, ltstr>::const_iterator it = name_set.find(name);
-	if (it == name_set.end()) {
-		char* str = new char[strlen(name)+1];
-		strcpy(str, name);
-		name_store.push_back(str);
-		name_set.insert(str);
-		return str;
-	} else {
-		return (*it);
-	}
-}
-
-void NameStorage::print() const
-{
-	for (unsigned int i = 0; i < name_store.size(); i++)
-		printf("%s\n", name_store[i]);
-}
-
-void Constants::import_constants(const Constants& c, OperationTree& otree, Tintintmap& tmap)
-{
-	for (Tconstantmap::const_iterator it = c.cmap.begin();
-		 it != c.cmap.end(); ++it) {
-		int told = (*it).first;
-		int tnew = otree.add_nulary();
-		tmap.insert(Tintintmap::value_type(told, tnew));
-		add_constant(tnew, (*it).second);
-	}
-}
-
-void Constants::setValues(EvalTree& et) const
-{
-	Tconstantmap::const_iterator it;
-	for (it = cmap.begin(); it != cmap.end(); ++it)
-		et.set_nulary((*it).first, (*it).second);
-}
-
-void Constants::add_constant(int t, double val)
-{
-	cmap.insert(Tconstantmap::value_type(t, val));
-	cinvmap.insert(Tconstantinvmap::value_type(val, t));
-}
-
-bool Constants::is_constant(int t) const
-{
-	if (t < OperationTree::num_constants)
-		return true;
-	Tconstantmap::const_iterator it = cmap.find(t);
-	return (it != cmap.end());
-}
-
-double Constants::get_constant_value(int t) const
-{
-	Tconstantmap::const_iterator it = cmap.find(t);
-	if (it != cmap.end())
-		return (*it).second;
-	else {
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "Tree index is not constant in Constants::get_constant_value");
-		return 0;
-	}
-}
-
-int Constants::check(const char* str) const
-{
-	double d;
-	sscanf(str, "%lf", &d);
- 	Tconstantinvmap::const_iterator it = cinvmap.find(d);
- 	if (it != cinvmap.end())
- 		return (*it).second;
- 	else
- 		return -1;
-}
-
-void Constants::print() const
-{
-	Tconstantmap::const_iterator it;
-	for (it = cmap.begin(); it != cmap.end(); ++it)
-		printf("$%d:  %8.4g\n", (*it).first, (*it).second);
-}
-
-
-DynamicAtoms::DynamicAtoms()
-	: nv(0), minlag(INT_MAX), maxlead(INT_MIN)
-{
-}
-
-DynamicAtoms::DynamicAtoms(const DynamicAtoms& da)
-	: Constants(da),
-	  varnames(da.varnames), vars(), indices(),
-	  nv(da.nv), minlag(da.minlag), maxlead(da.maxlead)
-{
-	// copy vars
-	for (Tvarmap::const_iterator it = da.vars.begin();
-		 it != da.vars.end(); ++it)
-		vars.insert(Tvarmap::value_type(varnames.query((*it).first),
-										(*it).second));
-	// copy indices
-	for (Tindexmap::const_iterator it = da.indices.begin();
-		 it != da.indices.end(); ++it)
-		indices.insert(Tindexmap::value_type((*it).first,
-											 varnames.query((*it).second)));
-}
-
-
-int DynamicAtoms::check(const char* name) const
-{
-	if (is_string_constant(name))
-		return Constants::check(name);
-
-	return check_variable(name);
-}
-
-int DynamicAtoms::check_variable(const char* name) const
-{
-	string str;
-	int ll;
-	parse_variable(name, str, ll);
-	Tvarmap::const_iterator it = vars.find(str.c_str());
-
-	if (it != vars.end()) {
-		const Tlagmap& lmap = (*it).second;
-		Tlagmap::const_iterator itt = lmap.find(ll);
-		if (itt != lmap.end())
-			return (*itt).second;
-	}
-	return -1;
-}
-
-
-void DynamicAtoms::assign(const char* name, int t)
-{
-	if (is_string_constant(name))
-		assign_constant(name, t);
-	else
-		assign_variable(name, t);
-}
-
-void DynamicAtoms::assign_constant(const char* name, int t)
-{
-	double val;
-	sscanf(name, "%lf", &val);
-	add_constant(t, val);
-}
-
-// parse the name and then call assing_variable(varname, ll, t)
-
-void DynamicAtoms::assign_variable(const char* name, int t)
-{
-	int ll;
-	string str;
-	parse_variable(name, str, ll);
-	// here str is just name without lead/lag
-	const char* ss = varnames.insert(str.c_str());
-
-	assign_variable(ss, ll, t);
-}
-
-void DynamicAtoms::assign_variable(const char* varname, int ll, int t)
-{
-	if (indices.end() != indices.find(t))
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "Attempt to assign already allocated tree index");
-
-	Tvarmap::iterator it = vars.find(varname);
-	if (it != vars.end()) {
-		Tlagmap& lmap = (*it).second;
-		if (lmap.end() != lmap.find(ll))
-			throw ogu::Exception(__FILE__,__LINE__,
-								 "Attempt to assign already allocated variable");
-		lmap.insert(Tlagmap::value_type(ll, t));
-	} else {
-		Tlagmap lmap;
-		lmap.insert(Tlagmap::value_type(ll, t));
-		vars.insert(Tvarmap::value_type(varname, lmap));
-	}
-	indices.insert(Tindexmap::value_type(t, varname));
-
-	nv++;
-	if (ll < minlag)
-		minlag = ll;
-	if (ll > maxlead)
-		maxlead = ll;	
-}
-
-void DynamicAtoms::unassign_variable(const char* varname, int ll, int t)
-{
-	Tvarmap::iterator it = vars.find(varname);
-	if (it != vars.end()) {
-		Tlagmap& lmap = (*it).second;
-		Tlagmap::iterator itt = lmap.find(ll);
-		if (itt != lmap.end()) {
-			if ((*itt).second == t) {
-				// erase it from the lagmap; if it becomes empty,
-				// erase the lagmap from varmap
-				lmap.erase(itt);
-				if (lmap.size() == 0)
-					vars.erase(it);
-				// erase it from the indices
-				Tindexmap::iterator ittt = indices.find(t);
-				if (ittt != indices.end())
-					indices.erase(ittt);
-
-				nv--;
-				if (ll == minlag || ll == maxlead)
-					update_minmaxll();
-			} else
-				throw ogu::Exception(__FILE__,__LINE__,
-									 "Tree index inconsistent in DynamicAtoms::unassign_variable");
-		} else
-			throw ogu::Exception(__FILE__,__LINE__,
-								 "Lead/lag of the variable not found in DynamicAtoms::unassign_variable");
-	} else
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "Variable not found in DynamicAtoms::unassign_variable");
-}
-
-void DynamicAtoms::update_minmaxll()
-{
-	minlag = INT_MAX;
-	maxlead =INT_MIN;
-	for (Tvarmap::const_iterator it = vars.begin(); it != vars.end(); ++it) {
-		const Tlagmap& lmap = (*it).second;
-		for (Tlagmap::const_iterator itt = lmap.begin(); itt != lmap.end(); ++itt) {
-			int ll = (*itt).first;
-			if (ll < minlag)
-				minlag = ll;
-			if (ll > maxlead)
-				maxlead = ll;
-		}
-	}	
-}
-
-vector<int> DynamicAtoms::variables() const
-{
-	vector<int> res;
-	for (Tvarmap::const_iterator it = vars.begin();
-		 it != vars.end(); ++it) {
-		const Tlagmap& lmap = (*it).second;
-		for (Tlagmap::const_iterator itt = lmap.begin();
-			 itt != lmap.end(); ++itt)
-			res.push_back((*itt).second);
-	}
-	return res;
-}
-
-void DynamicAtoms::varspan(int t, int& mlead, int& mlag) const
-{
-	Tindexmap::const_iterator it = indices.find(t);
-	if (indices.end() == it) {
-		mlead = INT_MIN;
-		mlag = INT_MAX;
-		return;
-	}
-	varspan((*it).second, mlead, mlag);
-}
-
-void DynamicAtoms::varspan(const char* name, int& mlead, int& mlag) const
-{
-	Tvarmap::const_iterator it = vars.find(name);
-	if (vars.end() == it) {
-		mlead = INT_MIN;
-		mlag = INT_MAX;
-		return;
-	}
-	const Tlagmap& lmap = (*it).second;
-	Tlagmap::const_iterator beg = lmap.begin();
-	Tlagmap::const_reverse_iterator end = lmap.rbegin();
-	mlag = (*beg).first;
-	mlead = (*end).first;
-}
-
-void DynamicAtoms::varspan(const vector<const char*>& names, int& mlead, int& mlag) const
-{
-	mlead = INT_MIN;
-	mlag = INT_MAX;
-	for (unsigned int i = 0; i < names.size(); i++) {
-		int lag, lead;
-		varspan(names[i], lead, lag);
-		if (lead > mlead)
-			mlead = lead;
-		if (lag < mlag)
-			mlag = lag;
-	}
-}
-
-bool DynamicAtoms::is_named_atom(int t) const
-{
-	return (indices.end() != indices.find(t));
-}
-
-int DynamicAtoms::index(const char* name, int ll) const
-{
-	Tvarmap::const_iterator it = vars.find(name);
-	if (vars.end() != it) {
-		const Tlagmap& lmap = (*it).second;
-		Tlagmap::const_iterator itt = lmap.find(ll);
-		if (lmap.end() != itt)
-			return (*itt).second;
-	}
-	return -1;
-}
-
-bool DynamicAtoms::is_referenced(const char* name) const
-{
-	Tvarmap::const_iterator it = vars.find(name);
-	return it != vars.end();
-}
-
-const DynamicAtoms::Tlagmap& DynamicAtoms::lagmap(const char* name) const
-{
-	Tvarmap::const_iterator it = vars.find(name);
-	if (vars.end() == it)
-		throw ogu::Exception(__FILE__,__LINE__,
-							 std::string("Couldn't find the name ")
-							 + name + " in DynamicAtoms::lagmap");
-	return (*it).second;
-}
-
-const char* DynamicAtoms::name(int t) const
-{
-	Tindexmap::const_iterator it = indices.find(t);
-	if (indices.end() == it)
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "Couldn't find tree index in DynamicAtoms::name");
-	return (*it).second;
-}
-
-int DynamicAtoms::lead(int t) const
-{
-	const char* nam = name(t);
-	const Tlagmap& lmap = lagmap(nam);
-	Tlagmap::const_iterator it = lmap.begin();
-	while (it != lmap.end() && (*it).second != t)
-		++it;
-	if (lmap.end() == it)
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "Couldn't find the three index in DynamicAtoms::lead");
-	return (*it).first;
-}
-
-void DynamicAtoms::print() const
-{
-	printf("names:\n");
-	varnames.print();
-	printf("constants:\n");
-	Constants::print();
-	printf("variables:\n");
-	for (Tvarmap::const_iterator it = vars.begin();
-		 it != vars.end(); ++it) {
-		const Tlagmap& lmap = (*it).second;
-		for (Tlagmap::const_iterator itt = lmap.begin();
-			 itt != lmap.end(); ++itt)
-			printf("$%d: %s(%d)\n", (*itt).second, (*it).first, (*itt).first);
-	}
-	printf("indices:\n");
-	for (Tindexmap::const_iterator it = indices.begin();
-		 it != indices.end(); ++it)
-		printf("t=%d ==> %s\n", (*it).first, (*it).second);
-}
-
-/** Note that the str has been parsed by the lexicographic
- * analyzer. It can be either a variable or a double. So it is easy to
- * recognize it by the first character. */
-bool DynamicAtoms::is_string_constant(const char* str)
-{
-	return str[0] == '.' || str[0] == '-' || (str[0] >= '0' && str[0] <= '9');
-}
-
-VarOrdering::VarOrdering(const VarOrdering& vo, const vector<const char*>& vnames,
-						 const DynamicAtoms& a)
-	: n_stat(vo.n_stat), n_pred(vo.n_pred), n_both(vo.n_both), n_forw(vo.n_forw),
-	  der_atoms(vo.der_atoms), positions(vo.positions),
-	  outer2y(vo.outer2y), y2outer(vo.y2outer), varnames(vnames), atoms(a)
-{
-}
-
-bool VarOrdering::check(int t) const
-{
-	map<int,int>::const_iterator it = positions.find(t);
-	return it != positions.end();
-}
-
-int VarOrdering::get_pos_of(int t) const
-{
-	map<int,int>::const_iterator it = positions.find(t);
-	if (it != positions.end()) {
-		return (*it).second;
-	} else {
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "Couldn't find the tree index in VarOrdering::get_pos_of");
-		return -1;
-	}
-}
-
-void VarOrdering::do_general(ord_type ordering)
-{
-	// auxiliary vectors for setting der_atoms and map
-	vector<int> pred_minus;
-	vector<int> both_minus;
-	vector<int> stat;
-	vector<int> pred_pad;
-	vector<int> both_pad;
-	vector<int> forw_pad;
-	vector<int> both_plus;
-	vector<int> forw_plus;
-
-	// auxiliary vectors for setting y2outer and outer2y 
-	vector<int> y2o_stat;
-	vector<int> y2o_pred;
-	vector<int> y2o_both;
-	vector<int> y2o_forw;
-
-	for (unsigned int i = 0; i < varnames.size(); i++) {
-		const char* ss = varnames[i];
-		int lead;
-		int lag;
-		atoms.varspan(ss, lead, lag);
-		if (lag == 0 && lead == 0) {
-			stat.push_back(atoms.index(ss, 0));
-			y2o_stat.push_back(i);
-		} else if (lag == -1 && lead < 1) {
-			pred_minus.push_back(atoms.index(ss, -1));
-			pred_pad.push_back(atoms.index(ss, 0));
-			y2o_pred.push_back(i);
-		} else if (lag > -1 && lead == 1) {
-			forw_pad.push_back(atoms.index(ss, 0));
-			forw_plus.push_back(atoms.index(ss, 1));
-			y2o_forw.push_back(i);
-		} else if (lag == -1 && lead == 1) {
-			both_minus.push_back(atoms.index(ss, -1));
-			both_pad.push_back(atoms.index(ss, 0));
-			both_plus.push_back(atoms.index(ss, 1));
-			y2o_both.push_back(i);
-		} else {
-			throw ogu::Exception(__FILE__,__LINE__,
-								 "A wrong lag/lead of a variable in VarOrdering::do_pbspbfbf");
-		}			
-	}
-
-	// here we fill ords according to ordering
-	vector<int>* ords[8];
-	if (ordering == pbspbfbf) {
-		ords[0] = &pred_minus;
-		ords[1] = &both_minus;
-		ords[2] = &stat;
-		ords[3] = &pred_pad;
-		ords[4] = &both_pad;
-		ords[5] = &forw_pad;
-		ords[6] = &both_plus;
-		ords[7] = &forw_plus;
-	} else if (ordering == bfspbfpb) {
-		ords[0] = &both_plus;
-		ords[1] = &forw_plus;
-		ords[2] = &stat;
-		ords[3] = &pred_pad;
-		ords[4] = &both_pad;
-		ords[5] = &forw_pad;
-		ords[6] = &pred_minus;
-		ords[7] = &both_minus;
-	} else { // BEWARE: when implementing a new ordering, check also a
-			 // code below setting y2outer
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "Ordering not implemented in VarOrdering::do_general");		
-	}
-
-	// make der_atoms and positions
-	int off = 0;
-	for (unsigned int i = 0; i < 8; i++)
-		for (unsigned int j = 0; j < (ords[i])->size(); j++, off++)
-			if ((*(ords[i]))[j] != -1) {
-				der_atoms.push_back((*(ords[i]))[j]);
-				positions.insert(std::pair<int,int>((*(ords[i]))[j], off));
-			}
-
-	// set integer constants
-	n_stat = stat.size();
-	n_pred = pred_pad.size();
-	n_both = both_pad.size();
-	n_forw = forw_pad.size();
-
-	// make y2outer mapping
-	y2outer.insert(y2outer.end(), y2o_stat.begin(), y2o_stat.end());
-	y2outer.insert(y2outer.end(), y2o_pred.begin(), y2o_pred.end());
-	y2outer.insert(y2outer.end(), y2o_both.begin(), y2o_both.end());
-	y2outer.insert(y2outer.end(), y2o_forw.begin(), y2o_forw.end());
-	// make outer2y mapping
-	outer2y.resize(y2outer.size(), -1);
-	for (unsigned int i = 0; i < y2outer.size(); i++)
-		outer2y[y2outer[i]] = i;
-}
-
-void VarOrdering::do_increasing_time()
-{
-	// get maxlead and minlag of the variables
-	int mlag, mlead;
-	atoms.varspan(varnames, mlead, mlag);
-	// setup the matrix of tree indices, if there is no occurrence,
-	// the index is set to -1
-	vector<int> ll_init(varnames.size(), -1);
-	vector<vector<int> > tree_ind(mlead-mlag+1, ll_init);
-	for (unsigned int iv = 0; iv < varnames.size(); iv++) {
-		try {
-			const DynamicAtoms::Tlagmap& lmap = atoms.lagmap(varnames[iv]);
-			for (DynamicAtoms::Tlagmap::const_iterator it = lmap.begin();
-				 it != lmap.end(); ++it) {
-				int ll = (*it).first;
-				int t = (*it).second;
-				tree_ind[ll-mlag][iv] = t;
-			}
-		} catch (const ogu::Exception& e) {
-			// ignore the error of not found variable in the tree
-		}
-	}
-
-	// setup der_atoms and positions
-	for (int ll = mlag; ll <= mlead; ll++)
-		for (unsigned int iv = 0; iv < varnames.size(); iv++) {
-			int t = tree_ind[ll-mlag][iv];
-			if (t != -1) {
-				der_atoms.push_back(t);
-				int pos = (ll-mlag)*varnames.size() + iv;
-				positions.insert(map<int,int>::value_type(t, pos));
-			}
-		}
-
-	// set outer2y and y2outer to identities
-	for (unsigned int iv = 0; iv < varnames.size(); iv++) {
-		outer2y.push_back(iv);
-		y2outer.push_back(iv);
-	}
-
-	// set n_stat, n_pred, n_both, and n_forw
-	for (unsigned int iv = 0; iv < varnames.size(); iv++) {
-		int mmlag, mmlead;
-		atoms.varspan(varnames[iv], mmlead, mmlag);
-		if (mmlead == 0 && mmlag == 0) {
-			n_stat++;
-		} else if (mmlead <= 0 && mmlag < 0) {
-			n_pred++;
-		} else if (mmlead > 0 && mmlag >=0) {
-			n_forw++;
-		} else if (mmlead > 0 && mmlag < 0) {
-			n_both++;
-		} else if (mmlead < mmlag) {
-			// variable does not occur in the tree, cound as static
-			n_stat++;
-		} else {
-			throw ogu::Exception(__FILE__,__LINE__,
-								 "A wrong lag/lead of a variable in VarOrdering::do_increasing_time");
-		}
-	}
-}
-
-void VarOrdering::print() const
-{
-	printf("nstat=%d, npred=%d, nboth=%d, nforw=%d\n", n_stat, n_pred, n_both, n_forw);
-	printf("der_atoms:\n");
-	for (unsigned int i = 0; i < der_atoms.size(); i++)
-		printf(" %d", der_atoms[i]);
-	printf("\nmap:\n");
-	for (map<int,int>::const_iterator it = positions.begin(); it != positions.end(); ++it)
-		printf(" [%d->%d]", (*it).first, (*it).second);
-	printf("\ny2outer:\n");
-	for (unsigned int i = 0; i < y2outer.size(); i++)
-		printf(" %d", y2outer[i]);
-	printf("\nouter2y:\n");
-	for (unsigned int i = 0; i < outer2y.size(); i++)
-		printf(" %d", outer2y[i]);
-	printf("\n");
-}
-
-// Local Variables:
-// mode:C++
-// End:
diff --git a/dynare++/parser/cc/dynamic_atoms.h b/dynare++/parser/cc/dynamic_atoms.hh
similarity index 99%
rename from dynare++/parser/cc/dynamic_atoms.h
rename to dynare++/parser/cc/dynamic_atoms.hh
index cf28da2ef67b5e74b9125919c6bc251881d09a21..e4dd3714c643979cb6a8f60877c24bdc36f4ae86 100644
--- a/dynare++/parser/cc/dynamic_atoms.h
+++ b/dynare++/parser/cc/dynamic_atoms.hh
@@ -5,7 +5,7 @@
 #ifndef OGP_DYNAMIC_ATOMS_H
 #define OGP_DYNAMIC_ATOMS_H
 
-#include "formula_parser.h"
+#include "formula_parser.hh"
 
 #include <vector>
 #include <map>
diff --git a/dynare++/parser/cc/fine_atoms.cc b/dynare++/parser/cc/fine_atoms.cc
new file mode 100644
index 0000000000000000000000000000000000000000..2080452f837caf5348564a8bb58136fdfc73997a
--- /dev/null
+++ b/dynare++/parser/cc/fine_atoms.cc
@@ -0,0 +1,555 @@
+// Copyright (C) 2005, Ondra Kamenik
+
+// $Id: fine_atoms.cpp 1759 2008-03-31 14:25:20Z kamenik $
+
+#include "utils/cc/exception.hh"
+
+#include "parser_exception.hh"
+#include "fine_atoms.hh"
+
+using namespace ogp;
+
+AllvarOuterOrdering::AllvarOuterOrdering(const vector<const char *> &allvar_outer,
+                                         const FineAtoms &a)
+  : atoms(a), allvar(),
+    endo2all(a.get_endovars().size(), -1),
+    exo2all(a.get_exovars().size(), -1)
+{
+  // fill in the allvar from allvar_outer
+  for (unsigned int i = 0; i < allvar_outer.size(); i++)
+    {
+      const char *s = atoms.varnames.query(allvar_outer[i]);
+      if (s)
+        allvar.push_back(s);
+      else
+        throw ogu::Exception(__FILE__, __LINE__,
+                             string("Variable ") + allvar_outer[i] + " is not a declared symbol in AllvarOuterOrdering constructor");
+    }
+
+  // fill in endo2all and exo2all
+  for (unsigned int i = 0; i < allvar.size(); i++)
+    {
+      Tvarintmap::const_iterator it = atoms.endo_outer_map.find(allvar[i]);
+      if (it != atoms.endo_outer_map.end())
+        endo2all[(*it).second] = i;
+      else
+        {
+          it = atoms.exo_outer_map.find(allvar[i]);
+          if (it != atoms.exo_outer_map.end())
+            exo2all[(*it).second] = i;
+          else
+            throw ogu::Exception(__FILE__, __LINE__,
+                                 string("Name ") + allvar[i] + " is neither endogenous nor exogenous variable in AllvarOuterOrdering constructor");
+        }
+    }
+
+  // check whether everything has been filled
+  unsigned int iendo = 0;
+  while (iendo < endo2all.size() && endo2all[iendo] != -1)
+    iendo++;
+  unsigned int iexo = 0;
+  while (iexo < exo2all.size() && exo2all[iexo] != -1)
+    iexo++;
+  if (iendo < endo2all.size())
+    throw ogu::Exception(__FILE__, __LINE__,
+                         string("Endogenous variable ") + atoms.get_endovars()[iendo]
+                         +" not found in outer all ordering in AllvarOuterOrdering constructor");
+  if (iexo < exo2all.size())
+    throw ogu::Exception(__FILE__, __LINE__,
+                         string("Exogenous variable ") + atoms.get_exovars()[iexo]
+                         +" not found in outer all ordering in AllvarOuterOrdering constructor");
+}
+
+AllvarOuterOrdering::AllvarOuterOrdering(const AllvarOuterOrdering &avo,
+                                         const FineAtoms &a)
+  : atoms(a), allvar(),
+    endo2all(avo.endo2all),
+    exo2all(avo.exo2all)
+{
+  // fill in the allvar from avo.allvar
+  for (unsigned int i = 0; i < avo.allvar.size(); i++)
+    {
+      const char *s = atoms.varnames.query(avo.allvar[i]);
+      allvar.push_back(s);
+    }
+}
+
+FineAtoms::FineAtoms(const FineAtoms &fa)
+  : DynamicAtoms(fa), params(), endovars(), exovars(),
+    endo_order(NULL), exo_order(NULL), allvar_order(NULL),
+    der_atoms(fa.der_atoms),
+    endo_atoms_map(fa.endo_atoms_map),
+    exo_atoms_map(fa.exo_atoms_map)
+{
+  // fill in params
+  for (unsigned int i = 0; i < fa.params.size(); i++)
+    {
+      const char *s = varnames.query(fa.params[i]);
+      if (!s)
+        throw ogu::Exception(__FILE__, __LINE__,
+                             string("Parameter ") + fa.params[i] + " does not exist in FineAtoms copy cosntructor");
+      params.push_back(s);
+      param_outer_map.insert(Tvarintmap::value_type(s, params.size()-1));
+    }
+  // fill in endovars
+  for (unsigned int i = 0; i < fa.endovars.size(); i++)
+    {
+      const char *s = varnames.query(fa.endovars[i]);
+      if (!s)
+        throw ogu::Exception(__FILE__, __LINE__,
+                             string("Endo variable ") + fa.endovars[i] + " does not exist in FineAtoms copy constructor");
+      endovars.push_back(s);
+      endo_outer_map.insert(Tvarintmap::value_type(s, endovars.size()-1));
+    }
+  // fill in exovars
+  for (unsigned int i = 0; i < fa.exovars.size(); i++)
+    {
+      const char *s = varnames.query(fa.exovars[i]);
+      if (!s)
+        throw ogu::Exception(__FILE__, __LINE__,
+                             string("Exo variable ") + fa.exovars[i] + " does not exist in FineAtoms copy cosntructor");
+      exovars.push_back(s);
+      exo_outer_map.insert(Tvarintmap::value_type(s, exovars.size()-1));
+    }
+
+  if (fa.endo_order)
+    endo_order = fa.endo_order->clone(endovars, *this);
+
+  if (fa.exo_order)
+    exo_order = fa.exo_order->clone(exovars, *this);
+
+  if (fa.allvar_order)
+    allvar_order = new AllvarOuterOrdering(*(fa.allvar_order), *this);
+}
+
+int
+FineAtoms::check_variable(const char *name) const
+{
+  string str;
+  int ll;
+  parse_variable(name, str, ll);
+  if (varnames.query(str.c_str()))
+    return DynamicAtoms::check_variable(name);
+  else
+    {
+      throw ParserException(string("Variable <")+str+"> not declared.", 0);
+      return -1;
+    }
+}
+
+int
+FineAtoms::num_exo_periods() const
+{
+  int mlead, mlag;
+  exovarspan(mlead, mlag);
+  return mlead-mlag+1;
+}
+
+void
+FineAtoms::parsing_finished(VarOrdering::ord_type ot)
+{
+  make_internal_orderings(ot);
+
+  // by default, concatenate outer endo and outer exo and make it as
+  // allvar outer:
+  vector<const char *> allvar_tmp;
+  allvar_tmp.insert(allvar_tmp.end(), endovars.begin(), endovars.end());
+  allvar_tmp.insert(allvar_tmp.end(), exovars.begin(), exovars.end());
+
+  if (allvar_order)
+    delete allvar_order;
+  allvar_order = new AllvarOuterOrdering(allvar_tmp, *this);
+}
+
+void
+FineAtoms::parsing_finished(VarOrdering::ord_type ot,
+                            const vector<const char *> allvar)
+{
+  make_internal_orderings(ot);
+  if (allvar_order)
+    delete allvar_order;
+  allvar_order = new AllvarOuterOrdering(allvar, *this);
+}
+
+const vector<const char *> &
+FineAtoms::get_allvar() const
+{
+  if (!allvar_order)
+    throw ogu::Exception(__FILE__, __LINE__,
+                         "FineAtoms::get_allvars called before parsing_finished");
+
+  return allvar_order->get_allvar();
+}
+
+const vector<int> &
+FineAtoms::outer_endo2all() const
+{
+  if (!allvar_order)
+    throw ogu::Exception(__FILE__, __LINE__,
+                         "FineAtoms::outer_endo2all called before parsing_finished");
+
+  return allvar_order->get_endo2all();
+}
+
+const vector<int> &
+FineAtoms::outer_exo2all() const
+{
+  if (!allvar_order)
+    throw ogu::Exception(__FILE__, __LINE__,
+                         "FineAtoms::outer_exo2all called before parsing_finished");
+
+  return allvar_order->get_exo2all();
+}
+
+vector<int>
+FineAtoms::variables() const
+{
+  if (endo_order)
+    {
+      return der_atoms;
+    }
+  else
+    {
+      throw ogu::Exception(__FILE__, __LINE__,
+                           "FineAtoms::variables called before parsing_finished");
+      return vector<int>();
+    }
+}
+
+int
+FineAtoms::nstat() const
+{
+  if (endo_order)
+    {
+      return endo_order->nstat();
+    }
+  else
+    {
+      throw ogu::Exception(__FILE__, __LINE__,
+                           "FineAtoms::nstat called before parsing_finished");
+      return -1;
+    }
+}
+
+int
+FineAtoms::npred() const
+{
+  if (endo_order)
+    {
+      return endo_order->npred();
+    }
+  else
+    {
+      throw ogu::Exception(__FILE__, __LINE__,
+                           "FineAtoms::npred called before parsing_finished");
+      return -1;
+    }
+}
+
+int
+FineAtoms::nboth() const
+{
+  if (endo_order)
+    {
+      return endo_order->nboth();
+    }
+  else
+    {
+      throw ogu::Exception(__FILE__, __LINE__,
+                           "FineAtoms::nboth called before parsing_finished");
+      return -1;
+    }
+}
+
+int
+FineAtoms::nforw() const
+{
+  if (endo_order)
+    {
+      return endo_order->nforw();
+    }
+  else
+    {
+      throw ogu::Exception(__FILE__, __LINE__,
+                           "FineAtoms::nforw called before parsing_finished");
+      return -1;
+    }
+}
+
+int
+FineAtoms::get_pos_of_endo(int t) const
+{
+  if (endo_order)
+    {
+      return endo_order->get_pos_of(t);
+    }
+  else
+    {
+      throw ogu::Exception(__FILE__, __LINE__,
+                           "FineAtoms::get_pos_of_endo called before parsing_finished");
+      return -1;
+    }
+}
+
+int
+FineAtoms::get_pos_of_exo(int t) const
+{
+  if (exo_order)
+    {
+      return exo_order->get_pos_of(t);
+    }
+  else
+    {
+      throw ogu::Exception(__FILE__, __LINE__,
+                           "FineAtoms::get_pos_of_exo called before parsing_finished");
+      return -1;
+    }
+}
+
+int
+FineAtoms::get_pos_of_all(int t) const
+{
+  if (endo_order && exo_order)
+    {
+      if (endo_order->check(t))
+        return endo_order->get_pos_of(t);
+      else if (exo_order->check(t))
+        return endo_order->length() + exo_order->get_pos_of(t);
+      else
+        {
+          throw ogu::Exception(__FILE__, __LINE__,
+                               "Atom is not endo nor exo in FineAtoms::get_pos_of_all");
+          return -1;
+        }
+    }
+  else
+    {
+      throw ogu::Exception(__FILE__, __LINE__,
+                           "FineAtoms::get_pos_of_exo called before parsing_finished");
+      return -1;
+    }
+}
+
+const vector<int> &
+FineAtoms::y2outer_endo() const
+{
+  if (!endo_order)
+    throw ogu::Exception(__FILE__, __LINE__,
+                         "FineAtoms::y2outer_endo called before parsing_finished");
+  return endo_order->get_y2outer();
+}
+
+const vector<int> &
+FineAtoms::outer2y_endo() const
+{
+  if (!endo_order)
+    throw ogu::Exception(__FILE__, __LINE__,
+                         "FineAtoms::outer2y_endo called before parsing_finished");
+  return endo_order->get_outer2y();
+}
+
+const vector<int> &
+FineAtoms::y2outer_exo() const
+{
+  if (!exo_order)
+    throw ogu::Exception(__FILE__, __LINE__,
+                         "FineAtoms::y2outer_endo called before parsing_finished");
+  return exo_order->get_y2outer();
+}
+
+const vector<int> &
+FineAtoms::outer2y_exo() const
+{
+  if (!exo_order)
+    throw ogu::Exception(__FILE__, __LINE__,
+                         "FineAtoms::outer2y_exo called before parsing_finished");
+  return exo_order->get_outer2y();
+}
+
+const vector<int> &
+FineAtoms::get_endo_atoms_map() const
+{
+  if (!endo_order)
+    throw ogu::Exception(__FILE__, __LINE__,
+                         "FineAtoms::get_endo_atoms_map called before parsing_finished");
+  return endo_atoms_map;
+}
+
+const vector<int> &
+FineAtoms::get_exo_atoms_map() const
+{
+  if (!exo_order)
+    throw ogu::Exception(__FILE__, __LINE__,
+                         "FineAtoms::get_exo_atoms_map called before parsing_finished");
+  return exo_atoms_map;
+}
+
+int
+FineAtoms::name2outer_param(const char *name) const
+{
+  Tvarintmap::const_iterator it = param_outer_map.find(name);
+  if (it == param_outer_map.end())
+    throw ogu::Exception(__FILE__, __LINE__,
+                         "Name is not a parameter in FineAtoms::name2outer_param");
+  return (*it).second;
+}
+
+int
+FineAtoms::name2outer_endo(const char *name) const
+{
+  Tvarintmap::const_iterator it = endo_outer_map.find(name);
+  if (it == endo_outer_map.end())
+    throw ogu::Exception(__FILE__, __LINE__,
+                         "Name is not an endogenous variable in FineAtoms::name2outer_endo");
+  return (*it).second;
+}
+
+int
+FineAtoms::name2outer_exo(const char *name) const
+{
+  Tvarintmap::const_iterator it = exo_outer_map.find(name);
+  if (it == exo_outer_map.end())
+    throw ogu::Exception(__FILE__, __LINE__,
+                         "Name is not an exogenous variable in FineAtoms::name2outer_exo");
+  return (*it).second;
+}
+
+int
+FineAtoms::name2outer_allvar(const char *name) const
+{
+  if (!allvar_order)
+    throw ogu::Exception(__FILE__, __LINE__,
+                         "FineAtoms::name2outer_allvar called beore parsing_finished");
+
+  Tvarintmap::const_iterator it = endo_outer_map.find(name);
+  if (it != endo_outer_map.end())
+    return allvar_order->get_endo2all()[(*it).second];
+  else
+    {
+      it = exo_outer_map.find(name);
+      if (it != exo_outer_map.end())
+        return allvar_order->get_exo2all()[(*it).second];
+    }
+
+  throw ogu::Exception(__FILE__, __LINE__,
+                       string("Name ") + name + " is neither endo nor exo variable in FineAtoms::name2outer_allvar");
+  return -1;
+}
+
+void
+FineAtoms::register_uniq_endo(const char *name)
+{
+  if (varnames.query(name))
+    throw ogp::ParserException(string("Endogenous variable <")+name+"> is not unique.", 0);
+  const char *ss = varnames.insert(name);
+  endovars.push_back(ss);
+  endo_outer_map.insert(Tvarintmap::value_type(ss, endovars.size()-1));
+}
+
+void
+FineAtoms::register_uniq_exo(const char *name)
+{
+  if (varnames.query(name))
+    throw ogp::ParserException(string("Exogenous variable <")+name+"> is not unique.", 0);
+  const char *ss = varnames.insert(name);
+  exovars.push_back(ss);
+  exo_outer_map.insert(Tvarintmap::value_type(ss, exovars.size()-1));
+}
+
+void
+FineAtoms::register_uniq_param(const char *name)
+{
+  if (varnames.query(name))
+    throw ogp::ParserException(string("Parameter <")+name+"> is not unique.", 0);
+  const char *ss = varnames.insert(name);
+  params.push_back(ss);
+  param_outer_map.insert(Tvarintmap::value_type(ss, params.size()-1));
+}
+
+void
+FineAtoms::make_internal_orderings(VarOrdering::ord_type ot)
+{
+  bool endo_ordering_done = false;
+  bool exo_ordering_done = false;
+
+  order_type = ot;
+
+  int mlead, mlag;
+  endovarspan(mlead, mlag);
+  if (mlag >= -1 && mlead <= 1)
+    {
+      // make endo ordering
+      if (endo_order)
+        delete endo_order;
+      if (ot == VarOrdering::pbspbfbf)
+        endo_order = new EndoVarOrdering1(endovars, *this);
+      else
+        endo_order = new EndoVarOrdering2(endovars, *this);
+      endo_order->do_ordering();
+      endo_ordering_done = true;
+    }
+
+  exovarspan(mlead, mlag);
+  if (mlag == 0 && mlead == 0)
+    {
+      // make exo ordering
+      if (exo_order)
+        delete exo_order;
+      exo_order = new ExoVarOrdering(exovars, *this);
+      exo_order->do_ordering();
+      exo_ordering_done = true;
+    }
+
+  if (endo_ordering_done && exo_ordering_done)
+    {
+      // concatenate der atoms from endo_order and exo_order
+      der_atoms.clear();
+      der_atoms.insert(der_atoms.end(),
+                       endo_order->get_der_atoms().begin(),
+                       endo_order->get_der_atoms().end());
+      der_atoms.insert(der_atoms.end(),
+                       exo_order->get_der_atoms().begin(),
+                       exo_order->get_der_atoms().end());
+
+      // create endo_atoms_map; der_atoms is a concatenation, so it is easy
+      int endo_atoms = endo_order->get_der_atoms().size();
+      endo_atoms_map.clear();
+      for (int i = 0; i < endo_atoms; i++)
+        endo_atoms_map.push_back(i);
+      // create exo_atoms_map
+      int exo_atoms = exo_order->get_der_atoms().size();
+      exo_atoms_map.clear();
+      for (int i = 0; i < exo_atoms; i++)
+        exo_atoms_map.push_back(endo_atoms + i);
+    }
+}
+
+void
+FineAtoms::print() const
+{
+  DynamicAtoms::print();
+  if (endo_order)
+    {
+      printf("Endo ordering:\n");
+      endo_order->print();
+    }
+  else
+    {
+      printf("Endo ordering not created.\n");
+    }
+  if (exo_order)
+    {
+      printf("Exo ordering:\n");
+      exo_order->print();
+    }
+  else
+    {
+      printf("Exo ordering not created.\n");
+    }
+  printf("endo atoms map:\n");
+  for (unsigned int i = 0; i < endo_atoms_map.size(); i++)
+    printf("%d --> %d\n", i, endo_atoms_map[i]);
+  printf("exo atoms map:\n");
+  for (unsigned int i = 0; i < exo_atoms_map.size(); i++)
+    printf("%d --> %d\n", i, exo_atoms_map[i]);
+}
diff --git a/dynare++/parser/cc/fine_atoms.cpp b/dynare++/parser/cc/fine_atoms.cpp
deleted file mode 100644
index 17920b8ad5e1b6c456dcae40ac9044da5fb43a96..0000000000000000000000000000000000000000
--- a/dynare++/parser/cc/fine_atoms.cpp
+++ /dev/null
@@ -1,482 +0,0 @@
-// Copyright (C) 2005, Ondra Kamenik
-
-// $Id: fine_atoms.cpp 1759 2008-03-31 14:25:20Z kamenik $
-
-#include "utils/cc/exception.h"
-
-#include "parser_exception.h"
-#include "fine_atoms.h"
-
-using namespace ogp;
-
-AllvarOuterOrdering::AllvarOuterOrdering(const vector<const char*>& allvar_outer,
-										 const FineAtoms& a)
-	: atoms(a), allvar(),
-	  endo2all(a.get_endovars().size(), -1),
-	  exo2all(a.get_exovars().size(), -1)
-{
-	// fill in the allvar from allvar_outer
-	for (unsigned int i = 0; i < allvar_outer.size(); i++) {
-		const char* s = atoms.varnames.query(allvar_outer[i]);
-		if (s)
-			allvar.push_back(s);
-		else
-			throw ogu::Exception(__FILE__, __LINE__,
-								 string("Variable ") + allvar_outer[i] + " is not a declared symbol in AllvarOuterOrdering constructor");
-	}
-
-	// fill in endo2all and exo2all
-	for (unsigned int i = 0; i < allvar.size(); i++) {
-		Tvarintmap::const_iterator it = atoms.endo_outer_map.find(allvar[i]);
-		if (it != atoms.endo_outer_map.end())
-			endo2all[(*it).second] = i;
-		else {
-			it = atoms.exo_outer_map.find(allvar[i]);
-			if (it != atoms.exo_outer_map.end())
-				exo2all[(*it).second] = i;
-			else
-				throw ogu::Exception(__FILE__, __LINE__,
-									 string("Name ") + allvar[i] + " is neither endogenous nor exogenous variable in AllvarOuterOrdering constructor");
-		}
-	}
-
-	// check whether everything has been filled
-	unsigned int iendo = 0;
-	while (iendo < endo2all.size() && endo2all[iendo] != -1) iendo++;
-	unsigned int iexo = 0;
-	while (iexo < exo2all.size() && exo2all[iexo] != -1) iexo++;
-	if (iendo < endo2all.size())
-		throw ogu::Exception(__FILE__, __LINE__,
-							 string("Endogenous variable ") + atoms.get_endovars()[iendo] +
-							 " not found in outer all ordering in AllvarOuterOrdering constructor");
-	if (iexo < exo2all.size())
-		throw ogu::Exception(__FILE__, __LINE__,
-							 string("Exogenous variable ") + atoms.get_exovars()[iexo] +
-							 " not found in outer all ordering in AllvarOuterOrdering constructor");
-}
-
-AllvarOuterOrdering::AllvarOuterOrdering(const AllvarOuterOrdering& avo,
-										 const FineAtoms& a)
-	: atoms(a), allvar(),
-	  endo2all(avo.endo2all),
-	  exo2all(avo.exo2all)
-{
-	// fill in the allvar from avo.allvar
-	for (unsigned int i = 0; i < avo.allvar.size(); i++) {
-		const char* s = atoms.varnames.query(avo.allvar[i]);
-		allvar.push_back(s);
-	}
-}
-
-
-FineAtoms::FineAtoms(const FineAtoms& fa)
-	: DynamicAtoms(fa), params(), endovars(), exovars(),
-	  endo_order(NULL), exo_order(NULL), allvar_order(NULL),
-	  der_atoms(fa.der_atoms),
-	  endo_atoms_map(fa.endo_atoms_map),
-	  exo_atoms_map(fa.exo_atoms_map)
-{
-	// fill in params
-	for (unsigned int i = 0; i < fa.params.size(); i++) {
-		const char* s = varnames.query(fa.params[i]);
-		if (! s)
-			throw ogu::Exception(__FILE__, __LINE__,
-								 string("Parameter ") + fa.params[i] + " does not exist in FineAtoms copy cosntructor");
-		params.push_back(s);
-		param_outer_map.insert(Tvarintmap::value_type(s, params.size()-1));
-	}
-	// fill in endovars
-	for (unsigned int i = 0; i < fa.endovars.size(); i++) {
-		const char* s = varnames.query(fa.endovars[i]);
-		if (! s)
-			throw ogu::Exception(__FILE__, __LINE__,
-								 string("Endo variable ") + fa.endovars[i] + " does not exist in FineAtoms copy constructor");
-		endovars.push_back(s);
-		endo_outer_map.insert(Tvarintmap::value_type(s, endovars.size()-1));
-	}
-	// fill in exovars
-	for (unsigned int i = 0; i < fa.exovars.size(); i++) {
-		const char* s = varnames.query(fa.exovars[i]);
-		if (! s)
-			throw ogu::Exception(__FILE__, __LINE__,
-								 string("Exo variable ") + fa.exovars[i] + " does not exist in FineAtoms copy cosntructor");
-		exovars.push_back(s);
-		exo_outer_map.insert(Tvarintmap::value_type(s, exovars.size()-1));
-	}
-
-	if (fa.endo_order)
-		endo_order = fa.endo_order->clone(endovars, *this);
-
-	if (fa.exo_order)
-		exo_order = fa.exo_order->clone(exovars, *this);
-
-	if (fa.allvar_order)
-		allvar_order = new AllvarOuterOrdering(*(fa.allvar_order), *this);
-}
-
-int FineAtoms::check_variable(const char* name) const
-{
-	string str;
-	int ll;
-	parse_variable(name, str, ll);
-	if (varnames.query(str.c_str()))
-		return DynamicAtoms::check_variable(name);
-	else {
-		throw ParserException(string("Variable <")+str+"> not declared.",0);
-		return -1;
-	}
-}
-
-int FineAtoms::num_exo_periods() const
-{
-	int mlead, mlag;
-	exovarspan(mlead, mlag);
-	return mlead-mlag+1;
-}
-
-void FineAtoms::parsing_finished(VarOrdering::ord_type ot)
-{
-	make_internal_orderings(ot);
-
-	// by default, concatenate outer endo and outer exo and make it as
-	// allvar outer:
-	vector<const char*> allvar_tmp;
-	allvar_tmp.insert(allvar_tmp.end(), endovars.begin(), endovars.end());
-	allvar_tmp.insert(allvar_tmp.end(), exovars.begin(), exovars.end());
-
-	if (allvar_order)
-		delete allvar_order;
-	allvar_order = new AllvarOuterOrdering(allvar_tmp, *this);
-}
-
-void FineAtoms::parsing_finished(VarOrdering::ord_type ot,
-								 const vector<const char*> allvar)
-{
-	make_internal_orderings(ot);
-	if (allvar_order)
-		delete allvar_order;
-	allvar_order = new AllvarOuterOrdering(allvar, *this);
-}
-
-const vector<const char*>& FineAtoms::get_allvar() const
-{
-	if (! allvar_order)
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "FineAtoms::get_allvars called before parsing_finished");
-
-	return allvar_order->get_allvar();
-}
-
-const vector<int>& FineAtoms::outer_endo2all() const
-{
-	if (! allvar_order)
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "FineAtoms::outer_endo2all called before parsing_finished");
-
-	return allvar_order->get_endo2all();
-}
-
-const vector<int>& FineAtoms::outer_exo2all() const
-{
-	if (! allvar_order)
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "FineAtoms::outer_exo2all called before parsing_finished");
-
-	return allvar_order->get_exo2all();
-}
-
-
-vector<int> FineAtoms::variables() const
-{
-	if (endo_order) {
-		return der_atoms;
-	} else {
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "FineAtoms::variables called before parsing_finished");
-		return vector<int>();
-	}
-}
-
-int FineAtoms::nstat() const
-{
-	if (endo_order) {
-		return endo_order->nstat();
-	} else {
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "FineAtoms::nstat called before parsing_finished");
-		return -1;
-	}
-}
-
-int FineAtoms::npred() const
-{
-	if (endo_order) {
-		return endo_order->npred();
-	} else {
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "FineAtoms::npred called before parsing_finished");
-		return -1;
-	}
-}
-
-int FineAtoms::nboth() const
-{
-	if (endo_order) {
-		return endo_order->nboth();
-	} else {
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "FineAtoms::nboth called before parsing_finished");
-		return -1;
-	}
-}
-
-int FineAtoms::nforw() const
-{
-	if (endo_order) {
-		return endo_order->nforw();
-	} else {
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "FineAtoms::nforw called before parsing_finished");
-		return -1;
-	}
-}
-
-int FineAtoms::get_pos_of_endo(int t) const
-{
-	if (endo_order) {
-		return endo_order->get_pos_of(t);
-	} else {
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "FineAtoms::get_pos_of_endo called before parsing_finished");
-		return -1;
-	}
-}
-
-int FineAtoms::get_pos_of_exo(int t) const
-{
-	if (exo_order) {
-		return exo_order->get_pos_of(t);
-	} else {
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "FineAtoms::get_pos_of_exo called before parsing_finished");
-		return -1;
-	}
-}
-
-int FineAtoms::get_pos_of_all(int t) const
-{
-	if (endo_order && exo_order) {
-		if (endo_order->check(t))
-			return endo_order->get_pos_of(t);
-		else if (exo_order->check(t))
-			return endo_order->length() + exo_order->get_pos_of(t);
-		else {
-			throw ogu::Exception(__FILE__,__LINE__,
-								 "Atom is not endo nor exo in FineAtoms::get_pos_of_all");
-			return -1;
-		}
-	} else {
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "FineAtoms::get_pos_of_exo called before parsing_finished");
-		return -1;
-	}
-}
-
-const vector<int>& FineAtoms::y2outer_endo() const
-{
-	if (! endo_order)
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "FineAtoms::y2outer_endo called before parsing_finished");
-	return endo_order->get_y2outer();
-}
-
-const vector<int>& FineAtoms::outer2y_endo() const
-{
-	if (! endo_order)
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "FineAtoms::outer2y_endo called before parsing_finished");
-	return endo_order->get_outer2y();
-}
-
-const vector<int>& FineAtoms::y2outer_exo() const
-{
-	if (! exo_order)
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "FineAtoms::y2outer_endo called before parsing_finished");
-	return exo_order->get_y2outer();
-}
-
-const vector<int>& FineAtoms::outer2y_exo() const
-{
-	if (! exo_order)
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "FineAtoms::outer2y_exo called before parsing_finished");
-	return exo_order->get_outer2y();
-}
-
-const vector<int>& FineAtoms::get_endo_atoms_map() const
-{
-	if (! endo_order)
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "FineAtoms::get_endo_atoms_map called before parsing_finished");
-	return endo_atoms_map;
-}
-
-const vector<int>& FineAtoms::get_exo_atoms_map() const
-{
-	if (! exo_order)
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "FineAtoms::get_exo_atoms_map called before parsing_finished");
-	return exo_atoms_map;
-}
-
-int FineAtoms::name2outer_param(const char* name) const
-{
-	Tvarintmap::const_iterator it = param_outer_map.find(name);
-	if (it == param_outer_map.end())
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "Name is not a parameter in FineAtoms::name2outer_param");
-	return (*it).second;
-}
-
-int FineAtoms::name2outer_endo(const char* name) const
-{
-	Tvarintmap::const_iterator it = endo_outer_map.find(name);
-	if (it == endo_outer_map.end())
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "Name is not an endogenous variable in FineAtoms::name2outer_endo");
-	return (*it).second;
-}
-
-int FineAtoms::name2outer_exo(const char* name) const
-{
-	Tvarintmap::const_iterator it = exo_outer_map.find(name);
-	if (it == exo_outer_map.end())
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "Name is not an exogenous variable in FineAtoms::name2outer_exo");
-	return (*it).second;
-}
-
-int FineAtoms::name2outer_allvar(const char* name) const
-{
-	if (! allvar_order)
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "FineAtoms::name2outer_allvar called beore parsing_finished");
-
-	Tvarintmap::const_iterator it = endo_outer_map.find(name);
-	if (it != endo_outer_map.end())
-		return allvar_order->get_endo2all()[(*it).second];
-	else {
-		it = exo_outer_map.find(name);
-		if (it != exo_outer_map.end())
-			return allvar_order->get_exo2all()[(*it).second];
-	}
-
-	throw ogu::Exception(__FILE__,__LINE__,
-						 string("Name ") + name + " is neither endo nor exo variable in FineAtoms::name2outer_allvar");
-	return -1;
-}
-
-void FineAtoms::register_uniq_endo(const char* name)
-{
-	if (varnames.query(name))
-		throw ogp::ParserException(string("Endogenous variable <")+name+"> is not unique.",0);
-	const char* ss = varnames.insert(name);
-	endovars.push_back(ss);
-	endo_outer_map.insert(Tvarintmap::value_type(ss, endovars.size()-1));
-}
-
-void FineAtoms::register_uniq_exo(const char* name)
-{
-	if (varnames.query(name))
-		throw ogp::ParserException(string("Exogenous variable <")+name+"> is not unique.",0);
-	const char* ss = varnames.insert(name);
-	exovars.push_back(ss);
-	exo_outer_map.insert(Tvarintmap::value_type(ss, exovars.size()-1));
-}
-
-void FineAtoms::register_uniq_param(const char* name)
-{
-	if (varnames.query(name))
-		throw ogp::ParserException(string("Parameter <")+name+"> is not unique.",0);
-	const char* ss = varnames.insert(name);
-	params.push_back(ss);
-	param_outer_map.insert(Tvarintmap::value_type(ss, params.size()-1));
-}
-
-void FineAtoms::make_internal_orderings(VarOrdering::ord_type ot)
-{
-	bool endo_ordering_done = false;
-	bool exo_ordering_done = false;
-
-	order_type = ot;
-
-	int mlead, mlag;
-	endovarspan(mlead, mlag);
-	if (mlag >= -1 && mlead <= 1) {
-		// make endo ordering
-		if (endo_order)
-			delete endo_order;
-		if (ot == VarOrdering::pbspbfbf)
-			endo_order = new EndoVarOrdering1(endovars, *this);
-		else
-			endo_order = new EndoVarOrdering2(endovars, *this);
-		endo_order->do_ordering();
-		endo_ordering_done = true;
-	}
-
-	exovarspan(mlead, mlag);
-	if (mlag == 0 && mlead == 0) {
-		// make exo ordering
-		if (exo_order)
-			delete exo_order;
-		exo_order = new ExoVarOrdering(exovars, *this);
-		exo_order->do_ordering();
-		exo_ordering_done = true;
-	}
-
-	if (endo_ordering_done && exo_ordering_done) {
-		// concatenate der atoms from endo_order and exo_order
-		der_atoms.clear();
-		der_atoms.insert(der_atoms.end(), 
-						 endo_order->get_der_atoms().begin(),
-						 endo_order->get_der_atoms().end());
-		der_atoms.insert(der_atoms.end(), 
-						 exo_order->get_der_atoms().begin(),
-						 exo_order->get_der_atoms().end());
-		
-		// create endo_atoms_map; der_atoms is a concatenation, so it is easy
-		int endo_atoms = endo_order->get_der_atoms().size();
-		endo_atoms_map.clear();
-		for (int i = 0; i < endo_atoms; i++)
-			endo_atoms_map.push_back(i);
-		// create exo_atoms_map
-		int exo_atoms = exo_order->get_der_atoms().size();
-		exo_atoms_map.clear();
-		for (int i = 0; i < exo_atoms; i++)
-			exo_atoms_map.push_back(endo_atoms + i);
-	}
-}
-
-void FineAtoms::print() const
-{
-	DynamicAtoms::print();
-	if (endo_order) {
-		printf("Endo ordering:\n");
-		endo_order->print();
-	} else {
-		printf("Endo ordering not created.\n");
-	}
-	if (exo_order) {
-		printf("Exo ordering:\n");
-		exo_order->print();
-	} else {
-		printf("Exo ordering not created.\n");
-	}
-	printf("endo atoms map:\n");
-	for (unsigned int i = 0; i < endo_atoms_map.size(); i++)
-		printf("%d --> %d\n", i, endo_atoms_map[i]);
-	printf("exo atoms map:\n");
-	for (unsigned int i = 0; i < exo_atoms_map.size(); i++)
-		printf("%d --> %d\n", i, exo_atoms_map[i]);
-}
diff --git a/dynare++/parser/cc/fine_atoms.h b/dynare++/parser/cc/fine_atoms.hh
similarity index 99%
rename from dynare++/parser/cc/fine_atoms.h
rename to dynare++/parser/cc/fine_atoms.hh
index 27e5a384165e3c6e3b34a005d8d38eb435aae6aa..610b6b7c48b676c61f458720cc4276b585abdbce 100644
--- a/dynare++/parser/cc/fine_atoms.h
+++ b/dynare++/parser/cc/fine_atoms.hh
@@ -5,7 +5,7 @@
 #ifndef OGP_FINE_ATOMS_H
 #define OGP_FINE_ATOMS_H
 
-#include "dynamic_atoms.h"
+#include "dynamic_atoms.hh"
 
 #include <vector>
 #include <string>
diff --git a/dynare++/parser/cc/formula.lex b/dynare++/parser/cc/formula.ll
similarity index 98%
rename from dynare++/parser/cc/formula.lex
rename to dynare++/parser/cc/formula.ll
index 15254afd2fc5f6701b60d626832ec10188fb6ee7..8747b6e88399b9bc2ad124c2dc3962cea5fc5d7a 100644
--- a/dynare++/parser/cc/formula.lex
+++ b/dynare++/parser/cc/formula.ll
@@ -1,5 +1,5 @@
 %{
-#include "location.h"
+#include "location.hh"
 #include "formula_tab.hh"
 
 	extern YYLTYPE fmla_lloc;
diff --git a/dynare++/parser/cc/formula.y b/dynare++/parser/cc/formula.yy
similarity index 98%
rename from dynare++/parser/cc/formula.y
rename to dynare++/parser/cc/formula.yy
index c687febd7e3d4934253dcee6195f73257014a41b..8cb954a2955db4c5a99339543d1f1900cb0ef934 100644
--- a/dynare++/parser/cc/formula.y
+++ b/dynare++/parser/cc/formula.yy
@@ -3,8 +3,8 @@
 
 #include <cstdio>
 
-#include "location.h"
-#include "formula_parser.h" 
+#include "location.hh"
+#include "formula_parser.hh" 
 #include "formula_tab.hh"
 
 	void fmla_error(const char*);
diff --git a/dynare++/parser/cc/formula_parser.cc b/dynare++/parser/cc/formula_parser.cc
new file mode 100644
index 0000000000000000000000000000000000000000..58e6743902ee5c68c79283ce975f1678dfa74433
--- /dev/null
+++ b/dynare++/parser/cc/formula_parser.cc
@@ -0,0 +1,566 @@
+// Copyright (C) 2005, Ondra Kamenik
+
+// $Id: formula_parser.cpp 2268 2008-11-22 10:38:03Z michel $
+
+#include "utils/cc/pascal_triangle.hh"
+#include "utils/cc/exception.hh"
+
+#include "parser_exception.hh"
+#include "location.hh"
+#include "formula_parser.hh"
+#include "formula_tab.hh"
+
+#include <cmath>
+
+using namespace ogp;
+
+extern location_type fmla_lloc;
+
+FormulaParser::FormulaParser(const FormulaParser &fp, Atoms &a)
+  : otree(fp.otree), atoms(a), formulas(fp.formulas), ders()
+{
+  // create derivatives
+  for (unsigned int i = 0; i < fp.ders.size(); i++)
+    ders.push_back(new FormulaDerivatives(*(fp.ders[i])));
+}
+
+FormulaParser::~FormulaParser()
+{
+  destroy_derivatives();
+}
+
+void
+FormulaParser::differentiate(int max_order)
+{
+  destroy_derivatives();
+  vector<int> vars;
+  vars = atoms.variables();
+  for (unsigned int i = 0; i < formulas.size(); i++)
+    ders.push_back(new FormulaDerivatives(otree, vars, formulas[i], max_order));
+}
+
+const FormulaDerivatives &
+FormulaParser::derivatives(int i) const
+{
+  if (i < (int) ders.size())
+    return *(ders[i]);
+  else
+    throw ogu::Exception(__FILE__, __LINE__,
+                         "Wrong formula index in FormulaParser::derivatives");
+  return *(ders[0]); // just because of compiler
+}
+
+void
+FormulaParser::add_formula(int t)
+{
+  formulas.push_back(t);
+}
+
+int
+FormulaParser::add_binary(code_t code, int t1, int t2)
+{
+  return otree.add_binary(code, t1, t2);
+}
+
+int
+FormulaParser::add_unary(code_t code, int t)
+{
+  return otree.add_unary(code, t);
+}
+
+int
+FormulaParser::add_nulary(const char *str)
+{
+  int t = -1;
+  try
+    {
+      t = atoms.check(str);
+    }
+  catch (const ParserException &e)
+    {
+      throw ParserException(e, fmla_lloc.off);
+    }
+  if (t == -1)
+    {
+      t = otree.add_nulary();
+      atoms.assign(str, t);
+    }
+  return t;
+}
+
+void
+FormulaParser::add_subst_formulas(const map<int, int> &subst, const FormulaParser &fp)
+{
+  for (int i = 0; i < fp.nformulas(); i++)
+    {
+      int f = add_substitution(fp.formula(i), subst, fp);
+      add_formula(f);
+    }
+}
+
+void
+FormulaParser::substitute_formulas(const map<int, int> &smap)
+{
+  for (int i = 0; i < nformulas(); i++)
+    {
+      // make substitution and replace the formula for it
+      int f = add_substitution(formulas[i], smap);
+      formulas[i] = f;
+      // update the derivatives if any
+      if (i < (int) ders.size() && ders[i])
+        {
+          int order = ders[i]->get_order();
+          delete ders[i];
+          ders[i] = new FormulaDerivatives(otree, atoms.variables(), formulas[i], order);
+        }
+    }
+}
+
+/** Global symbols for passing info to parser. */
+FormulaParser *fparser;
+
+/** The declarations of functions defined in formula_ll.cc and
+ * formula_tab.cc generated from formula.lex and formula.y */
+void *fmla__scan_buffer(char *, size_t);
+void fmla__destroy_buffer(void *);
+int fmla_parse();
+extern location_type fmla_lloc;
+
+/** This makes own copy of provided data, sets the buffer for the
+ * parser with fmla_scan_buffer, and launches fmla_parse(). Note that
+ * the pointer returned from fmla_scan_buffer must be freed at the
+ * end. */
+void
+FormulaParser::parse(int length, const char *stream)
+{
+  char *buffer = new char[length+2];
+  strncpy(buffer, stream, length);
+  buffer[length] = '\0';
+  buffer[length+1] = '\0';
+  fmla_lloc.off = 0;
+  fmla_lloc.ll = 0;
+  void *p = fmla__scan_buffer(buffer, (unsigned int) length+2);
+  fparser = this;
+  fmla_parse();
+  delete [] buffer;
+  fmla__destroy_buffer(p);
+}
+
+void
+FormulaParser::error(const char *mes) const
+{
+  throw ParserException(mes, fmla_lloc.off);
+}
+
+int
+FormulaParser::last_formula() const
+{
+  int res = -1;
+  for (unsigned int i = 0; i < formulas.size(); i++)
+    if (res < formulas[i])
+      res = formulas[i];
+  return std::max(res, otree.get_last_nulary());
+}
+
+int
+FormulaParser::pop_last_formula()
+{
+  if (formulas.size() == 0)
+    return -1;
+  int t = formulas.back();
+  if (formulas.size() == ders.size())
+    {
+      delete ders.back();
+      ders.pop_back();
+    }
+  formulas.pop_back();
+  return t;
+}
+
+void
+FormulaParser::print() const
+{
+  atoms.print();
+  for (unsigned int i = 0; i < formulas.size(); i++)
+    {
+      printf("formula %d:\n", formulas[i]);
+      otree.print_operation(formulas[i]);
+    }
+  for (unsigned int i = 0; i < ders.size(); i++)
+    {
+      printf("derivatives for the formula %d:\n", formulas[i]);
+      ders[i]->print(otree);
+    }
+}
+
+void
+FormulaParser::destroy_derivatives()
+{
+  while (ders.size() > 0)
+    {
+      delete ders.back();
+      ders.pop_back();
+    }
+}
+
+/** This constructor makes a vector of indices for formulas
+ * corresponding to derivatives of the given formula. The formula is
+ * supposed to belong to the provided tree, the created derivatives
+ * are added to the tree.
+ *
+ * The algorithm is as follows. todo: update description of the
+ * algorithm
+ */
+FormulaDerivatives::FormulaDerivatives(OperationTree &otree,
+                                       const vector<int> &vars, int f, int max_order)
+  : nvar(vars.size()), order(max_order)
+{
+  FoldMultiIndex fmi_zero(nvar);
+  tder.push_back(f);
+  indices.push_back(fmi_zero);
+  unsigned int last_order_beg = 0;
+  unsigned int last_order_end = tder.size();
+
+  for (int k = 1; k <= order; k++)
+    {
+      // interval <last_order_beg,last_order_end) is guaranteed
+      // here to contain at least one item
+      for (unsigned int run = last_order_beg; run < last_order_end; run++)
+        {
+          // shift one order from the run
+          FoldMultiIndex fmi(indices[run], 1);
+          // set starting variable from the run, note that if k=1,
+          // the shift order ctor of fmi will set it to zero
+          int ivar_start = fmi[k-1];
+          for (int ivar = ivar_start; ivar < nvar; ivar++, fmi.increment())
+            {
+              int der = otree.add_derivative(tder[run], vars[ivar]);
+              if (der != OperationTree::zero)
+                {
+                  tder.push_back(der);
+                  indices.push_back(fmi);
+                }
+            }
+        }
+
+      // set new last_order_beg and last_order_end
+      last_order_beg = last_order_end;
+      last_order_end = tder.size();
+      // if there was no new derivative, break out from the loop
+      if (last_order_beg >= last_order_end)
+        break;
+    }
+
+  // build ind2der map
+  for (unsigned int i = 0; i < indices.size(); i++)
+    ind2der.insert(Tfmiintmap::value_type(indices[i], i));
+
+}
+
+FormulaDerivatives::FormulaDerivatives(const FormulaDerivatives &fd)
+  : tder(fd.tder), indices(fd.indices), ind2der(fd.ind2der),
+    nvar(fd.nvar), order(fd.order)
+{
+}
+
+int
+FormulaDerivatives::derivative(const FoldMultiIndex &mi) const
+{
+  if (mi.order() > order)
+    throw ogu::Exception(__FILE__, __LINE__,
+                         "Wrong order of multi-index in FormulaDerivatives::derivative");
+  if (mi.nv() != nvar)
+    throw ogu::Exception(__FILE__, __LINE__,
+                         "Wrong multi-index variables in FormulaDerivatives::derivative");
+
+  Tfmiintmap::const_iterator it = ind2der.find(mi);
+  if (it == ind2der.end())
+    return OperationTree::zero;
+  else
+    return tder[(*it).second];
+}
+
+void
+FormulaDerivatives::print(const OperationTree &otree) const
+{
+  for (Tfmiintmap::const_iterator it = ind2der.begin();
+       it != ind2der.end(); ++it)
+    {
+      printf("derivative ");
+      (*it).first.print();
+      printf(" is formula %d\n", tder[(*it).second]);
+      otree.print_operation(tder[(*it).second]);
+    }
+}
+
+void
+FormulaCustomEvaluator::eval(const AtomValues &av, FormulaEvalLoader &loader)
+{
+  etree.reset_all();
+  av.setValues(etree);
+  for (unsigned int i = 0; i < terms.size(); i++)
+    {
+      double res = etree.eval(terms[i]);
+      loader.load((int) i, res);
+    }
+}
+
+FoldMultiIndex::FoldMultiIndex(int nv)
+  : nvar(nv), ord(0), data(new int[ord])
+{
+}
+
+FoldMultiIndex::FoldMultiIndex(int nv, int ordd, int ii)
+  : nvar(nv), ord(ordd), data(new int[ord])
+{
+  for (int i = 0; i < ord; i++)
+    data[i] = ii;
+}
+
+/** Note that a monotone sequence mapped by monotone mapping yields a
+ * monotone sequence. */
+FoldMultiIndex::FoldMultiIndex(int nv, const FoldMultiIndex &mi, const vector<int> &mp)
+  : nvar(nv), ord(mi.ord), data(new int[ord])
+{
+  for (int i = 0; i < ord; i++)
+    {
+      if (i < ord-1 && mp[i+1] < mp[i])
+        throw ogu::Exception(__FILE__, __LINE__,
+                             "Mapping not monotone in FoldMultiIndex constructor");
+      if (mp[mi[i]] >= nv || mp[mi[i]] < 0)
+        throw ogu::Exception(__FILE__, __LINE__,
+                             "Mapping out of bounds in FoldMultiIndex constructor");
+      data[i] = mp[mi[i]];
+    }
+}
+
+FoldMultiIndex::FoldMultiIndex(const FoldMultiIndex &fmi, int new_orders)
+  : nvar(fmi.nvar),
+    ord(fmi.ord+new_orders),
+    data(new int[ord])
+{
+  memcpy(data, fmi.data, fmi.ord*sizeof(int));
+  int new_item = (fmi.ord > 0) ? fmi.data[fmi.ord-1] : 0;
+  for (int i = fmi.ord; i < ord; i++)
+    {
+      data[i] = new_item;
+    }
+}
+
+FoldMultiIndex::FoldMultiIndex(const FoldMultiIndex &fmi)
+  : nvar(fmi.nvar),
+    ord(fmi.ord),
+    data(new int[fmi.ord])
+{
+  memcpy(data, fmi.data, ord*sizeof(int));
+}
+
+const FoldMultiIndex &
+FoldMultiIndex::operator=(const FoldMultiIndex &fmi)
+{
+  if (ord != fmi.ord)
+    {
+      delete [] data;
+      data = new int[fmi.ord];
+    }
+
+  ord = fmi.ord;
+  nvar = fmi.nvar;
+  memcpy(data, fmi.data, ord*sizeof(int));
+
+  return *this;
+}
+
+bool
+FoldMultiIndex::operator<(const FoldMultiIndex &fmi) const
+{
+  if (nvar != fmi.nvar)
+    ogu::Exception(__FILE__, __LINE__,
+                   "Different nvar in FoldMultiIndex::operator<");
+
+  if (ord < fmi.ord)
+    return true;
+  if (ord > fmi.ord)
+    return false;
+
+  int i = 0;
+  while (i < ord && data[i] == fmi.data[i])
+    i++;
+  if (i == ord)
+    return false;
+  else
+    return data[i] < fmi.data[i];
+}
+
+bool
+FoldMultiIndex::operator==(const FoldMultiIndex &fmi) const
+{
+  bool res = true;
+  res = res && (nvar == fmi.nvar) && (ord == fmi.ord);
+  if (res)
+    for (int i = 0; i < ord; i++)
+      if (data[i] != fmi.data[i])
+        return false;
+  return res;
+}
+
+void
+FoldMultiIndex::increment()
+{
+  if (ord == 0)
+    return;
+
+  int k = ord-1;
+  data[k]++;
+  while (k > 0 && data[k] == nvar)
+    {
+      data[k] = 0;
+      data[--k]++;
+    }
+  for (int kk = 1; kk < ord; kk++)
+    if (data[kk-1] > data[kk])
+      data[kk] = data[kk-1];
+}
+
+// For description of an algorithm for calculation of folded offset,
+// see Tensor Library Documentation, Ondra Kamenik, 2005, description
+// of FTensor::getOffsetRecurse().
+int
+FoldMultiIndex::offset() const
+{
+  // make copy for the recursions
+  int *tmp = new int[ord];
+  for (int i = 0; i < ord; i++)
+    tmp[i] = data[i];
+  // call the recursive algorithm
+  int res = offset_recurse(tmp, ord, nvar);
+
+  delete [] tmp;
+  return res;
+}
+
+void
+FoldMultiIndex::print() const
+{
+  printf("[");
+  for (int i = 0; i < ord; i++)
+    printf("%d ", data[i]);
+  printf("]");
+}
+
+int
+FoldMultiIndex::offset_recurse(int *data, int len, int nv)
+{
+  if (len == 0)
+    return 0;
+  // calculate length of initial constant indices
+  int prefix = 1;
+  while (prefix < len && data[0] == data[prefix])
+    prefix++;
+
+  int m = data[0];
+  int s1 = ptriang.noverk(nv+len-1, len) - ptriang.noverk(nv-m+len-1, len);
+
+  // cancel m from the rest of the sequence
+  for (int i = prefix; i < len; i++)
+    data[i] -= m;
+
+  // calculate offset of the remaining sequence
+  int s2 = offset_recurse(data+prefix, len-prefix, nv-m);
+  // return the sum
+  return s1+s2;
+}
+
+bool
+ltfmi::operator()(const FoldMultiIndex &i1, const FoldMultiIndex &i2) const
+{
+  return i1 < i2;
+}
+
+FormulaDerEvaluator::FormulaDerEvaluator(const FormulaParser &fp)
+  : etree(fp.otree, -1)
+{
+  for (unsigned int i = 0; i < fp.ders.size(); i++)
+    ders.push_back((const FormulaDerivatives *) (fp.ders[i]));
+
+  der_atoms = fp.atoms.variables();
+}
+
+void
+FormulaDerEvaluator::eval(const AtomValues &av, FormulaDerEvalLoader &loader, int order)
+{
+  if (ders.size() == 0)
+    return;
+  int maxorder = ders[0]->order;
+
+  if (order > maxorder)
+    throw ogu::Exception(__FILE__, __LINE__,
+                         "Wrong order in FormulaDerEvaluator::eval");
+
+  etree.reset_all();
+  av.setValues(etree);
+
+  int *vars = new int[order];
+
+  for (unsigned int i = 0; i < ders.size(); i++)
+    {
+      for (FormulaDerivatives::Tfmiintmap::const_iterator it = ders[i]->ind2der.begin();
+           it != ders[i]->ind2der.end(); ++it)
+        {
+          const FoldMultiIndex &mi = (*it).first;
+          if (mi.order() == order)
+            {
+              // set vars from multiindex mi and variables
+              for (int k = 0; k < order; k++)
+                vars[k] = der_atoms[mi[k]];
+              // evaluate
+              double res = etree.eval(ders[i]->tder[(*it).second]);
+              // load
+              loader.load(i, order, vars, res);
+            }
+        }
+    }
+
+  delete [] vars;
+}
+
+void
+FormulaDerEvaluator::eval(const vector<int> &mp, const AtomValues &av,
+                          FormulaDerEvalLoader &loader, int order)
+{
+  etree.reset_all();
+  av.setValues(etree);
+
+  int nvar_glob = der_atoms.size();
+  int nvar = mp.size();
+  int *vars = new int[order];
+
+  for (unsigned int i = 0; i < ders.size(); i++)
+    {
+      FoldMultiIndex mi(nvar, order);
+      do
+        {
+          // find index of the derivative in the tensor
+          FoldMultiIndex mi_glob(nvar_glob, mi, mp);
+          int der = ders[i]->derivative(mi_glob);
+          if (der != OperationTree::zero)
+            {
+              // set vars from the global multiindex
+              for (int k = 0; k < order; k++)
+                vars[k] = der_atoms[mi_glob[k]];
+              // evaluate derivative
+              double res = etree.eval(der);
+              // load
+              loader.load(i, order, vars, res);
+            }
+          mi.increment();
+        }
+      while (!mi.past_the_end());
+    }
+
+  delete [] vars;
+}
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/dynare++/parser/cc/formula_parser.cpp b/dynare++/parser/cc/formula_parser.cpp
deleted file mode 100644
index cd3c26101d47e031534049d1e52d0ea154c4b5c6..0000000000000000000000000000000000000000
--- a/dynare++/parser/cc/formula_parser.cpp
+++ /dev/null
@@ -1,517 +0,0 @@
-// Copyright (C) 2005, Ondra Kamenik
-
-// $Id: formula_parser.cpp 2268 2008-11-22 10:38:03Z michel $
-
-#include "utils/cc/pascal_triangle.h"
-#include "utils/cc/exception.h"
-
-#include "parser_exception.h"
-#include "location.h"
-#include "formula_parser.h"
-#include "formula_tab.hh"
-
-#include <cmath>
-
-using namespace ogp;
-
-extern location_type fmla_lloc;
-
-FormulaParser::FormulaParser(const FormulaParser& fp, Atoms& a)
-	: otree(fp.otree), atoms(a), formulas(fp.formulas), ders()
-{
-	// create derivatives
-	for (unsigned int i = 0; i < fp.ders.size(); i++)
-		ders.push_back(new FormulaDerivatives(*(fp.ders[i])));
-}
-
-FormulaParser::~FormulaParser()
-{
-	destroy_derivatives();
-}
-
-void FormulaParser::differentiate(int max_order)
-{
-	destroy_derivatives();
-	vector<int> vars;
-	vars = atoms.variables();
-	for (unsigned int i = 0; i < formulas.size(); i++)
-		ders.push_back(new FormulaDerivatives(otree, vars, formulas[i], max_order));
-}
-
-const FormulaDerivatives& FormulaParser::derivatives(int i) const
-{
-	if (i < (int)ders.size())
-		return *(ders[i]);
-	else
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "Wrong formula index in FormulaParser::derivatives");
-	return *(ders[0]); // just because of compiler
-}
-
-
-
-void FormulaParser::add_formula(int t)
-{
-	formulas.push_back(t);
-}
-
-int FormulaParser::add_binary(code_t code, int t1, int t2)
-{
-	return otree.add_binary(code, t1, t2);
-}
-
-int FormulaParser::add_unary(code_t code, int t)
-{
-	return otree.add_unary(code, t);
-}
-
-int FormulaParser::add_nulary(const char* str)
-{
-	int t = -1;
-	try {
-		t = atoms.check(str);
-	} catch (const ParserException& e) {
-		throw ParserException(e, fmla_lloc.off);
-	}
-	if (t == -1) {
-		t = otree.add_nulary();
-		atoms.assign(str, t);
-	}
-	return t;
-}
-
-void FormulaParser::add_subst_formulas(const map<int,int>& subst, const FormulaParser& fp)
-{
-	for (int i = 0; i < fp.nformulas(); i++) {
-		int f = add_substitution(fp.formula(i), subst, fp);
-		add_formula(f);
-	}
-}
-
-void FormulaParser::substitute_formulas(const map<int,int>& smap)
-{
-	for (int i = 0; i < nformulas(); i++) {
-		// make substitution and replace the formula for it
-		int f = add_substitution(formulas[i], smap);
-		formulas[i] = f;
-		// update the derivatives if any
-		if (i < (int)ders.size() && ders[i]) {
-			int order = ders[i]->get_order();
-			delete ders[i];
-			ders[i] = new FormulaDerivatives(otree, atoms.variables(), formulas[i], order);
-		}
-	}
-}
-
-/** Global symbols for passing info to parser. */
-FormulaParser* fparser;
-
-/** The declarations of functions defined in formula_ll.cc and
- * formula_tab.cc generated from formula.lex and formula.y */
-void* fmla__scan_buffer(char*, size_t);
-void fmla__destroy_buffer(void*);
-int fmla_parse();
-extern location_type fmla_lloc; 
-
-/** This makes own copy of provided data, sets the buffer for the
- * parser with fmla_scan_buffer, and launches fmla_parse(). Note that
- * the pointer returned from fmla_scan_buffer must be freed at the
- * end. */ 
-void FormulaParser::parse(int length, const char* stream)
-{
-	char* buffer = new char[length+2];
-	strncpy(buffer, stream, length);
-	buffer[length] = '\0';
-	buffer[length+1] = '\0';
-	fmla_lloc.off = 0;
-	fmla_lloc.ll = 0;
-	void* p = fmla__scan_buffer(buffer, (unsigned int)length+2);
-	fparser = this;
-	fmla_parse();
-	delete [] buffer;
-	fmla__destroy_buffer(p);
-}
-
-void FormulaParser::error(const char* mes) const
-{
-	throw ParserException(mes, fmla_lloc.off);
-}
-
-int FormulaParser::last_formula() const
-{
-	int res = -1;
-	for (unsigned int i = 0; i < formulas.size(); i++)
-		if (res < formulas[i])
-			res = formulas[i];
-	return std::max(res, otree.get_last_nulary());
-}
-
-int FormulaParser::pop_last_formula()
-{
-	if (formulas.size() == 0)
-		return -1;
-	int t = formulas.back();
-	if (formulas.size() == ders.size()) {
-		delete ders.back();
-		ders.pop_back();
-	}
-	formulas.pop_back();
-	return t;
-}
-
-void FormulaParser::print() const
-{
-	atoms.print();
-	for (unsigned int i = 0; i < formulas.size(); i++) {
-		printf("formula %d:\n", formulas[i]);
-		otree.print_operation(formulas[i]);
-	}
-	for (unsigned int i = 0; i < ders.size(); i++) {
-		printf("derivatives for the formula %d:\n", formulas[i]);
-		ders[i]->print(otree);
-	}
-}
-
-void FormulaParser::destroy_derivatives()
-{
-	while (ders.size() > 0) {
-		delete ders.back();
-		ders.pop_back();
-	}
-}
-
-/** This constructor makes a vector of indices for formulas
- * corresponding to derivatives of the given formula. The formula is
- * supposed to belong to the provided tree, the created derivatives
- * are added to the tree. 
- *
- * The algorithm is as follows. todo: update description of the
- * algorithm
-*/
-FormulaDerivatives::FormulaDerivatives(OperationTree& otree,
-									   const vector<int>& vars, int f, int max_order)
-	: nvar(vars.size()), order(max_order)
-{
-	FoldMultiIndex fmi_zero(nvar);
-	tder.push_back(f);
-	indices.push_back(fmi_zero);
-	unsigned int last_order_beg = 0;
-	unsigned int last_order_end = tder.size();
-
-	for (int k = 1; k <= order; k++) {
-		// interval <last_order_beg,last_order_end) is guaranteed
-		// here to contain at least one item
-		for (unsigned int run = last_order_beg; run < last_order_end; run++) {
-			// shift one order from the run
-			FoldMultiIndex fmi(indices[run], 1);
-			// set starting variable from the run, note that if k=1,
-			// the shift order ctor of fmi will set it to zero
-			int ivar_start = fmi[k-1];
-			for (int ivar = ivar_start; ivar < nvar; ivar++, fmi.increment()) {
-				int der = otree.add_derivative(tder[run], vars[ivar]);
-				if (der != OperationTree::zero) {
-					tder.push_back(der);
-					indices.push_back(fmi);
-				}
-			}
-		}
-
-		// set new last_order_beg and last_order_end
-		last_order_beg = last_order_end;
-		last_order_end = tder.size();
-		// if there was no new derivative, break out from the loop
-		if (last_order_beg >= last_order_end)
-			break;
-	}
-
-	// build ind2der map
-	for (unsigned int i = 0; i < indices.size(); i++)
-		ind2der.insert(Tfmiintmap::value_type(indices[i], i));
-
-}
-
-FormulaDerivatives::FormulaDerivatives(const FormulaDerivatives& fd)
-	: tder(fd.tder), indices(fd.indices), ind2der(fd.ind2der),
-	  nvar(fd.nvar), order(fd.order)
-{
-}
-
-int FormulaDerivatives::derivative(const FoldMultiIndex& mi) const
-{
-	if (mi.order() > order)
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "Wrong order of multi-index in FormulaDerivatives::derivative");
-	if (mi.nv() != nvar)
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "Wrong multi-index variables in FormulaDerivatives::derivative");
-
-	Tfmiintmap::const_iterator it = ind2der.find(mi);
-	if (it == ind2der.end())
-		return OperationTree::zero;
-	else
-		return tder[(*it).second];
-}
-
-void FormulaDerivatives::print(const OperationTree& otree) const
-{
-	for (Tfmiintmap::const_iterator it = ind2der.begin();
-		 it != ind2der.end(); ++it) {
-		printf("derivative ");
-		(*it).first.print();
-		printf(" is formula %d\n", tder[(*it).second]);
-		otree.print_operation(tder[(*it).second]);
-	}
-}
-
-void FormulaCustomEvaluator::eval(const AtomValues& av, FormulaEvalLoader& loader)
-{
-	etree.reset_all();
-	av.setValues(etree);
-	for (unsigned int i = 0; i < terms.size(); i++) {
-		double res = etree.eval(terms[i]);
-		loader.load((int)i, res);
-	}
-}
-
-FoldMultiIndex::FoldMultiIndex(int nv)
-	: nvar(nv), ord(0), data(new int[ord])
-{
-}
-
-FoldMultiIndex::FoldMultiIndex(int nv, int ordd, int ii)
-	: nvar(nv), ord(ordd), data(new int[ord])
-{
-	for (int i = 0; i < ord; i++)
-		data[i] = ii;
-}
-
-/** Note that a monotone sequence mapped by monotone mapping yields a
- * monotone sequence. */
-FoldMultiIndex::FoldMultiIndex(int nv, const FoldMultiIndex& mi, const vector<int>& mp)
-	: nvar(nv), ord(mi.ord), data(new int[ord])
-{
-	for (int i = 0; i < ord; i++) {
-		if (i < ord-1 && mp[i+1] < mp[i])
-			throw ogu::Exception(__FILE__,__LINE__,
-								 "Mapping not monotone in FoldMultiIndex constructor");
-		if (mp[mi[i]] >= nv || mp[mi[i]] < 0)
-			throw ogu::Exception(__FILE__,__LINE__,
-								 "Mapping out of bounds in FoldMultiIndex constructor");
-		data[i] = mp[mi[i]];
-	}
-}
-
-FoldMultiIndex::FoldMultiIndex(const FoldMultiIndex& fmi, int new_orders)
-	: nvar(fmi.nvar),
-	  ord(fmi.ord+new_orders),
-	  data(new int[ord])
-{
-	memcpy(data, fmi.data, fmi.ord*sizeof(int));
-	int new_item = (fmi.ord > 0)? fmi.data[fmi.ord-1] : 0;
-	for (int i = fmi.ord; i < ord; i++) {
-		data[i] = new_item;
-	}
-}
-
-FoldMultiIndex::FoldMultiIndex(const FoldMultiIndex& fmi)
-	: nvar(fmi.nvar),
-	  ord(fmi.ord),
-	  data(new int[fmi.ord])
-{
-	memcpy(data, fmi.data, ord*sizeof(int));
-}
-
-const FoldMultiIndex& FoldMultiIndex::operator=(const FoldMultiIndex& fmi)
-{
-	if (ord != fmi.ord) {
-		delete [] data;
-		data = new int[fmi.ord];
-	}
-
-	ord = fmi.ord;
-	nvar = fmi.nvar;
-	memcpy(data, fmi.data, ord*sizeof(int));
-
-	return *this;
-}
-
-bool FoldMultiIndex::operator<(const FoldMultiIndex& fmi) const
-{
-	if (nvar != fmi.nvar)
-		ogu::Exception(__FILE__,__LINE__,
-					   "Different nvar in FoldMultiIndex::operator<");
-
-	if (ord < fmi.ord)
-		return true;
-	if (ord > fmi.ord)
-		return false;
-
-	int i = 0;
-	while (i < ord && data[i] == fmi.data[i])
-		i++;
-	if (i == ord)
-		return false;
-	else
-		return data[i] < fmi.data[i];
-}
-
-bool FoldMultiIndex::operator==(const FoldMultiIndex& fmi) const
-{
-	bool res = true;
-	res = res && (nvar == fmi.nvar) && (ord == fmi.ord);
-	if (res)
-		for (int i = 0; i < ord; i++)
-			if (data[i] != fmi.data[i])
-				return false;
-	return res;
-}
-
-void FoldMultiIndex::increment()
-{
-	if (ord == 0)
-		return;
-
-	int k = ord-1;
-	data[k]++;
-	while (k > 0 && data[k] == nvar) {
-		data[k] = 0;
-		data[--k]++;
-	}
-	for (int kk = 1; kk < ord; kk++)
-		if (data[kk-1] > data[kk])
-			data[kk] = data[kk-1];
-}
-
-
-// For description of an algorithm for calculation of folded offset,
-// see Tensor Library Documentation, Ondra Kamenik, 2005, description
-// of FTensor::getOffsetRecurse().
-int FoldMultiIndex::offset() const
-{
-	// make copy for the recursions
-	int* tmp = new int[ord];
-	for (int i = 0; i < ord; i++)
-		tmp[i] = data[i];
-	// call the recursive algorithm
-	int res = offset_recurse(tmp, ord, nvar);
-
-	delete [] tmp;
-	return res;
-}
-
-void FoldMultiIndex::print() const
-{
-	printf("[");
-	for (int i = 0; i < ord; i++)
-		printf("%d ", data[i]);
-	printf("]");
-}
-
-int FoldMultiIndex::offset_recurse(int* data, int len, int nv)
-{
-	if (len == 0)
-		return 0;
-	// calculate length of initial constant indices
-	int prefix = 1;
-	while (prefix < len && data[0] == data[prefix])
-		prefix++;
-
-	int m = data[0];
-	int s1 = ptriang.noverk(nv+len-1, len) - ptriang.noverk(nv-m+len-1,len);
-
-	// cancel m from the rest of the sequence
-	for (int i = prefix; i < len; i++)
-		data[i] -= m;
-
-	// calculate offset of the remaining sequence
-	int s2 = offset_recurse(data+prefix, len-prefix, nv-m);
-	// return the sum
-	return s1+s2;
-}
-
-
-bool ltfmi::operator()(const FoldMultiIndex& i1, const FoldMultiIndex& i2) const
-{
-	return i1 < i2;
-}
-
-
-FormulaDerEvaluator::FormulaDerEvaluator(const FormulaParser& fp)
-	: etree(fp.otree, -1)
-{
-	for (unsigned int i = 0; i < fp.ders.size(); i++)
-		ders.push_back((const FormulaDerivatives*)(fp.ders[i]));
-
-	der_atoms = fp.atoms.variables();
-}
-
-void FormulaDerEvaluator::eval(const AtomValues& av, FormulaDerEvalLoader& loader, int order)
-{
-	if (ders.size() == 0)
-		return;
-	int maxorder = ders[0]->order;
-
-	if (order > maxorder)
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "Wrong order in FormulaDerEvaluator::eval");
-
-	etree.reset_all();
-	av.setValues(etree);
-
-	int* vars = new int[order];
-
-	for (unsigned int i = 0; i < ders.size(); i++) {
-		for (FormulaDerivatives::Tfmiintmap::const_iterator it = ders[i]->ind2der.begin();
-			 it != ders[i]->ind2der.end(); ++it) {
-			const FoldMultiIndex& mi = (*it).first;
-			if (mi.order() == order) {
-				// set vars from multiindex mi and variables
-				for (int k = 0; k < order; k++)
-					vars[k] = der_atoms[mi[k]];
-				// evaluate
-				double res = etree.eval(ders[i]->tder[(*it).second]);
-				// load
-				loader.load(i, order, vars, res);
-			}
-		}
-	}
-
-	delete [] vars;
-}
-
-void FormulaDerEvaluator::eval(const vector<int>& mp, const AtomValues& av,
-							   FormulaDerEvalLoader& loader, int order)
-{
-	etree.reset_all();
-	av.setValues(etree);
-
-	int nvar_glob = der_atoms.size();
-	int nvar = mp.size();
-	int* vars = new int[order];
-
-	for (unsigned int i = 0; i < ders.size(); i++) {
-		FoldMultiIndex mi(nvar, order);
-		do {
-			// find index of the derivative in the tensor
-			FoldMultiIndex mi_glob(nvar_glob, mi, mp);
-			int der = ders[i]->derivative(mi_glob);
-			if (der != OperationTree::zero) {
-				// set vars from the global multiindex
-				for (int k = 0; k < order; k++)
-					vars[k] = der_atoms[mi_glob[k]];
-				// evaluate derivative
-				double res = etree.eval(der);
-				// load
-				loader.load(i, order, vars, res);
-			}
-			mi.increment();
-		} while (! mi.past_the_end());
-	}
-
-	delete [] vars;
-}
-
-
-// Local Variables:
-// mode:C++
-// End:
diff --git a/dynare++/parser/cc/formula_parser.h b/dynare++/parser/cc/formula_parser.hh
similarity index 99%
rename from dynare++/parser/cc/formula_parser.h
rename to dynare++/parser/cc/formula_parser.hh
index 5cd4476e5103ac2d4d14eb278b2205670deb9118..1f2302063bc84d2b2e9d47f930518e60cb653e5b 100644
--- a/dynare++/parser/cc/formula_parser.h
+++ b/dynare++/parser/cc/formula_parser.hh
@@ -3,7 +3,7 @@
 #ifndef OGP_FORMULA_PARSER_H
 #define OGP_FORMULA_PARSER_H
 
-#include "tree.h"
+#include "tree.hh"
 
 namespace ogp
 {
diff --git a/dynare++/parser/cc/location.h b/dynare++/parser/cc/location.hh
similarity index 100%
rename from dynare++/parser/cc/location.h
rename to dynare++/parser/cc/location.hh
diff --git a/dynare++/parser/cc/matrix.lex b/dynare++/parser/cc/matrix.ll
similarity index 97%
rename from dynare++/parser/cc/matrix.lex
rename to dynare++/parser/cc/matrix.ll
index 880b8eca621fda2b083d66a6ba838c38f357719f..51c4c85dcb75b32db18a79ee5e0c54216e515aee 100644
--- a/dynare++/parser/cc/matrix.lex
+++ b/dynare++/parser/cc/matrix.ll
@@ -1,7 +1,7 @@
 %{
 // Copyright (C) 2006-2011, Ondra Kamenik
 
-#include "location.h"
+#include "location.hh"
 #include "matrix_tab.hh"
 
 	extern YYLTYPE matrix_lloc;
diff --git a/dynare++/parser/cc/matrix.y b/dynare++/parser/cc/matrix.yy
similarity index 96%
rename from dynare++/parser/cc/matrix.y
rename to dynare++/parser/cc/matrix.yy
index ef48f4c83ac2935674a216bb6e33271a08b5602f..a2fa51db527e1fbcec7cd0594ad287a23e12b136 100644
--- a/dynare++/parser/cc/matrix.y
+++ b/dynare++/parser/cc/matrix.yy
@@ -1,8 +1,8 @@
 // Copyright (C) 2006-2011, Ondra Kamenik
 
 %{
-#include "location.h"
-#include "matrix_parser.h" 
+#include "location.hh"
+#include "matrix_parser.hh"
 #include "matrix_tab.hh"
 
 	void matrix_error(const char*);
diff --git a/dynare++/parser/cc/matrix_parser.cc b/dynare++/parser/cc/matrix_parser.cc
new file mode 100644
index 0000000000000000000000000000000000000000..68b664f6618e719947bea3ee9c97bdaed303c972
--- /dev/null
+++ b/dynare++/parser/cc/matrix_parser.cc
@@ -0,0 +1,112 @@
+// Copyright (C) 2006, Ondra Kamenik
+
+// $Id: matrix_parser.cpp 2269 2008-11-23 14:33:22Z michel $
+
+#include "parser_exception.hh"
+#include "matrix_parser.hh"
+#include "location.hh"
+#include "matrix_tab.hh"
+#include <cstring>
+
+using namespace ogp;
+
+/** A global symbol for passing info to the MatrixParser from
+ * matrix_parse(). */
+MatrixParser *mparser;
+
+/** The declaration of functions defined in matrix_ll.cc and
+ * matrix_tab.cc generated from matrix.lex and matrix.y. */
+void *matrix__scan_buffer(char *, size_t);
+void matrix__destroy_buffer(void *);
+int matrix_parse();
+extern ogp::location_type matrix_lloc;
+
+void
+MatrixParser::parse(int length, const char *stream)
+{
+  // reinitialize the object
+  data.clear();
+  row_lengths.clear();
+  nc = 0;
+  // allocate temporary buffer and parse
+  char *buffer = new char[length+2];
+  strncpy(buffer, stream, length);
+  buffer[length] = '\0';
+  buffer[length+1] = '\0';
+  matrix_lloc.off = 0;
+  matrix_lloc.ll = 0;
+  void *p = matrix__scan_buffer(buffer, (unsigned int) length+2);
+  mparser = this;
+  matrix_parse();
+  delete [] buffer;
+  matrix__destroy_buffer(p);
+}
+
+void
+MatrixParser::add_item(double v)
+{
+  data.push_back(v);
+  if (row_lengths.size() == 0)
+    row_lengths.push_back(0);
+  (row_lengths.back())++;
+  if (row_lengths.back() > nc)
+    nc = row_lengths.back();
+}
+
+void
+MatrixParser::start_row()
+{
+  row_lengths.push_back(0);
+}
+
+void
+MatrixParser::error(const char *mes) const
+{
+  throw ParserException(mes, matrix_lloc.off);
+}
+
+int
+MatrixParser::find_first_non_empty_row(int start) const
+{
+  int r = start;
+  while (r < (int) row_lengths.size() && row_lengths[r] == 0)
+    r++;
+  return r;
+}
+
+MPIterator
+MatrixParser::begin() const
+{
+  MPIterator it(*this);
+  return it;
+}
+
+MPIterator
+MatrixParser::end() const
+{
+  MPIterator it(*this, "end");
+  return it;
+}
+
+MPIterator::MPIterator(const MatrixParser &mp)
+  : p(&mp), i(0), c(0), r(mp.find_first_non_empty_row())
+{
+}
+
+MPIterator::MPIterator(const MatrixParser &mp, const char *dummy)
+  : p(&mp), i(mp.data.size()), c(0), r(mp.row_lengths.size())
+{
+}
+
+MPIterator &
+MPIterator::operator++()
+{
+  i++;
+  c++;
+  if (p->row_lengths[r] <= c)
+    {
+      c = 0;
+      r = p->find_first_non_empty_row(r+1);
+    }
+  return *this;
+}
diff --git a/dynare++/parser/cc/matrix_parser.cpp b/dynare++/parser/cc/matrix_parser.cpp
deleted file mode 100644
index eadbd3533037498c6167033c9c0b73aca301645c..0000000000000000000000000000000000000000
--- a/dynare++/parser/cc/matrix_parser.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright (C) 2006, Ondra Kamenik
-
-// $Id: matrix_parser.cpp 2269 2008-11-23 14:33:22Z michel $
-
-#include "parser_exception.h"
-#include "matrix_parser.h"
-#include "location.h"
-#include "matrix_tab.hh"
-#include <cstring>
-
-using namespace ogp;
-
-/** A global symbol for passing info to the MatrixParser from
- * matrix_parse(). */
-MatrixParser* mparser;
-
-/** The declaration of functions defined in matrix_ll.cc and
- * matrix_tab.cc generated from matrix.lex and matrix.y. */
-void* matrix__scan_buffer(char*, size_t);
-void matrix__destroy_buffer(void*);
-int matrix_parse();
-extern ogp::location_type matrix_lloc;
-
-void MatrixParser::parse(int length, const char* stream)
-{
-	// reinitialize the object
-	data.clear();
-	row_lengths.clear();
-	nc = 0;
-	// allocate temporary buffer and parse
-	char* buffer = new char[length+2];
-	strncpy(buffer, stream, length);
-	buffer[length] = '\0';
-	buffer[length+1] = '\0';
-	matrix_lloc.off = 0;
-	matrix_lloc.ll = 0;
-	void* p = matrix__scan_buffer(buffer, (unsigned int)length+2);
-	mparser = this;
-	matrix_parse();
-	delete [] buffer;
-	matrix__destroy_buffer(p);
-}
-
-void MatrixParser::add_item(double v)
-{
-	data.push_back(v);
-	if (row_lengths.size() == 0)
-		row_lengths.push_back(0);
-	(row_lengths.back())++;
-	if (row_lengths.back() > nc)
-		nc = row_lengths.back();
-}
-
-void MatrixParser::start_row()
-{
-	row_lengths.push_back(0);
-}
-
-void MatrixParser::error(const char* mes) const
-{
-	throw ParserException(mes, matrix_lloc.off);
-}
-
-int MatrixParser::find_first_non_empty_row(int start) const
-{
-	int r = start;
-	while (r < (int)row_lengths.size() && row_lengths[r] == 0)
-		r++;
-	return r;
-}
-
-MPIterator MatrixParser::begin() const
-{
-	MPIterator it(*this);
-	return it;
-}
-
-MPIterator MatrixParser::end() const
-{
-	MPIterator it(*this, "end");
-	return it;
-}
-
-MPIterator::MPIterator(const MatrixParser& mp)
-	: p(&mp), i(0), c(0), r(mp.find_first_non_empty_row())
-{}
-
-MPIterator::MPIterator(const MatrixParser& mp, const char* dummy)
-	: p(&mp), i(mp.data.size()), c(0), r(mp.row_lengths.size())
-{}
-
-MPIterator& MPIterator::operator++()
-{
-	i++;
-	c++;
-	if (p->row_lengths[r] <= c) {
-		c = 0;
-		r = p->find_first_non_empty_row(r+1);
-	}
-	return *this;
-}
diff --git a/dynare++/parser/cc/matrix_parser.h b/dynare++/parser/cc/matrix_parser.hh
similarity index 100%
rename from dynare++/parser/cc/matrix_parser.h
rename to dynare++/parser/cc/matrix_parser.hh
diff --git a/dynare++/parser/cc/namelist.cc b/dynare++/parser/cc/namelist.cc
new file mode 100644
index 0000000000000000000000000000000000000000..c9c148e2a623724d4221d247741c2144c0ee0a7a
--- /dev/null
+++ b/dynare++/parser/cc/namelist.cc
@@ -0,0 +1,31 @@
+// Copyright (C) 2006, Ondra Kamenik
+
+// $Id: namelist.cpp 42 2007-01-22 21:53:24Z ondra $
+
+#include "namelist.hh"
+
+#include <cstring>
+
+using namespace ogp;
+
+/** A global symbol for passing info to NameListParser from its
+ * parser. */
+NameListParser *name_list_parser;
+
+void *namelist__scan_buffer(char *, unsigned int);
+void namelist__destroy_buffer(void *);
+void namelist_parse();
+
+void
+NameListParser::namelist_parse(int length, const char *stream)
+{
+  char *buffer = new char[length+2];
+  strncpy(buffer, stream, length);
+  buffer[length] = '\0';
+  buffer[length+1] = '\0';
+  void *p = namelist__scan_buffer(buffer, (unsigned int) length+2);
+  name_list_parser = this;
+  ::namelist_parse();
+  delete [] buffer;
+  namelist__destroy_buffer(p);
+}
diff --git a/dynare++/parser/cc/namelist.cpp b/dynare++/parser/cc/namelist.cpp
deleted file mode 100644
index 03bf9a51c9a891b373ded9724c6931ce1bd86986..0000000000000000000000000000000000000000
--- a/dynare++/parser/cc/namelist.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (C) 2006, Ondra Kamenik
-
-// $Id: namelist.cpp 42 2007-01-22 21:53:24Z ondra $
-
-#include "namelist.h"
-
-#include <cstring>
-
-using namespace ogp;
-
-/** A global symbol for passing info to NameListParser from its
- * parser. */
-NameListParser* name_list_parser;
-
-void* namelist__scan_buffer(char*, unsigned int);
-void namelist__destroy_buffer(void*);
-void namelist_parse();
-
-void NameListParser::namelist_parse(int length, const char* stream)
-{
-	char* buffer = new char[length+2];
-	strncpy(buffer, stream, length);
-	buffer[length] = '\0';
-	buffer[length+1] = '\0';
-	void* p = namelist__scan_buffer(buffer, (unsigned int)length+2);
-	name_list_parser = this;
-	::namelist_parse();
-	delete [] buffer;
-	namelist__destroy_buffer(p);
-}
diff --git a/dynare++/parser/cc/namelist.h b/dynare++/parser/cc/namelist.hh
similarity index 100%
rename from dynare++/parser/cc/namelist.h
rename to dynare++/parser/cc/namelist.hh
diff --git a/dynare++/parser/cc/namelist.lex b/dynare++/parser/cc/namelist.ll
similarity index 97%
rename from dynare++/parser/cc/namelist.lex
rename to dynare++/parser/cc/namelist.ll
index 0a14f904f97dc0068f678ff562f283c4cb8782f0..506ef997037f80c8c3cd157d797e984fc147fecc 100644
--- a/dynare++/parser/cc/namelist.lex
+++ b/dynare++/parser/cc/namelist.ll
@@ -1,5 +1,5 @@
 %{
-#include "location.h"
+#include "location.hh"
 #include "namelist_tab.hh"
 
 	extern YYLTYPE namelist_lloc;
diff --git a/dynare++/parser/cc/namelist.y b/dynare++/parser/cc/namelist.yy
similarity index 93%
rename from dynare++/parser/cc/namelist.y
rename to dynare++/parser/cc/namelist.yy
index 7d41d4890b20c306115fc93b86409ab5f3510872..762e478547aaeb10a1662bcc44d0e91d3450facb 100644
--- a/dynare++/parser/cc/namelist.y
+++ b/dynare++/parser/cc/namelist.yy
@@ -1,8 +1,8 @@
 // Copyright (C) 2007-2011, Ondra Kamenik
 
 %{
-#include "location.h"
-#include "namelist.h"
+#include "location.hh"
+#include "namelist.hh"
 #include "namelist_tab.hh"
 
 	void namelist_error(const char*);
diff --git a/dynare++/parser/cc/parser_exception.cc b/dynare++/parser/cc/parser_exception.cc
new file mode 100644
index 0000000000000000000000000000000000000000..e9512b58247700033a2ec9dce421d68f7c9259ef
--- /dev/null
+++ b/dynare++/parser/cc/parser_exception.cc
@@ -0,0 +1,118 @@
+// Copyright (C) 2006, Ondra Kamenik
+
+// $Id: parser_exception.cpp 2269 2008-11-23 14:33:22Z michel $
+
+#include "parser_exception.hh"
+#include <cstring>
+#include <cstdio>
+
+using namespace ogp;
+
+ParserException::ParserException(const char *m, int offset)
+  : mes(new char[strlen(m)+1]), off(offset),
+    aux_i1(-1), aux_i2(-1), aux_i3(-1)
+{
+  strcpy(mes, m);
+}
+
+ParserException::ParserException(const string &m, int offset)
+  : mes(new char[m.size()+1]), off(offset),
+    aux_i1(-1), aux_i2(-1), aux_i3(-1)
+{
+  strncpy(mes, m.c_str(), m.size());
+  mes[m.size()] = '\0';
+}
+
+ParserException::ParserException(const string &m, const char *dum, int i1)
+  : mes(new char[m.size()+1]), off(0),
+    aux_i1(i1), aux_i2(-1), aux_i3(-1)
+{
+  strncpy(mes, m.c_str(), m.size());
+  mes[m.size()] = '\0';
+}
+
+ParserException::ParserException(const string &m, const char *dum, int i1, int i2)
+  : mes(new char[m.size()+1]), off(0),
+    aux_i1(i1), aux_i2(i2), aux_i3(-1)
+{
+  strncpy(mes, m.c_str(), m.size());
+  mes[m.size()] = '\0';
+}
+
+ParserException::ParserException(const string &m, const char *dum, int i1, int i2, int i3)
+  : mes(new char[m.size()+1]), off(0),
+    aux_i1(i1), aux_i2(i2), aux_i3(i3)
+{
+  strncpy(mes, m.c_str(), m.size());
+  mes[m.size()] = '\0';
+}
+
+ParserException::ParserException(const ParserException &m, int plus_offset)
+  : mes(NULL),
+    aux_i1(-1), aux_i2(-1), aux_i3(-1)
+{
+  copy(m);
+  off += plus_offset;
+}
+
+ParserException::ParserException(const ParserException &m, const char *dum, int i)
+  : mes(NULL),
+    aux_i1(-1), aux_i2(-1), aux_i3(-1)
+{
+  copy(m);
+  aux_i3 = m.aux_i2;
+  aux_i2 = m.aux_i1;
+  aux_i1 = i;
+}
+
+ParserException::ParserException(const ParserException &m, const char *dum, int i1, int i2)
+  : mes(NULL),
+    aux_i1(-1), aux_i2(-1), aux_i3(-1)
+{
+  copy(m);
+  aux_i3 = m.aux_i1;
+  aux_i2 = i2;
+  aux_i1 = i1;
+}
+
+ParserException::ParserException(const ParserException &m, const char *dum, int i1, int i2, int i3)
+  : mes(NULL),
+    aux_i1(-1), aux_i2(-1), aux_i3(-1)
+{
+  copy(m);
+  aux_i3 = i3;
+  aux_i2 = i2;
+  aux_i1 = i1;
+}
+
+ParserException::ParserException(const ParserException &e)
+  : mes(NULL),
+    aux_i1(-1), aux_i2(-1), aux_i3(-1)
+{
+  copy(e);
+}
+
+ParserException::~ParserException()
+{
+  delete [] mes;
+}
+
+void
+ParserException::copy(const ParserException &e)
+{
+  if (mes)
+    delete [] mes;
+  mes = new char[strlen(e.mes)+1];
+  strcpy(mes, e.mes);
+  off = e.off;
+  aux_i1 = e.aux_i1;
+  aux_i2 = e.aux_i2;
+  aux_i3 = e.aux_i3;
+}
+
+void
+ParserException::print(FILE *fd) const
+{
+  // todo: to be refined
+  fprintf(fd, "%s: offset %d\n", mes, off);
+}
diff --git a/dynare++/parser/cc/parser_exception.cpp b/dynare++/parser/cc/parser_exception.cpp
deleted file mode 100644
index fbd0e28f95cf8b5b20bcb3304e1fadf0326fcc54..0000000000000000000000000000000000000000
--- a/dynare++/parser/cc/parser_exception.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright (C) 2006, Ondra Kamenik
-
-// $Id: parser_exception.cpp 2269 2008-11-23 14:33:22Z michel $
-
-#include "parser_exception.h"
-#include <cstring>
-#include <cstdio>
-
-using namespace ogp;
-
-ParserException::ParserException(const char* m, int offset)
-	: mes(new char[strlen(m)+1]), off(offset),
-	  aux_i1(-1), aux_i2(-1), aux_i3(-1)
-{
-	strcpy(mes, m);
-}
-
-ParserException::ParserException(const string& m, int offset)
-	: mes(new char[m.size()+1]), off(offset),
-	  aux_i1(-1), aux_i2(-1), aux_i3(-1)
-{
-	strncpy(mes, m.c_str(), m.size());
-	mes[m.size()] = '\0';
-}
-
-ParserException::ParserException(const string& m, const char* dum, int i1)
-	: mes(new char[m.size()+1]), off(0),
-	  aux_i1(i1), aux_i2(-1), aux_i3(-1)
-{
-	strncpy(mes, m.c_str(), m.size());
-	mes[m.size()] = '\0';
-}
-
-ParserException::ParserException(const string& m, const char* dum, int i1, int i2) 
-	: mes(new char[m.size()+1]), off(0),
-	  aux_i1(i1), aux_i2(i2), aux_i3(-1)
-{
-	strncpy(mes, m.c_str(), m.size());
-	mes[m.size()] = '\0';
-}
-
-ParserException::ParserException(const string& m, const char* dum, int i1, int i2, int i3) 
-	: mes(new char[m.size()+1]), off(0),
-	  aux_i1(i1), aux_i2(i2), aux_i3(i3)
-{
-	strncpy(mes, m.c_str(), m.size());
-	mes[m.size()] = '\0';
-}
-
-ParserException::ParserException(const ParserException& m, int plus_offset)
-	: mes(NULL),
-	  aux_i1(-1), aux_i2(-1), aux_i3(-1)
-{
-	copy(m);
-	off += plus_offset;
-}
-
-ParserException::ParserException(const ParserException& m, const char* dum, int i)
-	: mes(NULL),
-	  aux_i1(-1), aux_i2(-1), aux_i3(-1)
-{
-	copy(m);
-	aux_i3 = m.aux_i2;
-	aux_i2 = m.aux_i1;
-	aux_i1 = i;
-}
-
-ParserException::ParserException(const ParserException& m, const char* dum, int i1, int i2)
-	: mes(NULL),
-	  aux_i1(-1), aux_i2(-1), aux_i3(-1)
-{
-	copy(m);
-	aux_i3 = m.aux_i1;
-	aux_i2 = i2;
-	aux_i1 = i1;
-}
-
-ParserException::ParserException(const ParserException& m, const char* dum, int i1, int i2, int i3)
-	: mes(NULL),
-	  aux_i1(-1), aux_i2(-1), aux_i3(-1)
-{
-	copy(m);
-	aux_i3 = i3;
-	aux_i2 = i2;
-	aux_i1 = i1;
-}
-
-
-ParserException::ParserException(const ParserException& e)
-	: mes(NULL),
-	  aux_i1(-1), aux_i2(-1), aux_i3(-1)
-{
-	copy(e);
-} 
-
-ParserException::~ParserException()
-{
-	delete [] mes;
-}
-
-void ParserException::copy(const ParserException& e)
-{
-	if (mes)
-		delete [] mes;
-	mes = new char[strlen(e.mes)+1];
-	strcpy(mes, e.mes);
-	off = e.off;
-	aux_i1 = e.aux_i1;
-	aux_i2 = e.aux_i2;
-	aux_i3 = e.aux_i3;
-}
-
-void ParserException::print(FILE* fd) const
-{
-	// todo: to be refined
-	fprintf(fd, "%s: offset %d\n", mes, off);
-}
diff --git a/dynare++/parser/cc/parser_exception.h b/dynare++/parser/cc/parser_exception.hh
similarity index 100%
rename from dynare++/parser/cc/parser_exception.h
rename to dynare++/parser/cc/parser_exception.hh
diff --git a/dynare++/parser/cc/static_atoms.cc b/dynare++/parser/cc/static_atoms.cc
new file mode 100644
index 0000000000000000000000000000000000000000..288f2a37a08e78807fb668013bf8f7c2645e6489
--- /dev/null
+++ b/dynare++/parser/cc/static_atoms.cc
@@ -0,0 +1,141 @@
+// Copyright (C) 2006, Ondra Kamenik
+
+// $Id: static_atoms.cpp 1360 2007-07-10 11:44:20Z kamenik $
+
+#include "static_atoms.hh"
+#include "utils/cc/exception.hh"
+
+using namespace ogp;
+
+StaticAtoms::StaticAtoms(const StaticAtoms &a)
+  : Atoms(), Constants(a), varnames(a.varnames),
+    varorder(), vars(), indices()
+{
+  // fill varorder
+  for (unsigned int i = 0; i < a.varorder.size(); i++)
+    {
+      const char *s = varnames.query(a.varorder[i]);
+      varorder.push_back(s);
+    }
+
+  // fill vars
+  for (Tvarmap::const_iterator it = a.vars.begin();
+       it != a.vars.end(); ++it)
+    {
+      const char *s = varnames.query((*it).first);
+      vars.insert(Tvarmap::value_type(s, (*it).second));
+    }
+
+  // fill indices
+  for (Tinvmap::const_iterator it = a.indices.begin();
+       it != a.indices.end(); ++it)
+    {
+      const char *s = varnames.query((*it).second);
+      indices.insert(Tinvmap::value_type((*it).first, s));
+    }
+}
+
+void
+StaticAtoms::import_atoms(const DynamicAtoms &da, OperationTree &otree, Tintintmap &tmap)
+{
+  Constants::import_constants(da, otree, tmap);
+
+  for (int i = 0; i < da.get_name_storage().num(); i++)
+    {
+      const char *name = da.get_name_storage().get_name(i);
+      register_name(name);
+      int tnew = otree.add_nulary();
+      assign(name, tnew);
+      if (da.is_referenced(name))
+        {
+          const DynamicAtoms::Tlagmap &lmap = da.lagmap(name);
+          for (DynamicAtoms::Tlagmap::const_iterator it = lmap.begin();
+               it != lmap.end(); ++it)
+            {
+              int told = (*it).second;
+              tmap.insert(Tintintmap::value_type(told, tnew));
+            }
+        }
+    }
+}
+
+int
+StaticAtoms::check(const char *name) const
+{
+  if (DynamicAtoms::is_string_constant(name))
+    {
+      return Constants::check(name);
+    }
+  else
+    {
+      return check_variable(name);
+    }
+}
+
+int
+StaticAtoms::index(const char *name) const
+{
+  Tvarmap::const_iterator it = vars.find(name);
+  if (it == vars.end())
+    return -1;
+  else
+    return (*it).second;
+}
+
+const char *
+StaticAtoms::inv_index(int t) const
+{
+  Tinvmap::const_iterator it = indices.find(t);
+  if (it == indices.end())
+    return NULL;
+  else
+    return (*it).second;
+}
+
+void
+StaticAtoms::assign(const char *name, int t)
+{
+  if (DynamicAtoms::is_string_constant(name))
+    {
+      double val;
+      sscanf(name, "%lf", &val);
+      add_constant(t, val);
+    }
+  else
+    {
+      const char *ss = varnames.insert(name);
+      vars.insert(Tvarmap::value_type(ss, t));
+      indices.insert(Tinvmap::value_type(t, ss));
+    }
+}
+
+vector<int>
+StaticAtoms::variables() const
+{
+  vector<int> res;
+  for (Tvarmap::const_iterator it = vars.begin();
+       it != vars.end(); ++it)
+    {
+      res.push_back((*it).second);
+    }
+  return res;
+}
+
+void
+StaticAtoms::register_name(const char *name)
+{
+  const char *ss = varnames.insert(name);
+  varorder.push_back(ss);
+}
+
+void
+StaticAtoms::print() const
+{
+  printf("constants:\n");
+  Constants::print();
+  printf("variable names:\n");
+  varnames.print();
+  printf("map to tree indices:\n");
+  for (Tvarmap::const_iterator it = vars.begin(); it != vars.end(); ++it)
+    printf("%s\t->\t%d\n", (*it).first, (*it).second);
+}
diff --git a/dynare++/parser/cc/static_atoms.cpp b/dynare++/parser/cc/static_atoms.cpp
deleted file mode 100644
index 7276cc0c9a90e9b40dd39f0a6dff566e99e317de..0000000000000000000000000000000000000000
--- a/dynare++/parser/cc/static_atoms.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright (C) 2006, Ondra Kamenik
-
-// $Id: static_atoms.cpp 1360 2007-07-10 11:44:20Z kamenik $
-
-#include "static_atoms.h"
-#include "utils/cc/exception.h"
-
-using namespace ogp;
-
-StaticAtoms::StaticAtoms(const StaticAtoms& a)
-	: Atoms(), Constants(a), varnames(a.varnames),
-	  varorder(), vars(), indices()
-{
-	// fill varorder
-	for (unsigned int i = 0; i < a.varorder.size(); i++) {
-		const char* s = varnames.query(a.varorder[i]);
-		varorder.push_back(s);
-	}
-
-	// fill vars
-	for (Tvarmap::const_iterator it = a.vars.begin();
-		 it != a.vars.end(); ++it) {
-		const char* s = varnames.query((*it).first);
-		vars.insert(Tvarmap::value_type(s, (*it).second));
-	}
-
-	// fill indices
-	for (Tinvmap::const_iterator it = a.indices.begin();
-		 it != a.indices.end(); ++it) {
-		const char* s = varnames.query((*it).second);
-		indices.insert(Tinvmap::value_type((*it).first, s));
-	}
-}
-
-void StaticAtoms::import_atoms(const DynamicAtoms& da, OperationTree& otree, Tintintmap& tmap)
-{
-	Constants::import_constants(da, otree, tmap);
-
-	for (int i = 0; i < da.get_name_storage().num(); i++) {
-		const char* name = da.get_name_storage().get_name(i);
-		register_name(name);
-		int tnew = otree.add_nulary();
-		assign(name, tnew);
-        if (da.is_referenced(name)) {
-            const DynamicAtoms::Tlagmap& lmap = da.lagmap(name);
-			for (DynamicAtoms::Tlagmap::const_iterator it = lmap.begin();
-				 it != lmap.end(); ++it) {
-				int told = (*it).second;
-				tmap.insert(Tintintmap::value_type(told, tnew));
-			}
-        }
-	}
-}
-
-
-int StaticAtoms::check(const char* name) const
-{
-	if (DynamicAtoms::is_string_constant(name)) {
-		return Constants::check(name);
-	} else {
-		return check_variable(name);
-	}
-}
-
-int StaticAtoms::index(const char* name) const
-{
-	Tvarmap::const_iterator it = vars.find(name);
-	if (it == vars.end())
-		return -1;
-	else
-		return (*it).second;
-}
-
-const char* StaticAtoms::inv_index(int t) const
-{
-	Tinvmap::const_iterator it = indices.find(t);
-	if (it == indices.end())
-		return NULL;
-	else
-		return (*it).second;
-}
-
-void StaticAtoms::assign(const char* name, int t)
-{
-	if (DynamicAtoms::is_string_constant(name)) {
-		double val;
-		sscanf(name, "%lf", &val);
-		add_constant(t, val);
-	} else {
-		const char* ss = varnames.insert(name);
-		vars.insert(Tvarmap::value_type(ss, t));
-		indices.insert(Tinvmap::value_type(t, ss));
-	}
-}
-
-vector<int> StaticAtoms::variables() const
-{
-	vector<int> res;
-	for (Tvarmap::const_iterator it = vars.begin();
-		 it != vars.end(); ++it) {
-		res.push_back((*it).second);
-	}
-	return res;
-}
-
-void StaticAtoms::register_name(const char* name)
-{
-	const char* ss = varnames.insert(name);
-	varorder.push_back(ss);
-}
-
-void StaticAtoms::print() const
-{
-	printf("constants:\n");
-	Constants::print();
-	printf("variable names:\n");
-	varnames.print();
-	printf("map to tree indices:\n");
-	for (Tvarmap::const_iterator it = vars.begin(); it != vars.end(); ++it)
-		printf("%s\t->\t%d\n", (*it).first, (*it).second);
-}
diff --git a/dynare++/parser/cc/static_atoms.h b/dynare++/parser/cc/static_atoms.hh
similarity index 99%
rename from dynare++/parser/cc/static_atoms.h
rename to dynare++/parser/cc/static_atoms.hh
index e94825d2933f49f2f7e5b2c72ce7732ad03a385e..cb362dea1caf33c323066790397412c7b95b3129 100644
--- a/dynare++/parser/cc/static_atoms.h
+++ b/dynare++/parser/cc/static_atoms.hh
@@ -5,7 +5,7 @@
 #ifndef OGP_STATIC_ATOMS
 #define OGP_STATIC_ATOMS
 
-#include "dynamic_atoms.h"
+#include "dynamic_atoms.hh"
 
 namespace ogp
 {
diff --git a/dynare++/parser/cc/static_fine_atoms.cc b/dynare++/parser/cc/static_fine_atoms.cc
new file mode 100644
index 0000000000000000000000000000000000000000..807e9df8c6fa9a099b5ef3acf068470e43eed86c
--- /dev/null
+++ b/dynare++/parser/cc/static_fine_atoms.cc
@@ -0,0 +1,237 @@
+// Copyright (C) 2006, Ondra Kamenik
+
+// $Id: static_fine_atoms.cpp 82 2007-04-19 11:33:30Z ondra $
+
+#include "utils/cc/exception.hh"
+
+#include "static_fine_atoms.hh"
+#include "parser_exception.hh"
+
+using namespace ogp;
+
+StaticFineAtoms::StaticFineAtoms(const StaticFineAtoms &sfa)
+  : StaticAtoms(sfa),
+    params(), param_outer_map(),
+    endovars(), endo_outer_map(),
+    exovars(), exo_outer_map(),
+    der_atoms(sfa.der_atoms),
+    endo_atoms_map(sfa.endo_atoms_map),
+    exo_atoms_map(sfa.exo_atoms_map)
+{
+  for (unsigned int i = 0; i < sfa.params.size(); i++)
+    {
+      const char *name = varnames.query(sfa.params[i]);
+      params.push_back(name);
+      param_outer_map.insert(Tvarintmap::value_type(name, i));
+    }
+
+  for (unsigned int i = 0; i < sfa.endovars.size(); i++)
+    {
+      const char *name = varnames.query(sfa.endovars[i]);
+      endovars.push_back(name);
+      endo_outer_map.insert(Tvarintmap::value_type(name, i));
+    }
+
+  for (unsigned int i = 0; i < sfa.exovars.size(); i++)
+    {
+      const char *name = varnames.query(sfa.exovars[i]);
+      exovars.push_back(name);
+      exo_outer_map.insert(Tvarintmap::value_type(name, i));
+    }
+}
+
+void
+StaticFineAtoms::import_atoms(const FineAtoms &fa, OperationTree &otree, Tintintmap &tmap)
+{
+  StaticAtoms::import_atoms(fa, otree, tmap);
+
+  // we just need to put parameters, endovars, and exovars to
+  // respective vectors, the names are already in the storage
+
+  // parameters
+  const vector<const char *> &fa_params = fa.get_params();
+  for (unsigned int i = 0; i < fa_params.size(); i++)
+    register_param(fa_params[i]);
+
+  // endogenous
+  const vector<const char *> &fa_endovars = fa.get_endovars();
+  for (unsigned int i = 0; i < fa_endovars.size(); i++)
+    register_endo(fa_endovars[i]);
+
+  // exogenous
+  const vector<const char *> &fa_exovars = fa.get_exovars();
+  for (unsigned int i = 0; i < fa_exovars.size(); i++)
+    register_exo(fa_exovars[i]);
+
+  parsing_finished();
+}
+
+void
+StaticFineAtoms::import_atoms(const FineAtoms &fa, OperationTree &otree, Tintintmap &tmap,
+                              const char *dummy)
+{
+  StaticAtoms::import_atoms(fa, otree, tmap);
+
+  // we just need to put parameters, endovars, and exovars to
+  // respective vectors, the names are already in the storage
+
+  // parameters
+  const vector<const char *> &fa_params = fa.get_params();
+  for (unsigned int i = 0; i < fa_params.size(); i++)
+    register_param(fa_params[i]);
+
+  // endogenous
+  const vector<const char *> &fa_endovars = fa.get_endovars();
+  for (unsigned int i = 0; i < fa_endovars.size(); i++)
+    register_endo(fa_endovars[fa.y2outer_endo()[i]]);
+
+  // exogenous
+  const vector<const char *> &fa_exovars = fa.get_exovars();
+  for (unsigned int i = 0; i < fa_exovars.size(); i++)
+    register_exo(fa_exovars[fa.y2outer_exo()[i]]);
+
+  parsing_finished();
+}
+
+int
+StaticFineAtoms::check_variable(const char *name) const
+{
+  const char *ss = varnames.query(name);
+  if (ss == NULL)
+    throw ParserException(string("Variable <")+name+"> not declared.", 0);
+  return index(name);
+}
+
+void
+StaticFineAtoms::parsing_finished()
+{
+  // build der_atoms, and endo_atoms_map and exo_atoms_map
+  der_atoms.clear();
+  endo_atoms_map.clear();
+  exo_atoms_map.clear();
+
+  // go through all endo and exo insert tree indices, ignore names
+  // whose tree index is -1 (those which are not referenced)
+  for (unsigned int i = 0; i < endovars.size(); i++)
+    {
+      int t = index(endovars[i]);
+      if (t != -1)
+        {
+          endo_atoms_map.push_back(der_atoms.size());
+          der_atoms.push_back(t);
+        }
+    }
+  for (unsigned int i = 0; i < exovars.size(); i++)
+    {
+      int t = index(exovars[i]);
+      if (t != -1)
+        {
+          exo_atoms_map.push_back(der_atoms.size());
+          der_atoms.push_back(t);
+        }
+    }
+}
+
+int
+StaticFineAtoms::name2outer_param(const char *name) const
+{
+  Tvarintmap::const_iterator it = param_outer_map.find(name);
+  if (it == param_outer_map.end())
+    throw ogu::Exception(__FILE__, __LINE__,
+                         "Name is not a parameter in StaticFineAtoms::name2outer_param");
+  return (*it).second;
+}
+
+int
+StaticFineAtoms::name2outer_endo(const char *name) const
+{
+  Tvarintmap::const_iterator it = endo_outer_map.find(name);
+  if (it == endo_outer_map.end())
+    throw ogu::Exception(__FILE__, __LINE__,
+                         "Name is not an endogenous variable in StaticFineAtoms::name2outer_endo");
+  return (*it).second;
+}
+
+int
+StaticFineAtoms::name2outer_exo(const char *name) const
+{
+  Tvarintmap::const_iterator it = exo_outer_map.find(name);
+  if (it == exo_outer_map.end())
+    throw ogu::Exception(__FILE__, __LINE__,
+                         "Name is not an exogenous variable in StaticFineAtoms::name2outer_exo");
+  return (*it).second;
+}
+
+void
+StaticFineAtoms::register_uniq_endo(const char *name)
+{
+  if (varnames.query(name))
+    throw ogp::ParserException(string("Endogenous variable <")+name+"> is not unique.", 0);
+  const char *ss = varnames.insert(name);
+  register_endo(ss);
+}
+
+void
+StaticFineAtoms::register_uniq_exo(const char *name)
+{
+  if (varnames.query(name))
+    throw ogp::ParserException(string("Exogenous variable <")+name+"> is not unique.", 0);
+  const char *ss = varnames.insert(name);
+  register_exo(ss);
+}
+
+void
+StaticFineAtoms::register_uniq_param(const char *name)
+{
+  if (varnames.query(name))
+    throw ogp::ParserException(string("Parameter <")+name+"> is not unique.", 0);
+  const char *ss = varnames.insert(name);
+  register_param(ss);
+}
+
+void
+StaticFineAtoms::print() const
+{
+  StaticAtoms::print();
+  printf("endo atoms map:\n");
+  for (unsigned int i = 0; i < endo_atoms_map.size(); i++)
+    printf("%d --> %d\n", i, endo_atoms_map[i]);
+  printf("exo atoms map:\n");
+  for (unsigned int i = 0; i < exo_atoms_map.size(); i++)
+    printf("%d --> %d\n", i, exo_atoms_map[i]);
+  printf("der atoms:\n");
+  for (unsigned int i = 0; i < der_atoms.size(); i++)
+    printf("%d\t%d\n", i, der_atoms[i]);
+}
+
+void
+StaticFineAtoms::register_endo(const char *name)
+{
+  const char *ss = varnames.query(name);
+  if (ss == NULL)
+    throw ogp::ParserException(string("Endogenous variable <")
+                               +name+"> not found in storage.", 0);
+  endovars.push_back(ss);
+  endo_outer_map.insert(Tvarintmap::value_type(ss, endovars.size()-1));
+}
+
+void
+StaticFineAtoms::register_exo(const char *name)
+{
+  const char *ss = varnames.query(name);
+  if (ss == NULL)
+    throw ogp::ParserException(string("Exogenous variable <")
+                               +name+"> not found in storage.", 0);
+  exovars.push_back(ss);
+  exo_outer_map.insert(Tvarintmap::value_type(ss, exovars.size()-1));
+}
+
+void
+StaticFineAtoms::register_param(const char *name)
+{
+  const char *ss = varnames.query(name);
+  if (ss == NULL)
+    throw ogp::ParserException(string("Parameter <")+name+"> not found in storage.", 0);
+  params.push_back(ss);
+  param_outer_map.insert(Tvarintmap::value_type(ss, params.size()-1));
+}
diff --git a/dynare++/parser/cc/static_fine_atoms.cpp b/dynare++/parser/cc/static_fine_atoms.cpp
deleted file mode 100644
index 9c5f90a14ea441229ba8e7402a871c643b359697..0000000000000000000000000000000000000000
--- a/dynare++/parser/cc/static_fine_atoms.cpp
+++ /dev/null
@@ -1,217 +0,0 @@
-// Copyright (C) 2006, Ondra Kamenik
-
-// $Id: static_fine_atoms.cpp 82 2007-04-19 11:33:30Z ondra $
-
-#include "utils/cc/exception.h"
-
-#include "static_fine_atoms.h"
-#include "parser_exception.h"
-
-using namespace ogp;
-
-StaticFineAtoms::StaticFineAtoms(const StaticFineAtoms& sfa)
-	: StaticAtoms(sfa),
-	  params(), param_outer_map(),
-	  endovars(), endo_outer_map(),
-	  exovars(), exo_outer_map(),
-	  der_atoms(sfa.der_atoms),
-	  endo_atoms_map(sfa.endo_atoms_map),
-	  exo_atoms_map(sfa.exo_atoms_map)
-{
-	for (unsigned int i = 0; i < sfa.params.size(); i++) {
-		const char* name = varnames.query(sfa.params[i]);
-		params.push_back(name);
-		param_outer_map.insert(Tvarintmap::value_type(name, i));
-	}
-
-	for (unsigned int i = 0; i < sfa.endovars.size(); i++) {
-		const char* name = varnames.query(sfa.endovars[i]);
-		endovars.push_back(name);
-		endo_outer_map.insert(Tvarintmap::value_type(name, i));
-	}
-
-	for (unsigned int i = 0; i < sfa.exovars.size(); i++) {
-		const char* name = varnames.query(sfa.exovars[i]);
-		exovars.push_back(name);
-		exo_outer_map.insert(Tvarintmap::value_type(name, i));
-	}
-}
-
-void StaticFineAtoms::import_atoms(const FineAtoms& fa, OperationTree& otree, Tintintmap& tmap)
-{
-	StaticAtoms::import_atoms(fa, otree, tmap);
-
-	// we just need to put parameters, endovars, and exovars to
-	// respective vectors, the names are already in the storage
-
-	// parameters
-	const vector<const char*>& fa_params = fa.get_params();
-	for (unsigned int i = 0; i < fa_params.size(); i++)
-		register_param(fa_params[i]);
-
-	// endogenous
-	const vector<const char*>& fa_endovars = fa.get_endovars();
-	for (unsigned int i = 0; i < fa_endovars.size(); i++)
-		register_endo(fa_endovars[i]);
-
-	// exogenous
-	const vector<const char*>& fa_exovars = fa.get_exovars();
-	for (unsigned int i = 0; i < fa_exovars.size(); i++)
-		register_exo(fa_exovars[i]);
-
-	parsing_finished();
-}
-
-void StaticFineAtoms::import_atoms(const FineAtoms& fa, OperationTree& otree, Tintintmap& tmap,
-								   const char* dummy)
-{
-	StaticAtoms::import_atoms(fa, otree, tmap);
-
-	// we just need to put parameters, endovars, and exovars to
-	// respective vectors, the names are already in the storage
-
-	// parameters
-	const vector<const char*>& fa_params = fa.get_params();
-	for (unsigned int i = 0; i < fa_params.size(); i++)
-		register_param(fa_params[i]);
-
-	// endogenous
-	const vector<const char*>& fa_endovars = fa.get_endovars();
-	for (unsigned int i = 0; i < fa_endovars.size(); i++)
-		register_endo(fa_endovars[fa.y2outer_endo()[i]]);
-
-	// exogenous
-	const vector<const char*>& fa_exovars = fa.get_exovars();
-	for (unsigned int i = 0; i < fa_exovars.size(); i++)
-		register_exo(fa_exovars[fa.y2outer_exo()[i]]);
-
-	parsing_finished();
-}
-
-int StaticFineAtoms::check_variable(const char* name) const
-{
-	const char* ss = varnames.query(name);
-	if (ss == NULL)
-		throw ParserException(string("Variable <")+name+"> not declared.",0);
-	return index(name);
-}
-
-void StaticFineAtoms::parsing_finished()
-{
-	// build der_atoms, and endo_atoms_map and exo_atoms_map
-	der_atoms.clear();
-	endo_atoms_map.clear();
-	exo_atoms_map.clear();
-
-	// go through all endo and exo insert tree indices, ignore names
-	// whose tree index is -1 (those which are not referenced)
-	for (unsigned int i = 0; i < endovars.size(); i++) {
-		int t = index(endovars[i]);
-		if (t != -1) {
-			endo_atoms_map.push_back(der_atoms.size());
-			der_atoms.push_back(t);
-		}
-	}
-	for (unsigned int i = 0; i < exovars.size(); i++) {
-		int t = index(exovars[i]);
-		if (t != -1) {
-			exo_atoms_map.push_back(der_atoms.size());
-			der_atoms.push_back(t);
-		}
-	}
-}
-
-int StaticFineAtoms::name2outer_param(const char* name) const
-{
-	Tvarintmap::const_iterator it = param_outer_map.find(name);
-	if (it == param_outer_map.end())
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "Name is not a parameter in StaticFineAtoms::name2outer_param");
-	return (*it).second;
-}
-
-int StaticFineAtoms::name2outer_endo(const char* name) const
-{
-	Tvarintmap::const_iterator it = endo_outer_map.find(name);
-	if (it == endo_outer_map.end())
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "Name is not an endogenous variable in StaticFineAtoms::name2outer_endo");
-	return (*it).second;
-}
-
-int StaticFineAtoms::name2outer_exo(const char* name) const
-{
-	Tvarintmap::const_iterator it = exo_outer_map.find(name);
-	if (it == exo_outer_map.end())
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "Name is not an exogenous variable in StaticFineAtoms::name2outer_exo");
-	return (*it).second;
-}
-
-void StaticFineAtoms::register_uniq_endo(const char* name)
-{
-	if (varnames.query(name))
-		throw ogp::ParserException(string("Endogenous variable <")+name+"> is not unique.",0);
-	const char* ss = varnames.insert(name);
-	register_endo(ss);
-}
-
-void StaticFineAtoms::register_uniq_exo(const char* name)
-{
-	if (varnames.query(name))
-		throw ogp::ParserException(string("Exogenous variable <")+name+"> is not unique.",0);
-	const char* ss = varnames.insert(name);
-	register_exo(ss);
-}
-
-void StaticFineAtoms::register_uniq_param(const char* name)
-{
-	if (varnames.query(name))
-		throw ogp::ParserException(string("Parameter <")+name+"> is not unique.",0);
-	const char* ss = varnames.insert(name);
-	register_param(ss);
-}
-
-void StaticFineAtoms::print() const
-{
-	StaticAtoms::print();
-	printf("endo atoms map:\n");
-	for (unsigned int i = 0; i < endo_atoms_map.size(); i++)
-		printf("%d --> %d\n", i, endo_atoms_map[i]);
-	printf("exo atoms map:\n");
-	for (unsigned int i = 0; i < exo_atoms_map.size(); i++)
-		printf("%d --> %d\n", i, exo_atoms_map[i]);	
-	printf("der atoms:\n");
-	for (unsigned int i = 0; i < der_atoms.size(); i++)
-		printf("%d\t%d\n",i, der_atoms[i]);
-}
-
-void StaticFineAtoms::register_endo(const char* name)
-{
-	const char* ss = varnames.query(name);
-	if (ss == NULL)
-		throw ogp::ParserException(string("Endogenous variable <")
-								   +name+"> not found in storage.",0);
-	endovars.push_back(ss);
-	endo_outer_map.insert(Tvarintmap::value_type(ss, endovars.size()-1));
-}
-
-void StaticFineAtoms::register_exo(const char* name)
-{
-	const char* ss = varnames.query(name);
-	if (ss == NULL)
-		throw ogp::ParserException(string("Exogenous variable <")
-								   +name+"> not found in storage.",0);
-	exovars.push_back(ss);
-	exo_outer_map.insert(Tvarintmap::value_type(ss, exovars.size()-1));
-}
-
-void StaticFineAtoms::register_param(const char* name)
-{
-	const char* ss = varnames.query(name);
-	if (ss == NULL)
-		throw ogp::ParserException(string("Parameter <")+name+"> not found in storage.",0);
-	params.push_back(ss);
-	param_outer_map.insert(Tvarintmap::value_type(ss, params.size()-1));
-}
-
diff --git a/dynare++/parser/cc/static_fine_atoms.h b/dynare++/parser/cc/static_fine_atoms.hh
similarity index 99%
rename from dynare++/parser/cc/static_fine_atoms.h
rename to dynare++/parser/cc/static_fine_atoms.hh
index c4247f4a737b815e08fb00e91b97b4710248c572..7d2758ea20363e6315a9eb24cebfbebb45bfbb15 100644
--- a/dynare++/parser/cc/static_fine_atoms.h
+++ b/dynare++/parser/cc/static_fine_atoms.hh
@@ -5,8 +5,8 @@
 #ifndef OGP_STATIC_FINE_ATOMS_H
 #define OGP_STATIC_FINE_ATOMS_H
 
-#include "static_atoms.h"
-#include "fine_atoms.h"
+#include "static_atoms.hh"
+#include "fine_atoms.hh"
 
 namespace ogp
 {
diff --git a/dynare++/parser/cc/tree.cc b/dynare++/parser/cc/tree.cc
new file mode 100644
index 0000000000000000000000000000000000000000..200500d9f2b835a0b66f8ba2a1b9a28b67e97b75
--- /dev/null
+++ b/dynare++/parser/cc/tree.cc
@@ -0,0 +1,1036 @@
+// Copyright (C) 2005-2011, Ondra Kamenik
+
+#include "utils/cc/exception.hh"
+
+#include "tree.hh"
+
+#include <cstdlib>
+
+#include <cmath>
+#include <limits>
+
+#ifdef __MINGW32__
+# define __CROSS_COMPILATION__
+#endif
+
+#ifdef __MINGW64__
+# define __CROSS_COMPILATION__
+#endif
+
+#ifdef __CROSS_COMPILATION__
+# define M_PI 3.14159265358979323846
+#endif
+
+using namespace ogp;
+
+/** Here we just implement complementary error function without
+ * declaring it for uses from outside this unit. The implementation is taken from "Numerical Recipes in C" 2nd ed. 1992 p. 221, */
+double
+erffc(double x)
+{
+  double z = std::abs(x);
+  double t = 1/(1+0.5*z);
+  double r = t*exp(-z*z-1.26551223+t*(1.00002368+t*(0.37409196+t*(0.09678418+t*(-0.18628806+t*(0.27886807+t*(-1.13520398+t*(1.48851587+t*(-0.82215223+t*0.17087277)))))))));
+  return x >= 0 ? r : 2-r;
+}
+
+/** Here we initialize OperationTree to contain only zero, one, nan
+ * and two_over_pi terms. */
+OperationTree::OperationTree()
+{
+  last_nulary = -1;
+  // allocate space for the constants
+  for (int i = 0; i < num_constants; i++)
+    add_nulary();
+}
+
+int
+OperationTree::add_nulary()
+{
+  int op = terms.size();
+  Operation nulary;
+  terms.push_back(nulary);
+  _Tintset s;
+  s.insert(op);
+  nul_incidence.push_back(s);
+  _Tderivmap empty;
+  derivatives.push_back(empty);
+  last_nulary = op;
+  return op;
+}
+
+int
+OperationTree::add_unary(code_t code, int op)
+{
+  if (op == zero
+      && (code == UMINUS
+          || code == SIN
+          || code == TAN
+          || code == SQRT
+          || code == ERF))
+    return zero;
+  if ((op == zero && code == LOG) || op == nan)
+    return nan;
+  if (op == zero && (code == EXP
+                     || code == COS
+                     || code == ERFC))
+    return one;
+
+  Operation unary(code, op);
+  _Topmap::const_iterator i = ((const _Topmap &) opmap).find(unary);
+  if (i == opmap.end())
+    {
+      int newop = terms.size();
+      // add to the terms
+      terms.push_back(unary);
+      // copy incidence of the operand
+      nul_incidence.push_back(nul_incidence[op]);
+      // insert it to opmap
+      opmap.insert(_Topval(unary, newop));
+      // add empty map of derivatives
+      _Tderivmap empty;
+      derivatives.push_back(empty);
+      return newop;
+    }
+  return (*i).second;
+}
+
+int
+OperationTree::add_binary(code_t code, int op1, int op2)
+{
+  // quick exits for special values
+  if (op1 == nan || op2 == nan)
+    return nan;
+  // for plus
+  if (code == PLUS)
+    {
+      if (op1 == zero && op2 == zero)
+        return zero;
+      else if (op1 == zero)
+        return op2;
+      else if (op2 == zero)
+        return op1;
+    }
+  // for minus
+  if (code == MINUS)
+    {
+      if (op1 == zero && op2 == zero)
+        return zero;
+      else if (op1 == zero)
+        return add_unary(UMINUS, op2);
+      else if (op2 == zero)
+        return op1;
+    }
+  // for times
+  if (code == TIMES)
+    {
+      if (op1 == zero || op2 == zero)
+        return zero;
+      else if (op1 == one)
+        return op2;
+      else if (op2 == one)
+        return op1;
+    }
+  // for divide
+  if (code == DIVIDE)
+    {
+      if (op1 == op2)
+        return one;
+      else if (op1 == zero)
+        return zero;
+      else if (op2 == zero)
+        return nan;
+    }
+  // for power
+  if (code == POWER)
+    {
+      if (op1 == zero && op2 == zero)
+        return nan;
+      else if (op1 == zero)
+        return zero;
+      else if (op2 == zero)
+        return one;
+      else if (op1 == one)
+        return one;
+      else if (op2 == one)
+        return op1;
+    }
+
+  // order operands of commutative operations
+  if (code == TIMES || code == PLUS)
+    if (op1 > op2)
+      {
+        int tmp = op1;
+        op1 = op2;
+        op2 = tmp;
+      }
+
+  // construct operation and check/add it
+  Operation binary(code, op1, op2);
+  _Topmap::const_iterator i = ((const _Topmap &) opmap).find(binary);
+  if (i == opmap.end())
+    {
+      int newop = terms.size();
+      terms.push_back(binary);
+      // sum both sets of incidenting nulary operations
+      nul_incidence.push_back(nul_incidence[op1]);
+      nul_incidence.back().insert(nul_incidence[op2].begin(), nul_incidence[op2].end());
+      // add to opmap
+      opmap.insert(_Topval(binary, newop));
+      // add empty map of derivatives
+      _Tderivmap empty;
+      derivatives.push_back(empty);
+      return newop;
+    }
+  return (*i).second;
+}
+
+int
+OperationTree::add_derivative(int t, int v)
+{
+  if (t < 0 || t >= (int) terms.size())
+    throw ogu::Exception(__FILE__, __LINE__,
+                         "Wrong value for tree index in OperationTree::add_derivative");
+
+  // quick returns for nulary terms or empty incidence
+  if (terms[t].nary() == 0 && t != v)
+    {
+      return zero;
+    }
+  if (terms[t].nary() == 0 && t == v)
+    {
+      return one;
+    }
+  if (nul_incidence[t].end() == nul_incidence[t].find(v))
+    {
+      return zero;
+    }
+
+  // quick return if the derivative has been registered
+  _Tderivmap::const_iterator i = derivatives[t].find(v);
+  if (i != derivatives[t].end())
+    return (*i).second;
+
+  int res = -1;
+  switch (terms[t].getCode())
+    {
+
+    case UMINUS:
+      {
+        int tmp = add_derivative(terms[t].getOp1(), v);
+        res = add_unary(UMINUS, tmp);
+        break;
+      }
+    case LOG:
+      {
+        int tmp = add_derivative(terms[t].getOp1(), v);
+        res = add_binary(DIVIDE, tmp, terms[t].getOp1());
+        break;
+      }
+    case EXP:
+      {
+        int tmp = add_derivative(terms[t].getOp1(), v);
+        res = add_binary(TIMES, t, tmp);
+        break;
+      }
+    case SIN:
+      {
+        int tmp = add_derivative(terms[t].getOp1(), v);
+        res = add_binary(TIMES, add_unary(COS, terms[t].getOp1()), tmp);
+        break;
+      }
+    case COS:
+      {
+        int tmp = add_derivative(terms[t].getOp1(), v);
+        res = add_unary(UMINUS, add_binary(TIMES, add_unary(SIN, terms[t].getOp1()), tmp));
+        break;
+      }
+    case TAN:
+      {
+        int tmp = add_derivative(terms[t].getOp1(), v);
+        int tmp2 = add_unary(COS, terms[t].getOp1());
+        res = add_binary(DIVIDE, tmp, add_binary(TIMES, tmp2, tmp2));
+        break;
+      }
+    case SQRT:
+      {
+        int tmp = add_derivative(terms[t].getOp1(), v);
+        res = add_binary(DIVIDE, tmp,
+                         add_binary(PLUS, t, t));
+        break;
+      }
+    case ERF:
+      {
+        int tmp = add_binary(TIMES, terms[t].getOp1(), terms[t].getOp1());
+        tmp = add_unary(UMINUS, tmp);
+        tmp = add_unary(EXP, tmp);
+        int der = add_derivative(terms[t].getOp1(), v);
+        tmp = add_binary(TIMES, tmp, der);
+        res = add_binary(TIMES, two_over_pi, tmp);
+        break;
+      }
+    case ERFC:
+      {
+        int tmp = add_binary(TIMES, terms[t].getOp1(), terms[t].getOp1());
+        tmp = add_unary(UMINUS, tmp);
+        tmp = add_unary(EXP, tmp);
+        int der = add_derivative(terms[t].getOp1(), v);
+        tmp = add_binary(TIMES, tmp, der);
+        tmp = add_binary(TIMES, two_over_pi, tmp);
+        res = add_unary(UMINUS, tmp);
+        break;
+      }
+    case PLUS:
+      {
+        int tmp1 = add_derivative(terms[t].getOp1(), v);
+        int tmp2 = add_derivative(terms[t].getOp2(), v);
+        res = add_binary(PLUS, tmp1, tmp2);
+        break;
+      }
+    case MINUS:
+      {
+        int tmp1 = add_derivative(terms[t].getOp1(), v);
+        int tmp2 = add_derivative(terms[t].getOp2(), v);
+        res = add_binary(MINUS, tmp1, tmp2);
+        break;
+      }
+    case TIMES:
+      {
+        int tmp1 = add_derivative(terms[t].getOp1(), v);
+        int tmp2 = add_derivative(terms[t].getOp2(), v);
+        int res1 = add_binary(TIMES, terms[t].getOp1(), tmp2);
+        int     res2 = add_binary(TIMES, tmp1, terms[t].getOp2());
+        res = add_binary(PLUS, res1, res2);
+        break;
+      }
+    case DIVIDE:
+      {
+        int tmp1 = add_derivative(terms[t].getOp1(), v);
+        int tmp2 = add_derivative(terms[t].getOp2(), v);
+        if (tmp2 == zero)
+          res = add_binary(DIVIDE, tmp1, terms[t].getOp2());
+        else
+          {
+            int nom = add_binary(MINUS,
+                                 add_binary(TIMES, tmp1, terms[t].getOp2()),
+                                 add_binary(TIMES, tmp2, terms[t].getOp1()));
+            int den = add_binary(TIMES, terms[t].getOp2(), terms[t].getOp2());
+            res = add_binary(DIVIDE, nom, den);
+          }
+        break;
+      }
+    case POWER:
+      {
+        int tmp1 = add_derivative(terms[t].getOp1(), v);
+        int tmp2 = add_derivative(terms[t].getOp2(), v);
+        int s1 = add_binary(TIMES, tmp2,
+                            add_binary(TIMES, t,
+                                       add_unary(LOG, terms[t].getOp1())));
+        int s2 = add_binary(TIMES, tmp1,
+                            add_binary(TIMES, terms[t].getOp2(),
+                                       add_binary(POWER, terms[t].getOp1(),
+                                                  add_binary(MINUS, terms[t].getOp2(), one))));
+        res = add_binary(PLUS, s1, s2);
+        break;
+      }
+    case NONE:
+      break;
+    }
+
+  if (res == -1)
+    throw ogu::Exception(__FILE__, __LINE__,
+                         "Unknown operation code.");
+
+  register_derivative(t, v, res);
+
+  return res;
+}
+
+int
+OperationTree::add_substitution(int t, const map<int, int> &subst)
+{
+  return add_substitution(t, subst, *this);
+}
+
+int
+OperationTree::add_substitution(int t, const map<int, int> &subst,
+                                const OperationTree &otree)
+{
+  // return substitution of t if it is in the map
+  map<int, int>::const_iterator it = subst.find(t);
+  if (subst.end() != it)
+    return (*it).second;
+
+  int nary = otree.terms[t].nary();
+  if (nary == 2)
+    {
+      // return the binary operation of the substituted terms
+      int t1 = add_substitution(otree.terms[t].getOp1(), subst, otree);
+      int t2 = add_substitution(otree.terms[t].getOp2(), subst, otree);
+      return add_binary(otree.terms[t].getCode(), t1, t2);
+    }
+  else if (nary == 1)
+    {
+      // return the unary operation of the substituted term
+      int t1 = add_substitution(otree.terms[t].getOp1(), subst, otree);
+      return add_unary(otree.terms[t].getCode(), t1);
+    }
+  else
+    {
+      // if t is not the first num_constants, and otree is not this
+      // tree, then raise and exception. Otherwise return t, since
+      // it is either a special term (having the same semantics in
+      // both trees), or the trees are the same, hence t has the
+      // same semantics
+      if (t < num_constants || this == &otree)
+        return t;
+      else
+        {
+          throw ogu::Exception(__FILE__, __LINE__,
+                               "Incomplete substitution map in OperationTree::add_substitution");
+          return -1;
+        }
+    }
+}
+
+void
+OperationTree::nularify(int t)
+{
+  // remove the original operation from opmap
+  _Topmap::iterator it = opmap.find(terms[t]);
+  if (it != opmap.end())
+    opmap.erase(it);
+  // turn the operation to nulary
+  Operation nulary_op;
+  terms[t] = nulary_op;
+  // update last nulary
+  if (last_nulary < t)
+    last_nulary = t;
+  // update nul_incidence information for all terms including t
+  update_nul_incidence_after_nularify(t);
+}
+
+void
+OperationTree::register_derivative(int t, int v, int tder)
+{
+  // todo: might check that the insert inserts a new pair
+  derivatives[t].insert(_Tderivmap::value_type(v, tder));
+}
+
+unordered_set<int>
+OperationTree::select_terms(int t, const opselector &sel) const
+{
+  unordered_set<int> subterms;
+  select_terms(t, sel, subterms);
+  return subterms;
+}
+
+void
+OperationTree::select_terms(int t, const opselector &sel, unordered_set<int> &subterms) const
+{
+  const Operation &op = terms[t];
+
+  if (sel(t))
+    subterms.insert(t);
+  else
+    if (op.nary() == 2)
+      {
+        select_terms(op.getOp1(), sel, subterms);
+        select_terms(op.getOp2(), sel, subterms);
+      }
+    else if (op.nary() == 1)
+      {
+        select_terms(op.getOp1(), sel, subterms);
+      }
+}
+
+unordered_set<int>
+OperationTree::select_terms_inv(int t, const opselector &sel) const
+{
+  unordered_set<int> subterms;
+  select_terms_inv(t, sel, subterms);
+  return subterms;
+}
+
+bool
+OperationTree::select_terms_inv(int t, const opselector &sel, unordered_set<int> &subterms) const
+{
+  const Operation &op = terms[t];
+
+  if (op.nary() == 2)
+    {
+      bool a1 = select_terms_inv(op.getOp1(), sel, subterms);
+      bool a2 = select_terms_inv(op.getOp2(), sel, subterms);
+      if (a1 && a2 && sel(t))
+        {
+          subterms.insert(t);
+          return true;
+        }
+    }
+  else if (op.nary() == 1)
+    {
+      bool a1 = select_terms_inv(op.getOp1(), sel, subterms);
+      if (a1 && sel(t))
+        {
+          subterms.insert(t);
+          return true;
+        }
+    }
+  else
+    {
+      if (sel(t))
+        {
+          subterms.insert(t);
+          return true;
+        }
+    }
+
+  return false;
+}
+
+void
+OperationTree::forget_derivative_maps()
+{
+  for (unsigned int i = 0; i < derivatives.size(); i++)
+    derivatives[i].clear();
+}
+
+void
+OperationTree::print_operation_tree(int t, FILE *fd, OperationFormatter &f) const
+{
+  f.format(terms[t], t, fd);
+}
+
+void
+OperationTree::print_operation(int t) const
+{
+  DefaultOperationFormatter dof(*this);
+  print_operation_tree(t, stdout, dof);
+}
+
+void
+OperationTree::update_nul_incidence_after_nularify(int t)
+{
+  unordered_set<int> updated;
+  for (int tnode = num_constants; tnode < (int) terms.size(); tnode++)
+    {
+      const Operation &op = terms[tnode];
+      if (op.nary() == 2)
+        {
+          int op1 = op.getOp1();
+          int op2 = op.getOp2();
+          if (op1 >= tnode || op2 >= tnode)
+            throw ogu::Exception(__FILE__, __LINE__,
+                                 "Tree disorder asserted");
+          bool updated1 = (updated.end() != updated.find(op1));
+          bool updated2 = (updated.end() != updated.find(op2));
+          if (updated1 || updated2)
+            {
+              nul_incidence[tnode] = nul_incidence[op1];
+              nul_incidence[tnode].insert(nul_incidence[op2].begin(), nul_incidence[op2].end());
+              updated.insert(tnode);
+            }
+        }
+      else if (op.nary() == 1)
+        {
+          int op1 = op.getOp1();
+          if (op1 >= tnode)
+            throw ogu::Exception(__FILE__, __LINE__,
+                                 "Tree disorder asserted");
+          bool updated1 = (updated.end() != updated.find(op1));
+          if (updated1)
+            {
+              nul_incidence[tnode] = nul_incidence[op1];
+              updated.insert(tnode);
+            }
+        }
+      else if (op.nary() == 0)
+        {
+          if (tnode == t)
+            {
+              nul_incidence[tnode].clear();
+              nul_incidence[tnode].insert(tnode);
+              updated.insert(tnode);
+            }
+        }
+    }
+}
+
+EvalTree::EvalTree(const OperationTree &ot, int last)
+  : otree(ot),
+    values(new double[(last == -1) ? ot.terms.size() : last+1]),
+    flags(new bool[(last == -1) ? ot.terms.size() : last+1]),
+    last_operation((last == -1) ? ot.terms.size()-1 : last)
+{
+  if (last_operation < OperationTree::num_constants-1
+      || last_operation > (int) ot.terms.size()-1)
+    throw ogu::Exception(__FILE__, __LINE__,
+                         "Wrong last in EvalTree constructor.");
+
+  values[0] = 0.0;
+  flags[0] = true;
+  values[1] = 1.0;
+  flags[1] = true;
+  values[2] = std::numeric_limits<double>::quiet_NaN();
+  flags[2] = true;
+  values[3] = 2.0/sqrt(M_PI);
+  flags[3] = true;
+  // this sets from num_constants on
+  reset_all();
+}
+
+void
+EvalTree::reset_all()
+{
+  for (int i = OperationTree::num_constants; i <= last_operation; i++)
+    flags[i] = false;
+}
+
+void
+EvalTree::set_nulary(int t, double val)
+{
+  if (t < 0 || t > last_operation)
+    throw ogu::Exception(__FILE__, __LINE__,
+                         "The tree index out of bounds in EvalTree::set_nulary");
+  if (t < OperationTree::num_constants || otree.terms[t].nary() != 0)
+    throw ogu::Exception(__FILE__, __LINE__,
+                         "The term is not nulary assignable in EvalTree::set_nulary");
+
+  values[t] = val;
+  flags[t] = true;
+}
+
+double
+EvalTree::eval(int t)
+{
+  if (t < 0 || t > last_operation)
+    throw ogu::Exception(__FILE__, __LINE__,
+                         "The tree index out of bounds in EvalTree::eval");
+  if (otree.terms[t].nary() == 0 && flags[t] == false)
+    throw ogu::Exception(__FILE__, __LINE__,
+                         "Nulary term has not been assigned a value in EvalTree::eval");
+
+  if (!flags[t])
+    {
+      const Operation &op = otree.terms[t];
+      if (op.nary() == 1)
+        {
+          double r1 = eval(op.getOp1());
+          double res;
+          if (op.getCode() == UMINUS)
+            res = -r1;
+          else if (op.getCode() == LOG)
+            res = log(r1);
+          else if (op.getCode() == EXP)
+            res = exp(r1);
+          else if (op.getCode() == SIN)
+            res = sin(r1);
+          else if (op.getCode() == COS)
+            res = cos(r1);
+          else if (op.getCode() == TAN)
+            res = tan(r1);
+          else if (op.getCode() == SQRT)
+            res = sqrt(r1);
+          else if (op.getCode() == ERF)
+            res = 1-erffc(r1);
+          else if (op.getCode() == ERFC)
+            res = erffc(r1);
+          else
+            {
+              throw ogu::Exception(__FILE__, __LINE__,
+                                   "Unknown unary operation code in EvalTree::eval");
+              res = 0.0;
+            }
+          values[t] = res;
+          flags[t] = true;
+        }
+      else if (op.nary() == 2)
+        {
+          double res;
+          if (op.getCode() == PLUS)
+            {
+              double r1 = eval(op.getOp1());
+              double r2 = eval(op.getOp2());
+              res = r1 + r2;
+            }
+          else if (op.getCode() == MINUS)
+            {
+              double r1 = eval(op.getOp1());
+              double r2 = eval(op.getOp2());
+              res = r1 - r2;
+            }
+          else if (op.getCode() == TIMES)
+            {
+              // pickup less complex formula first
+              unsigned int nul1 = otree.nulary_of_term(op.getOp1()).size();
+              unsigned int nul2 = otree.nulary_of_term(op.getOp2()).size();
+              if (nul1 < nul2)
+                {
+                  double r1 = eval(op.getOp1());
+                  if (r1 == 0.0)
+                    res = 0.0;
+                  else
+                    {
+                      double r2 = eval(op.getOp2());
+                      res = r1 * r2;
+                    }
+                }
+              else
+                {
+                  double r2 = eval(op.getOp2());
+                  if (r2 == 0)
+                    res = 0.0;
+                  else
+                    {
+                      double r1 = eval(op.getOp1());
+                      res = r1*r2;
+                    }
+                }
+            }
+          else if (op.getCode() == DIVIDE)
+            {
+              double r1 = eval(op.getOp1());
+              if (r1 == 0)
+                res = 0.0;
+              else
+                {
+                  double r2 = eval(op.getOp2());
+                  res = r1 / r2;
+                }
+            }
+          else if (op.getCode() == POWER)
+            {
+              // suppose that more complex is the first op in average
+              double r2 = eval(op.getOp2());
+              if (r2 == 0.0)
+                res = 1.0;
+              else
+                {
+                  double r1 = eval(op.getOp1());
+                  res = pow(r1, r2);
+                }
+            }
+          else
+            {
+              throw ogu::Exception(__FILE__, __LINE__,
+                                   "Unknown binary operation code in EvalTree::eval");
+              res = 0.0;
+            }
+          values[t] = res;
+          flags[t] = true;
+        }
+      return values[t];
+    }
+
+  // if (! std::isfinite(values[t]))
+  //	printf("Tree value t=%d is not finite = %f\n", t, values[t]);
+
+  return values[t];
+}
+
+void
+EvalTree::print() const
+{
+  printf("last_op=%d\n", last_operation);
+  printf("         0     1     2     3     4     5     6     7     8     9\n");
+  printf("----------------------------------------------------------------\n");
+  for (int i = 0; i <= (last_operation+1)/10; i++)
+    {
+      printf("%-3d|", i);
+      int j = 0;
+      while (j < 10 && 10*i+j < last_operation+1)
+        {
+          int k = 10*i+j;
+          if (flags[k])
+            printf(" %5.1g", values[k]);
+          else
+            printf(" -----");
+          j++;
+        }
+      printf("\n");
+    }
+}
+
+void
+DefaultOperationFormatter::format(const Operation &op, int t, FILE *fd)
+{
+  // add to the stop_set
+  if (stop_set.end() == stop_set.find(t))
+    stop_set.insert(t);
+  else
+    return;
+
+  // call recursively non-nulary terms of the operation
+  if (op.nary() == 2)
+    {
+      int t1 = op.getOp1();
+      const Operation &op1 = otree.terms[t1];
+      int t2 = op.getOp2();
+      const Operation &op2 = otree.terms[t2];
+      if (op1.nary() > 0)
+        format(op1, t1, fd);
+      if (op2.nary() > 0)
+        format(op2, t2, fd);
+    }
+  if (op.nary() == 1)
+    {
+      int t1 = op.getOp1();
+      const Operation &op1 = otree.terms[t1];
+      if (op1.nary() > 0)
+        format(op1, t1, fd);
+    }
+
+  // print 'term ='
+  format_term(t, fd);
+  fprintf(fd, " = ");
+  if (op.nary() == 0)
+    {
+      format_nulary(t, fd);
+    }
+  else if (op.nary() == 1)
+    {
+      int t1 = op.getOp1();
+      const Operation &op1 = otree.terms[t1];
+      const char *opname = "unknown";
+      switch (op.getCode())
+        {
+        case UMINUS:
+          opname = "-";
+          break;
+        case LOG:
+          opname = "log";
+          break;
+        case EXP:
+          opname = "exp";
+          break;
+        case SIN:
+          opname = "sin";
+          break;
+        case COS:
+          opname = "cos";
+          break;
+        case TAN:
+          opname = "tan";
+          break;
+        case SQRT:
+          opname = "sqrt";
+          break;
+        case ERF:
+          opname = "erf";
+          break;
+        case ERFC:
+          opname = "erfc";
+          break;
+        default:
+          break;
+        }
+      fprintf(fd, "%s(", opname);
+      if (op1.nary() == 0)
+        format_nulary(t1, fd);
+      else
+        format_term(t1, fd);
+      fprintf(fd, ")");
+    }
+  else
+    {
+      int t1 = op.getOp1();
+      const Operation &op1 = otree.terms[t1];
+      int t2 = op.getOp2();
+      const Operation &op2 = otree.terms[t2];
+      const char *opname = "unknown";
+      switch (op.getCode())
+        {
+        case PLUS:
+          opname = "+";
+          break;
+        case MINUS:
+          opname = "-";
+          break;
+        case TIMES:
+          opname = "*";
+          break;
+        case DIVIDE:
+          opname = "/";
+          break;
+        case POWER:
+          opname = "^";
+          break;
+        default:
+          break;
+        }
+      if (op1.nary() == 0)
+        format_nulary(t1, fd);
+      else
+        format_term(t1, fd);
+      fprintf(fd, " %s ", opname);
+      if (op2.nary() == 0)
+        format_nulary(t2, fd);
+      else
+        format_term(t2, fd);
+    }
+
+  print_delim(fd);
+
+}
+
+void
+DefaultOperationFormatter::format_term(int t, FILE *fd) const
+{
+  fprintf(fd, "$%d", t);
+}
+
+void
+DefaultOperationFormatter::format_nulary(int t, FILE *fd) const
+{
+  if (t == OperationTree::zero)
+    fprintf(fd, "0");
+  else if (t == OperationTree::one)
+    fprintf(fd, "1");
+  else if (t == OperationTree::nan)
+    fprintf(fd, "NaN");
+  else
+    fprintf(fd, "$%d", t);
+}
+
+void
+DefaultOperationFormatter::print_delim(FILE *fd) const
+{
+  fprintf(fd, ";\n");
+}
+
+std::string
+OperationStringConvertor::convert(const Operation &op, int t) const
+{
+  if (op.nary() == 0)
+    {
+      if (t < OperationTree::num_constants)
+        if (t == OperationTree::zero)
+          return std::string("0");
+        else if (t == OperationTree::one)
+          return std::string("1");
+        else if (t == OperationTree::nan)
+          return std::string("NaN");
+        else if (t == OperationTree::two_over_pi)
+          {
+            char buf[100];
+            sprintf(buf, "%20.16g", 2.0/std::sqrt(M_PI));
+            return std::string(buf);
+          }
+        else
+          {
+            return std::string("error!error");
+          }
+      else
+        return nulsc.convert(t);
+    }
+  else if (op.nary() == 1)
+    {
+      int t1 = op.getOp1();
+      const Operation &op1 = otree.operation(t1);
+      const char *opname = "unknown";
+      switch (op.getCode())
+        {
+        case UMINUS:
+          opname = "-";
+          break;
+        case LOG:
+          opname = "log";
+          break;
+        case EXP:
+          opname = "exp";
+          break;
+        case SIN:
+          opname = "sin";
+          break;
+        case COS:
+          opname = "cos";
+          break;
+        case TAN:
+          opname = "tan";
+          break;
+        case SQRT:
+          opname = "sqrt";
+          break;
+        case ERF:
+          opname = "erf";
+          break;
+        case ERFC:
+          opname = "erfc";
+          break;
+        default:
+          break;
+        }
+      std::string s1 = convert(op1, t1);
+      return std::string(opname) + "(" + s1 + ")";
+    }
+  else
+    {
+      int t1 = op.getOp1();
+      const Operation &op1 = otree.operation(t1);
+      int t2 = op.getOp2();
+      const Operation &op2 = otree.operation(t2);
+      const char *opname = "unknown";
+      switch (op.getCode())
+        {
+        case PLUS:
+          opname = "+";
+          break;
+        case MINUS:
+          opname = "-";
+          break;
+        case TIMES:
+          opname = "*";
+          break;
+        case DIVIDE:
+          opname = "/";
+          break;
+        case POWER:
+          opname = "^";
+          break;
+        default:
+          break;
+        }
+      // decide about parenthesis
+      bool op1_par = true;
+      bool op2_par = true;
+      if (op.getCode() == PLUS)
+        {
+          op1_par = false;
+          op2_par = false;
+        }
+      else if (op.getCode() == MINUS)
+        {
+          op1_par = false;
+          if (op2.getCode() != MINUS && op2.getCode() != PLUS)
+            op2_par = false;
+        }
+      else
+        {
+          if (op1.nary() < 2)
+            op1_par = false;
+          if (op2.nary() < 2)
+            op2_par = false;
+        }
+
+      std::string res;
+      if (op1_par)
+        res += "(";
+      res += convert(op1, t1);
+      if (op1_par)
+        res += ")";
+      res += " ";
+      res += opname;
+      res += " ";
+      if (op2_par)
+        res += "(";
+      res += convert(op2, t2);
+      if (op2_par)
+        res += ")";
+
+      return res;
+    }
+}
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/dynare++/parser/cc/tree.cpp b/dynare++/parser/cc/tree.cpp
deleted file mode 100644
index 3ab37e77696896eb1183c7f0a95dd91e00a0c24d..0000000000000000000000000000000000000000
--- a/dynare++/parser/cc/tree.cpp
+++ /dev/null
@@ -1,928 +0,0 @@
-// Copyright (C) 2005-2011, Ondra Kamenik
-
-
-#include "utils/cc/exception.h"
-
-#include "tree.h"
-
-#include <cstdlib>
-
-#include <cmath>
-#include <limits>
-
-#ifdef __MINGW32__
-#define __CROSS_COMPILATION__
-#endif
-
-#ifdef __MINGW64__
-#define __CROSS_COMPILATION__
-#endif
-
-#ifdef __CROSS_COMPILATION__
-#define M_PI 3.14159265358979323846
-#endif
-
-
-using namespace ogp;
-
-
-/** Here we just implement complementary error function without
- * declaring it for uses from outside this unit. The implementation is taken from "Numerical Recipes in C" 2nd ed. 1992 p. 221, */
-double erffc(double x)
-{
-	double z = std::abs(x);
-	double t = 1/(1+0.5*z);
-	double r = t*exp(-z*z-1.26551223+t*(1.00002368+t*(0.37409196+t*(0.09678418+t*(-0.18628806+t*(0.27886807+t*(-1.13520398+t*(1.48851587+t*(-0.82215223+t*0.17087277)))))))));
-	return x >= 0 ? r : 2-r;
-}
-
-/** Here we initialize OperationTree to contain only zero, one, nan
- * and two_over_pi terms. */
-OperationTree::OperationTree()
-{
-	last_nulary = -1;
-	// allocate space for the constants
-	for (int i = 0; i < num_constants; i++)
-		add_nulary();
-}
-
-int OperationTree::add_nulary()
-{
-	int op = terms.size();
-	Operation nulary;
-	terms.push_back(nulary);
-	_Tintset s;
-	s.insert(op);
-	nul_incidence.push_back(s);
-	_Tderivmap empty;
-	derivatives.push_back(empty);
-	last_nulary = op;
-	return op;
-}
-
-int OperationTree::add_unary(code_t code, int op)
-{
-	if (op == zero &&
-		(code == UMINUS ||
-		 code == SIN ||
-		 code == TAN ||
-		 code == SQRT ||
-		 code == ERF))
-		return zero;
-	if ((op == zero && code == LOG) || op == nan)
-		return nan;
-	if (op == zero && (code == EXP ||
-					   code == COS ||
-					   code == ERFC))
-		return one;
-
-	Operation unary(code, op);
-	_Topmap::const_iterator i = ((const _Topmap&)opmap).find(unary);
-	if (i == opmap.end()) {
-		int newop = terms.size();
-		// add to the terms
-		terms.push_back(unary);
-		// copy incidence of the operand
-		nul_incidence.push_back(nul_incidence[op]);
-		// insert it to opmap
-		opmap.insert(_Topval(unary, newop));
-		// add empty map of derivatives
-		_Tderivmap empty;
-		derivatives.push_back(empty);
-		return newop;
-	}
-	return (*i).second;
-}
-
-int OperationTree::add_binary(code_t code, int op1, int op2)
-{
-	// quick exits for special values
-	if (op1 == nan || op2 == nan)
-		return nan;
-	// for plus
-	if (code == PLUS) {
-		if (op1 == zero && op2 == zero)
-			return zero;
-		else if (op1 == zero)
-			return op2;
-		else if (op2 == zero)
-			return op1;
-    }
-	// for minus
-	if (code == MINUS) {
-		if (op1 == zero && op2 == zero)
-			return zero;
-		else if (op1 == zero)
-			return add_unary(UMINUS, op2);
-		else if (op2 == zero)
-			return op1;
-    }
-	// for times
-	if (code == TIMES) {
-		if (op1 == zero || op2 == zero)
-			return zero;
-		else if (op1 == one)
-			return op2;
-		else if (op2 == one)
-			return op1;
-    }
-	// for divide
-	if (code == DIVIDE) {
-		if (op1 == op2)
-			return one;
-		else if (op1 == zero)
-			return zero;
-		else if (op2 == zero)
-			return nan;
-    }
-	// for power
-	if (code == POWER) {
-		if (op1 == zero && op2 == zero)
-			return nan;
-		else if (op1 == zero)
-			return zero;
-		else if (op2 == zero)
-			return one;
-		else if (op1 == one)
-			return one;
-		else if (op2 == one)
-			return op1;
-    }
-
-	// order operands of commutative operations
-	if (code == TIMES || code == PLUS)
-		if (op1 > op2) {
-			int tmp = op1;
-			op1 = op2;
-			op2 = tmp;
-		}
-
-	// construct operation and check/add it
-	Operation binary(code, op1, op2);
-	_Topmap::const_iterator i = ((const _Topmap&)opmap).find(binary);
-	if (i == opmap.end()) {
-		int newop = terms.size();
-		terms.push_back(binary);
-		// sum both sets of incidenting nulary operations
-		nul_incidence.push_back(nul_incidence[op1]);
-		nul_incidence.back().insert(nul_incidence[op2].begin(), nul_incidence[op2].end());
-		// add to opmap
-		opmap.insert(_Topval(binary, newop));
-		// add empty map of derivatives
-		_Tderivmap empty;
-		derivatives.push_back(empty);
-		return newop;
-	}
-	return (*i).second;
-}
-
-int OperationTree::add_derivative(int t, int v)
-{
-	if (t < 0 || t >= (int) terms.size())
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "Wrong value for tree index in OperationTree::add_derivative");
-
-	// quick returns for nulary terms or empty incidence
-	if (terms[t].nary() == 0 && t != v) {
-		return zero;
-	}
-	if (terms[t].nary() == 0 && t == v) {
-		return one;
-	}
-	if (nul_incidence[t].end() == nul_incidence[t].find(v)) {
-		return zero;
-	}
-
-	// quick return if the derivative has been registered
-	_Tderivmap::const_iterator i = derivatives[t].find(v);
-	if (i != derivatives[t].end())
-		return (*i).second;
-
-	int res = -1;
-	switch (terms[t].getCode()) {
-
-	case UMINUS:
-	{
-		int tmp = add_derivative(terms[t].getOp1(), v);
-		res = add_unary(UMINUS, tmp);
-		break;
-	}
-	case LOG:
-	{
-		int tmp = add_derivative(terms[t].getOp1(), v);
-		res = add_binary(DIVIDE, tmp, terms[t].getOp1());
-		break;
-	}
-	case EXP:
-	{
-		int tmp = add_derivative(terms[t].getOp1(), v);
-		res = add_binary(TIMES, t, tmp);
-		break;
-	}
-	case SIN:
-	{
-		int tmp = add_derivative(terms[t].getOp1(), v);
-		res = add_binary(TIMES, add_unary(COS, terms[t].getOp1()), tmp);
-		break;
-	}
-	case COS:
-	{
-		int tmp = add_derivative(terms[t].getOp1(), v);
-		res = add_unary(UMINUS, add_binary(TIMES, add_unary(SIN, terms[t].getOp1()), tmp));
-		break;
-	}
-	case TAN:
-	{
-		int tmp = add_derivative(terms[t].getOp1(), v);
-		int tmp2 = add_unary(COS, terms[t].getOp1());
-		res = add_binary(DIVIDE, tmp, add_binary(TIMES, tmp2, tmp2));
-		break;
-	}
-	case SQRT:
-	{
-		int tmp = add_derivative(terms[t].getOp1(), v);
-		res = add_binary(DIVIDE, tmp,
-						 add_binary(PLUS, t, t));
-		break;
-	}
-	case ERF:
-	{
-		int tmp = add_binary(TIMES, terms[t].getOp1(), terms[t].getOp1());
-		tmp = add_unary(UMINUS, tmp);
-		tmp = add_unary(EXP, tmp);
-		int der = add_derivative(terms[t].getOp1(), v);
-		tmp = add_binary(TIMES, tmp, der);
-		res = add_binary(TIMES, two_over_pi, tmp);
-		break;
-	}
-	case ERFC:
-	{
-		int tmp = add_binary(TIMES, terms[t].getOp1(), terms[t].getOp1());
-		tmp = add_unary(UMINUS, tmp);
-		tmp = add_unary(EXP, tmp);
-		int der = add_derivative(terms[t].getOp1(), v);
-		tmp = add_binary(TIMES, tmp, der);
-		tmp = add_binary(TIMES, two_over_pi, tmp);
-		res = add_unary(UMINUS, tmp);
-		break;
-	}
-	case PLUS:
-	{
-		int tmp1 = add_derivative(terms[t].getOp1(), v);
-		int tmp2 = add_derivative(terms[t].getOp2(), v);
-		res = add_binary(PLUS, tmp1, tmp2);
-		break;
-	}
-	case MINUS:
-	{
-		int tmp1 = add_derivative(terms[t].getOp1(), v);
-		int tmp2 = add_derivative(terms[t].getOp2(), v);
-		res = add_binary(MINUS, tmp1, tmp2);
-		break;
-	}
-	case TIMES:
-	{
-		int tmp1 = add_derivative(terms[t].getOp1(), v);
-		int tmp2 = add_derivative(terms[t].getOp2(), v);
-		int res1 = add_binary(TIMES, terms[t].getOp1(), tmp2);
-		int	res2 = add_binary(TIMES, tmp1, terms[t].getOp2());
-		res = add_binary(PLUS, res1, res2);
-		break;
-	}
-	case DIVIDE:
-	{
-		int tmp1 = add_derivative(terms[t].getOp1(), v);
-		int tmp2 = add_derivative(terms[t].getOp2(), v);
-		if (tmp2 == zero)
-			res = add_binary(DIVIDE, tmp1, terms[t].getOp2());
-		else {
-			int nom = add_binary(MINUS,
-								 add_binary(TIMES, tmp1, terms[t].getOp2()),
-								 add_binary(TIMES, tmp2, terms[t].getOp1()));
-			int den = add_binary(TIMES, terms[t].getOp2(), terms[t].getOp2());
-			res = add_binary(DIVIDE, nom, den);
-		}
-		break;
-	}
-	case POWER:
-	{
-		int tmp1 = add_derivative(terms[t].getOp1(), v);
-		int tmp2 = add_derivative(terms[t].getOp2(), v);
-		int s1 = add_binary(TIMES, tmp2,
-							add_binary(TIMES, t,
-									   add_unary(LOG, terms[t].getOp1())));
-		int s2 = add_binary(TIMES, tmp1,
-							add_binary(TIMES, terms[t].getOp2(),
-									   add_binary(POWER, terms[t].getOp1(),
-												  add_binary(MINUS, terms[t].getOp2(), one))));
-		res = add_binary(PLUS, s1, s2);
-		break;
-	}
-	case NONE:
-		break;
-	}
-
-	if (res == -1)
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "Unknown operation code.");
-
-	register_derivative(t, v, res);
-
-	return res;
-}
-
-int OperationTree::add_substitution(int t, const map<int,int>& subst)
-{
-	return add_substitution(t, subst, *this); 
-}
-
-int OperationTree::add_substitution(int t, const map<int,int>& subst,
-									const OperationTree& otree)
-{
-	// return substitution of t if it is in the map
-	map<int,int>::const_iterator it = subst.find(t);
-	if (subst.end() != it)
-		return (*it).second;
-
-	int nary = otree.terms[t].nary();
-	if (nary == 2) {
-		// return the binary operation of the substituted terms
-		int t1 = add_substitution(otree.terms[t].getOp1(), subst, otree);
-		int t2 = add_substitution(otree.terms[t].getOp2(), subst, otree);
-		return add_binary(otree.terms[t].getCode(), t1, t2);
-	} else if (nary == 1) {
-		// return the unary operation of the substituted term
-		int t1 = add_substitution(otree.terms[t].getOp1(), subst, otree);
-		return add_unary(otree.terms[t].getCode(), t1);
-	} else {
-		// if t is not the first num_constants, and otree is not this
-		// tree, then raise and exception. Otherwise return t, since
-		// it is either a special term (having the same semantics in
-		// both trees), or the trees are the same, hence t has the
-		// same semantics
-		if (t < num_constants || this == &otree)
-			return t;
-		else {
-			throw ogu::Exception(__FILE__,__LINE__,
-								 "Incomplete substitution map in OperationTree::add_substitution");
-			return -1;
-		}
-	}
-}
-
-
-void OperationTree::nularify(int t)
-{
-	// remove the original operation from opmap
-	_Topmap::iterator it = opmap.find(terms[t]);
-	if (it != opmap.end())
-		opmap.erase(it);
-	// turn the operation to nulary
-	Operation nulary_op;
-	terms[t] = nulary_op;
-	// update last nulary
-	if (last_nulary < t)
-		last_nulary = t;
-	// update nul_incidence information for all terms including t
-	update_nul_incidence_after_nularify(t);
-}
-
-void OperationTree::register_derivative(int t, int v, int tder)
-{
-	// todo: might check that the insert inserts a new pair
-	derivatives[t].insert(_Tderivmap::value_type(v, tder));
-}
-
-unordered_set<int> OperationTree::select_terms(int t, const opselector& sel) const
-{
-	unordered_set<int> subterms;
-	select_terms(t, sel, subterms);
-	return subterms;
-}
-
-void OperationTree::select_terms(int t, const opselector& sel, unordered_set<int>& subterms) const
-{
-	const Operation& op = terms[t];
-
-	if (sel(t))
-		subterms.insert(t);
-	else
-		if (op.nary() == 2) {
-			select_terms(op.getOp1(), sel, subterms);
-			select_terms(op.getOp2(), sel, subterms);
-		} else if (op.nary() == 1) {
-			select_terms(op.getOp1(), sel, subterms);
-		}
-}
-
-unordered_set<int> OperationTree::select_terms_inv(int t, const opselector& sel) const
-{
-	unordered_set<int> subterms;
-	select_terms_inv(t, sel, subterms);
-	return subterms;
-}
-
-bool OperationTree::select_terms_inv(int t, const opselector& sel, unordered_set<int>& subterms) const
-{
-	const Operation& op = terms[t];
-
-	if (op.nary() == 2) {
-		bool a1 = select_terms_inv(op.getOp1(), sel, subterms);
-		bool a2 = select_terms_inv(op.getOp2(), sel, subterms);
-		if (a1 && a2 && sel(t)) {
-			subterms.insert(t);
-			return true;
-		}
-	} else if (op.nary() == 1) {
-		bool a1 = select_terms_inv(op.getOp1(), sel, subterms);
-		if (a1 && sel(t)) {
-			subterms.insert(t);
-			return true;
-		}
-	} else {
-		if (sel(t)) {
-			subterms.insert(t);
-			return true;
-		}
-	}
-
-	return false;
-}
-
-void OperationTree::forget_derivative_maps()
-{
-	for (unsigned int i = 0; i < derivatives.size(); i++)
-		derivatives[i].clear();
-}
-
-
-void OperationTree::print_operation_tree(int t, FILE* fd, OperationFormatter& f) const
-{
-	f.format(terms[t], t, fd);
-}
-
-void OperationTree::print_operation(int t) const
-{
-	DefaultOperationFormatter dof(*this);
-	print_operation_tree(t, stdout, dof);
-}
-
-void OperationTree::update_nul_incidence_after_nularify(int t)
-{
-	unordered_set<int> updated;
-	for (int tnode = num_constants; tnode < (int)terms.size(); tnode++) {
-		const Operation& op = terms[tnode];
-		if (op.nary() == 2) {
-			int op1 = op.getOp1();
-			int op2 = op.getOp2();
-			if (op1 >= tnode || op2 >= tnode)
-				throw ogu::Exception(__FILE__,__LINE__,
-									 "Tree disorder asserted");
-			bool updated1 = (updated.end() != updated.find(op1));
-			bool updated2 = (updated.end() != updated.find(op2));
-			if (updated1 || updated2) {
-				nul_incidence[tnode] = nul_incidence[op1];
-				nul_incidence[tnode].insert(nul_incidence[op2].begin(), nul_incidence[op2].end());
-				updated.insert(tnode);
-			}
-		} else if (op.nary() == 1) {
-			int op1 = op.getOp1();
-			if (op1 >= tnode)
-				throw ogu::Exception(__FILE__,__LINE__,
-									 "Tree disorder asserted");
-			bool updated1 = (updated.end() != updated.find(op1));
-			if (updated1) {
-				nul_incidence[tnode] = nul_incidence[op1];
-				updated.insert(tnode);
-			}
-		} else if (op.nary() == 0) {
-			if (tnode == t) {
-				nul_incidence[tnode].clear();
-				nul_incidence[tnode].insert(tnode);
-				updated.insert(tnode);
-			}
-		}
-	}
-}
-
-
-EvalTree::EvalTree(const OperationTree& ot, int last)
-	: otree(ot),
-	  values(new double[(last==-1)? ot.terms.size() : last+1]),
-	  flags(new bool[(last==-1)? ot.terms.size() : last+1]),
-	  last_operation((last==-1)? ot.terms.size()-1 : last)
-{
-	if (last_operation < OperationTree::num_constants-1 ||
-		last_operation > (int)ot.terms.size()-1)
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "Wrong last in EvalTree constructor.");
-
-	values[0] = 0.0;
-	flags[0] = true;
-	values[1] = 1.0;
-	flags[1] = true;
-	values[2] = std::numeric_limits<double>::quiet_NaN();
-	flags[2] = true;
-	values[3] = 2.0/sqrt(M_PI);
-	flags[3] = true;
-	// this sets from num_constants on
-	reset_all();
-}
-
-void EvalTree::reset_all()
-{
-	for (int i = OperationTree::num_constants; i <= last_operation; i++)
-		flags[i] = false;
-}
-
-void EvalTree::set_nulary(int t, double val)
-{
-	if (t < 0 || t > last_operation)
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "The tree index out of bounds in EvalTree::set_nulary");
-	if (t < OperationTree::num_constants || otree.terms[t].nary() != 0)
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "The term is not nulary assignable in EvalTree::set_nulary");
-
-	values[t] = val;
-	flags[t] = true;
-}
-
-double EvalTree::eval(int t)
-{
-	if (t < 0 || t > last_operation)
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "The tree index out of bounds in EvalTree::eval");
-	if (otree.terms[t].nary() == 0 && flags[t] == false)
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "Nulary term has not been assigned a value in EvalTree::eval");
-
-	if (! flags[t]) {
-		const Operation& op = otree.terms[t];
-		if (op.nary() == 1) {
-			double r1 = eval(op.getOp1());
-			double res;
-			if (op.getCode() == UMINUS)
-				res = -r1;
-			else if (op.getCode() == LOG)
-				res = log(r1);
-			else if (op.getCode() == EXP)
-				res = exp(r1);
-			else if (op.getCode() == SIN)
-				res = sin(r1);
-			else if (op.getCode() == COS)
-				res = cos(r1);
-			else if (op.getCode() == TAN)
-				res = tan(r1);
-			else if (op.getCode() == SQRT)
-				res = sqrt(r1);
-			else if (op.getCode() == ERF)
-				res = 1-erffc(r1);
-			else if (op.getCode() == ERFC)
-				res = erffc(r1);
-			else {
-				throw ogu::Exception(__FILE__,__LINE__,
-									 "Unknown unary operation code in EvalTree::eval");
-				res = 0.0;
-			}
-			values[t] = res;
-			flags[t] = true;
-		} else if (op.nary() == 2) {
-			double res;
-			if (op.getCode() == PLUS) {
-				double r1 = eval(op.getOp1());
-				double r2 = eval(op.getOp2());
-				res = r1 + r2;
-			} else if (op.getCode() == MINUS) {
-				double r1 = eval(op.getOp1());
-				double r2 = eval(op.getOp2());
-				res = r1 - r2;
-			} else if (op.getCode() == TIMES) {
-				// pickup less complex formula first
-				unsigned int nul1 = otree.nulary_of_term(op.getOp1()).size();
-				unsigned int nul2 = otree.nulary_of_term(op.getOp2()).size();
-				if (nul1 < nul2) {
-					double r1 = eval(op.getOp1());
-					if (r1 == 0.0)
-						res = 0.0;
-					else {
-						double r2 = eval(op.getOp2());
-						res = r1 * r2;
-					}
-				} else {
-					double r2 = eval(op.getOp2());
-					if (r2 == 0)
-						res = 0.0;
-					else {
-						double r1 = eval(op.getOp1());
-						res = r1*r2;
-					}
-				}
-			} else if (op.getCode() == DIVIDE) {
-				double r1 = eval(op.getOp1());
-				if (r1 == 0)
-					res = 0.0;
-				else {
-					double r2 = eval(op.getOp2());
-					res = r1 / r2;
-				}
-			} else if (op.getCode() == POWER) {
-				// suppose that more complex is the first op in average
-				double r2 = eval(op.getOp2());
-				if (r2 == 0.0)
-					res = 1.0;
-				else {
-					double r1 = eval(op.getOp1());
-					res = pow(r1, r2);
-				}
-			} else {
-				throw ogu::Exception(__FILE__,__LINE__,
-									 "Unknown binary operation code in EvalTree::eval");
-				res = 0.0;
-			}
-			values[t] = res;
-			flags[t] = true;
-		}
-		return values[t];
-	}
-
-	// if (! std::isfinite(values[t]))
-	//	printf("Tree value t=%d is not finite = %f\n", t, values[t]);
-
-	return values[t];
-}
-
-void EvalTree::print() const
-{
-	printf("last_op=%d\n", last_operation);
-	printf("         0     1     2     3     4     5     6     7     8     9\n");
-	printf("----------------------------------------------------------------\n");
-	for (int i = 0; i <= (last_operation+1)/10; i++) {
-		printf("%-3d|", i);
-		int j = 0;
-		while (j < 10 && 10*i+j < last_operation+1) {
-			int k = 10*i+j;
-			if (flags[k])
-				printf(" %5.1g", values[k]);
-			else
-				printf(" -----");
-			j++;
-		}
-		printf("\n");
-	}
-}
-
-void DefaultOperationFormatter::format(const Operation& op, int t, FILE* fd)
-{
-	// add to the stop_set
-	if (stop_set.end() == stop_set.find(t))
-		stop_set.insert(t);
-	else
-		return;
-
-	// call recursively non-nulary terms of the operation
-	if (op.nary() == 2) {
-		int t1 = op.getOp1();
-		const Operation& op1 = otree.terms[t1];
-		int t2 = op.getOp2();
-		const Operation& op2 = otree.terms[t2];
-		if (op1.nary() > 0)
-			format(op1, t1, fd);
-		if (op2.nary() > 0)
-			format(op2, t2, fd);
-	} 
-	if (op.nary() == 1) {
-		int t1 = op.getOp1();
-		const Operation& op1 = otree.terms[t1];
-		if (op1.nary() > 0)
-			format(op1, t1, fd);
-	}
-
-	// print 'term ='
-	format_term(t, fd);
-	fprintf(fd, " = ");
-	if (op.nary() == 0) {
-		format_nulary(t, fd);
-	} else if (op.nary() == 1) {
-		int t1 = op.getOp1();
-		const Operation& op1 = otree.terms[t1];
-		const char* opname = "unknown";
-		switch (op.getCode()) {
-		case UMINUS:
-			opname = "-";
-			break;
-		case LOG:
-			opname = "log";
-			break;
-		case EXP:
-			opname = "exp";
-			break;
-		case SIN:
-			opname = "sin";
-			break;
-		case COS:
-			opname = "cos";
-			break;
-		case TAN:
-			opname = "tan";
-			break;
-		case SQRT:
-			opname = "sqrt";
-			break;
-		case ERF:
-			opname = "erf";
-			break;
-		case ERFC:
-			opname = "erfc";
-			break;
-		default:
-			break;
-		}
-		fprintf(fd, "%s(", opname);
-		if (op1.nary() == 0)
-			format_nulary(t1, fd);
-		else
-			format_term(t1, fd);
-		fprintf(fd, ")");
-	} else {
-		int t1 = op.getOp1();
-		const Operation& op1 = otree.terms[t1];
-		int t2 = op.getOp2();
-		const Operation& op2 = otree.terms[t2];
-		const char* opname = "unknown";
-		switch (op.getCode()) {
-		case PLUS:
-			opname = "+";
-			break;
-		case MINUS:
-			opname = "-";
-			break;
-		case TIMES:
-			opname = "*";
-			break;
-		case DIVIDE:
-			opname = "/";
-			break;
-		case POWER:
-			opname = "^";
-			break;
-		default:
-			break;
-		}
-		if (op1.nary() == 0)
-			format_nulary(t1, fd);
-		else
-			format_term(t1, fd);
-		fprintf(fd, " %s ", opname);
-		if (op2.nary() == 0)
-			format_nulary(t2, fd);
-		else
-			format_term(t2, fd);
-	}
-
-	print_delim(fd);
-
-}
-
-void DefaultOperationFormatter::format_term(int t, FILE* fd) const
-{
-	fprintf(fd, "$%d", t);
-}
-
-void DefaultOperationFormatter::format_nulary(int t, FILE* fd) const
-{
-	if (t == OperationTree::zero)
-		fprintf(fd, "0");
-	else if (t == OperationTree::one)
-		fprintf(fd, "1");
-	else if (t == OperationTree::nan)
-		fprintf(fd, "NaN");
-	else
-		fprintf(fd, "$%d", t);
-}
-
-void DefaultOperationFormatter::print_delim(FILE* fd) const
-{
-	fprintf(fd, ";\n");
-}
-
-std::string OperationStringConvertor::convert(const Operation& op, int t) const
-{
-	if (op.nary() == 0) {
-		if (t < OperationTree::num_constants)
-			if (t == OperationTree::zero)
-				return std::string("0");
-			else if (t == OperationTree::one)
-				return std::string("1");
-			else if (t == OperationTree::nan)
-				return std::string("NaN");
-			else if (t == OperationTree::two_over_pi) {
-				char buf[100];
-				sprintf(buf, "%20.16g", 2.0/std::sqrt(M_PI));
-				return std::string(buf);
-			} else {
-				return std::string("error!error");
-			}
-		else
-			return nulsc.convert(t);
-	} else if (op.nary() == 1) {
-		int t1 = op.getOp1();
-		const Operation& op1 = otree.operation(t1);
-		const char* opname = "unknown";
-		switch (op.getCode()) {
-		case UMINUS:
-			opname = "-";
-			break;
-		case LOG:
-			opname = "log";
-			break;
-		case EXP:
-			opname = "exp";
-			break;
-		case SIN:
-			opname = "sin";
-			break;
-		case COS:
-			opname = "cos";
-			break;
-		case TAN:
-			opname = "tan";
-			break;
-		case SQRT:
-			opname = "sqrt";
-			break;
-		case ERF:
-			opname = "erf";
-			break;
-		case ERFC:
-			opname = "erfc";
-			break;
-		default:
-			break;
-		}
-		std::string s1 = convert(op1, t1);
-		return std::string(opname) + "(" + s1 + ")";
-	} else {
-		int t1 = op.getOp1();
-		const Operation& op1 = otree.operation(t1);
-		int t2 = op.getOp2();
-		const Operation& op2 = otree.operation(t2);
-		const char* opname = "unknown";
-		switch (op.getCode()) {
-		case PLUS:
-			opname = "+";
-			break;
-		case MINUS:
-			opname = "-";
-			break;
-		case TIMES:
-			opname = "*";
-			break;
-		case DIVIDE:
-			opname = "/";
-			break;
-		case POWER:
-			opname = "^";
-			break;
-		default:
-			break;
-		}
-		// decide about parenthesis
-		bool op1_par = true;
-		bool op2_par = true;
-		if (op.getCode() == PLUS) {
-			op1_par = false;
-			op2_par = false;
-		} else if (op.getCode() == MINUS) {
-			op1_par = false;
-			if (op2.getCode() != MINUS && op2.getCode() != PLUS)
-				op2_par = false;
-		} else {
-			if (op1.nary() < 2)
-				op1_par = false;
-			if (op2.nary() < 2)
-				op2_par = false;
-		}
-
-		std::string res;
-		if (op1_par)
-			res += "(";
-		res += convert(op1, t1);
-		if (op1_par)
-			res += ")";
-		res += " ";
-		res += opname;
-		res += " ";
-		if (op2_par)
-			res += "(";
-		res += convert(op2, t2);
-		if (op2_par)
-			res += ")";
-
-		return res;
-	}
-}
-
-// Local Variables:
-// mode:C++
-// End:
diff --git a/dynare++/parser/cc/tree.h b/dynare++/parser/cc/tree.hh
similarity index 100%
rename from dynare++/parser/cc/tree.h
rename to dynare++/parser/cc/tree.hh
diff --git a/dynare++/src/Makefile.am b/dynare++/src/Makefile.am
index 126264c34d529b8002d089defddfab2241b1d1f7..e3b56ee1e5299eb8320a30e7bb3558679d2a4317 100644
--- a/dynare++/src/Makefile.am
+++ b/dynare++/src/Makefile.am
@@ -3,22 +3,22 @@ bin_PROGRAMS = dynare++
 GENERATED_FILES = dynglob_ll.cc dynglob_tab.cc dynglob_tab.hh
 
 dynare___SOURCES = \
-	main.cpp \
-	dynare3.cpp \
-	dynare_atoms.h \
-	dynare_model.h \
-	forw_subst_builder.h \
-	planner_builder.cpp \
-	dynare3.h \
-	dynare_exception.h \
-	dynare_params.cpp \
-	planner_builder.h \
-	dynare_atoms.cpp \
-	dynare_model.cpp \
-	dynare_params.h \
-	forw_subst_builder.cpp \
-	nlsolve.cpp \
-	nlsolve.h \
+	main.cc \
+	dynare3.cc \
+	dynare_atoms.hh \
+	dynare_model.hh \
+	forw_subst_builder.hh \
+	planner_builder.cc \
+	dynare3.hh \
+	dynare_exception.hh \
+	dynare_params.cc \
+	planner_builder.hh \
+	dynare_atoms.cc \
+	dynare_model.cc \
+	dynare_params.hh \
+	forw_subst_builder.cc \
+	nlsolve.cc \
+	nlsolve.hh \
 	$(GENERATED_FILES)
 
 dynare___CPPFLAGS = -I../sylv/cc -I../tl/cc -I../kord -I../integ/cc -I.. -I$(top_srcdir)/mex/sources -DDYNVERSION=\"$(PACKAGE_VERSION)\" $(BOOST_CPPFLAGS) $(CPPFLAGS_MATIO)
@@ -27,10 +27,10 @@ dynare___LDADD = ../kord/libkord.a ../integ/cc/libinteg.a ../tl/cc/libtl.a ../pa
 dynare___CXXFLAGS = $(AM_CXXFLAGS) $(PTHREAD_CFLAGS)
 
 BUILT_SOURCES = $(GENERATED_FILES)
-EXTRA_DIST = dynglob.lex dynglob.y
+EXTRA_DIST = dynglob.ll dynglob.yy
 
-dynglob_tab.cc dynglob_tab.hh: dynglob.y
-	$(YACC) -d -odynglob_tab.cc dynglob.y
+dynglob_tab.cc dynglob_tab.hh: dynglob.yy
+	$(YACC) -d -odynglob_tab.cc dynglob.yy
 
-dynglob_ll.cc: dynglob.lex
-	$(LEX) -i -odynglob_ll.cc dynglob.lex
+dynglob_ll.cc: dynglob.ll
+	$(LEX) -i -odynglob_ll.cc dynglob.ll
diff --git a/dynare++/src/dynare3.cc b/dynare++/src/dynare3.cc
new file mode 100644
index 0000000000000000000000000000000000000000..80826598e7128df39a12464d5bc646eceef62ea0
--- /dev/null
+++ b/dynare++/src/dynare3.cc
@@ -0,0 +1,390 @@
+#include "dynare3.hh"
+#include "dynare_exception.hh"
+#include "planner_builder.hh"
+#include "forw_subst_builder.hh"
+
+#include "utils/cc/memory_file.hh"
+#include "utils/cc/exception.hh"
+#include "parser/cc/parser_exception.hh"
+#include "parser/cc/atom_substitutions.hh"
+#include "../tl/cc/tl_exception.hh"
+#include "../kord/kord_exception.hh"
+
+#ifndef DYNVERSION
+# define DYNVERSION "unknown"
+#endif
+
+/**************************************************************************************/
+/*       DynareNameList class                                                         */
+/**************************************************************************************/
+vector<int>
+DynareNameList::selectIndices(const vector<const char *> &ns) const
+{
+  vector<int> res;
+  for (unsigned int i = 0; i < ns.size(); i++)
+    {
+      int j = 0;
+      while (j < getNum() && strcmp(getName(j), ns[i]) != 0)
+        j++;
+      if (j == getNum())
+        throw DynareException(__FILE__, __LINE__,
+                              string("Couldn't find name for ") + ns[i]
+                              +" in DynareNameList::selectIndices");
+      res.push_back(j);
+    }
+  return res;
+}
+
+/**************************************************************************************/
+/*       Dynare class                                                                 */
+/**************************************************************************************/
+
+Dynare::Dynare(const char *modname, int ord, double sstol, Journal &jr)
+  : journal(jr), model(NULL), ysteady(NULL), md(1), dnl(NULL), denl(NULL), dsnl(NULL),
+    fe(NULL), fde(NULL), ss_tol(sstol)
+{
+  // make memory file
+  ogu::MemoryFile mf(modname);
+  if (mf.exists())
+    {
+      try
+        {
+          model = new ogdyn::DynareParser(mf.base(), mf.length(), ord);
+        }
+      catch (const ogp::ParserException &pe)
+        {
+          int line;
+          int col;
+          mf.line_and_col(pe.offset(), line, col);
+          throw DynareException(pe.message(), modname, line, col);
+        }
+      ysteady = new Vector(model->getAtoms().ny());
+      dnl = new DynareNameList(*this);
+      denl = new DynareExogNameList(*this);
+      dsnl = new DynareStateNameList(*this, *dnl, *denl);
+      fe = new ogp::FormulaEvaluator(model->getParser());
+      fde = new ogp::FormulaDerEvaluator(model->getParser());
+      writeModelInfo(journal);
+    }
+  else
+    {
+      throw DynareException(__FILE__, __LINE__, string("Could not open model file ")+modname);
+    }
+}
+
+Dynare::Dynare(const char **endo, int num_endo,
+               const char **exo, int num_exo,
+               const char **par, int num_par,
+               const char *equations, int len, int ord,
+               double sstol, Journal &jr)
+  : journal(jr), model(NULL), ysteady(NULL), md(1), dnl(NULL), denl(NULL), dsnl(NULL),
+    fe(NULL), fde(NULL), ss_tol(sstol)
+{
+  try
+    {
+      model = new ogdyn::DynareSPModel(endo, num_endo, exo, num_exo, par, num_par,
+                                       equations, len, ord);
+    }
+  catch (const ogp::ParserException &pe)
+    {
+      throw DynareException(pe.message(), pe.offset());
+    }
+  ysteady = new Vector(model->getAtoms().ny());
+  dnl = new DynareNameList(*this);
+  denl = new DynareExogNameList(*this);
+  dsnl = new DynareStateNameList(*this, *dnl, *denl);
+  fe = new ogp::FormulaEvaluator(model->getParser());
+  fde = new ogp::FormulaDerEvaluator(model->getParser());
+  writeModelInfo(journal);
+}
+
+Dynare::Dynare(const Dynare &dynare)
+  : journal(dynare.journal), model(NULL),
+    ysteady(NULL), md(dynare.md),
+    dnl(NULL), denl(NULL), dsnl(NULL), fe(NULL), fde(NULL),
+    ss_tol(dynare.ss_tol)
+{
+  model = dynare.model->clone();
+  ysteady = new Vector(*(dynare.ysteady));
+  dnl = new DynareNameList(*this);
+  denl = new DynareExogNameList(*this);
+  dsnl = new DynareStateNameList(*this, *dnl, *denl);
+  fe = new ogp::FormulaEvaluator(model->getParser());
+  fde = new ogp::FormulaDerEvaluator(model->getParser());
+}
+
+Dynare::~Dynare()
+{
+  if (model)
+    delete model;
+  if (ysteady)
+    delete ysteady;
+  if (dnl)
+    delete dnl;
+  if (dsnl)
+    delete dsnl;
+  if (denl)
+    delete denl;
+  if (fe)
+    delete fe;
+  if (fde)
+    delete fde;
+}
+
+void
+Dynare::writeMat(mat_t *fd, const char *prefix) const
+{
+  char tmp[100];
+  sprintf(tmp, "%s_vars", prefix);
+  getAllEndoNames().writeMat(fd, tmp);
+  getAllEndoNames().writeMatIndices(fd, prefix);
+  sprintf(tmp, "%s_state_vars", prefix);
+  getStateNames().writeMat(fd, tmp);
+  sprintf(tmp, "%s_shocks", prefix);
+  getExogNames().writeMat(fd, tmp);
+  getExogNames().writeMatIndices(fd, prefix);
+  sprintf(tmp, "%s_vcov_exo", prefix);
+  model->getVcov().writeMat(fd, tmp);
+  TwoDMatrix aux(1, 1);
+  sprintf(tmp, "%s_nstat", prefix);
+  aux.get(0, 0) = nstat();
+  aux.writeMat(fd, tmp);
+  sprintf(tmp, "%s_npred", prefix);
+  aux.get(0, 0) = npred();
+  aux.writeMat(fd, tmp);
+  sprintf(tmp, "%s_nboth", prefix);
+  aux.get(0, 0) = nboth();
+  aux.writeMat(fd, tmp);
+  sprintf(tmp, "%s_nforw", prefix);
+  aux.get(0, 0) = nforw();
+  aux.writeMat(fd, tmp);
+}
+
+void
+Dynare::writeDump(const std::string &basename) const
+{
+  std::string fname(basename);
+  fname += ".dump";
+  std::ofstream out(fname.c_str());
+  model->dump_model(out);
+  out.close();
+}
+
+void
+Dynare::solveDeterministicSteady(Vector &steady)
+{
+  JournalRecordPair pa(journal);
+  pa << "Non-linear solver for deterministic steady state" << endrec;
+  steady = (const Vector &) model->getInit();
+  DynareVectorFunction dvf(*this);
+  DynareJacobian dj(*this);
+  ogu::NLSolver nls(dvf, dj, 500, ss_tol, journal);
+  int iter;
+  if (!nls.solve(steady, iter))
+    throw DynareException(__FILE__, __LINE__,
+                          "Could not obtain convergence in non-linear solver");
+}
+
+// evaluate system at given y_t=y_{t+1}=y_{t-1}, and given shocks x_t
+void
+Dynare::evaluateSystem(Vector &out, const Vector &yy, const Vector &xx)
+{
+  ConstVector yym(yy, nstat(), nys());
+  ConstVector yyp(yy, nstat()+npred(), nyss());
+  evaluateSystem(out, yym, yy, yyp, xx);
+}
+
+// evaluate system at given y^*_{t-1}, y_t, y^{**}_{t+1} and at
+// exogenous x_t, all three vectors yym, yy, and yyp have the
+// respective lengths of y^*_{t-1}, y_t, y^{**}_{t+1}
+void
+Dynare::evaluateSystem(Vector &out, const Vector &yym, const Vector &yy,
+                       const Vector &yyp, const Vector &xx)
+{
+  ogdyn::DynareAtomValues dav(model->getAtoms(), model->getParams(), yym, yy, yyp, xx);
+  DynareEvalLoader del(model->getAtoms(), out);
+  fe->eval(dav, del);
+}
+
+void
+Dynare::calcDerivatives(const Vector &yy, const Vector &xx)
+{
+  ConstVector yym(yy, nstat(), nys());
+  ConstVector yyp(yy, nstat()+npred(), nyss());
+  ogdyn::DynareAtomValues dav(model->getAtoms(), model->getParams(), yym, yy, yyp, xx);
+  DynareDerEvalLoader ddel(model->getAtoms(), md, model->getOrder());
+  for (int iord = 1; iord <= model->getOrder(); iord++)
+    fde->eval(dav, ddel, iord);
+}
+
+void
+Dynare::calcDerivativesAtSteady()
+{
+  Vector xx(nexog());
+  xx.zeros();
+  calcDerivatives(*ysteady, xx);
+}
+
+void
+Dynare::writeModelInfo(Journal &jr) const
+{
+  // write info on variables
+  {
+    JournalRecordPair rp(journal);
+    rp << "Information on variables" << endrec;
+    JournalRecord rec1(journal);
+    rec1 << "Number of endogenous:            " << ny() << endrec;
+    JournalRecord rec2(journal);
+    rec2 << "Number of exogenous:             " << nexog() << endrec;
+    JournalRecord rec3(journal);
+    rec3 << "Number of static:                " << nstat() << endrec;
+    JournalRecord rec4(journal);
+    rec4 << "Number of predetermined:         " << npred()+nboth() << endrec;
+    JournalRecord rec5(journal);
+    rec5 << "Number of forward looking:       " << nforw()+nboth() << endrec;
+    JournalRecord rec6(journal);
+    rec6 << "Number of both:                  " << nboth() << endrec;
+  }
+
+  // write info on planner variables
+  const ogdyn::PlannerInfo *pinfo = model->get_planner_info();
+  if (pinfo)
+    {
+      JournalRecordPair rp(journal);
+      rp << "Information on planner variables" << endrec;
+      JournalRecord rec1(journal);
+      rec1 << "Number of Lagrange multipliers:  " << pinfo->num_lagrange_mults << endrec;
+      JournalRecord rec2(journal);
+      rec2 << "Number of auxiliary variables:   " << pinfo->num_aux_variables << endrec;
+      JournalRecord rec3(journal);
+      rec3 << "Number of new terms in the tree: " << pinfo->num_new_terms << endrec;
+    }
+
+  // write info on forward substitutions
+  const ogdyn::ForwSubstInfo *finfo = model->get_forw_subst_info();
+  if (finfo)
+    {
+      JournalRecordPair rp(journal);
+      rp << "Information on forward substitutions" << endrec;
+      JournalRecord rec1(journal);
+      rec1 << "Number of affected equations:    " << finfo->num_affected_equations << endrec;
+      JournalRecord rec2(journal);
+      rec2 << "Number of substituted terms:     " << finfo->num_subst_terms << endrec;
+      JournalRecord rec3(journal);
+      rec3 << "Number of auxiliary variables:   " << finfo->num_aux_variables << endrec;
+      JournalRecord rec4(journal);
+      rec4 << "Number of new terms in the tree: " << finfo->num_new_terms << endrec;
+    }
+
+  // write info on substitutions
+  const ogp::SubstInfo *sinfo = model->get_subst_info();
+  if (sinfo)
+    {
+      JournalRecordPair rp(journal);
+      rp << "Information on substitutions" << endrec;
+      JournalRecord rec1(journal);
+      rec1 << "Number of substitutions:         " << sinfo->num_substs << endrec;
+    }
+}
+
+DynareNameList::DynareNameList(const Dynare &dynare)
+{
+  for (int i = 0; i < dynare.ny(); i++)
+    {
+      int j = dynare.model->getAtoms().y2outer_endo()[i];
+      const char *name = dynare.model->getAtoms().get_endovars()[j];
+      names.push_back(name);
+    }
+}
+
+DynareStateNameList::DynareStateNameList(const Dynare &dynare, const DynareNameList &dnl,
+                                         const DynareExogNameList &denl)
+{
+  for (int i = 0; i < dynare.nys(); i++)
+    names.push_back(dnl.getName(i+dynare.nstat()));
+  for (int i = 0; i < dynare.nexog(); i++)
+    names.push_back(denl.getName(i));
+}
+
+DynareExogNameList::DynareExogNameList(const Dynare &dynare)
+{
+  for (int i = 0; i < dynare.nexog(); i++)
+    {
+      int j = dynare.model->getAtoms().y2outer_exo()[i];
+      const char *name = dynare.model->getAtoms().get_exovars()[j];
+      names.push_back(name);
+    }
+}
+
+DynareEvalLoader::DynareEvalLoader(const ogp::FineAtoms &a, Vector &out)
+  : Vector(out)
+{
+  if (a.ny() != out.length())
+    throw DynareException(__FILE__, __LINE__, "Wrong length of out vector in DynareEvalLoader constructor");
+}
+
+/** This clears the container of model derivatives and initializes it
+ * inserting empty sparse tensors up to the given order. */
+DynareDerEvalLoader::DynareDerEvalLoader(const ogp::FineAtoms &a,
+                                         TensorContainer<FSSparseTensor> &mod_ders,
+                                         int order)
+  : atoms(a), md(mod_ders)
+{
+  md.clear();
+  for (int iord = 1; iord <= order; iord++)
+    {
+      FSSparseTensor *t = new FSSparseTensor(iord, atoms.ny()+atoms.nys()+atoms.nyss()+atoms.nexo(), atoms.ny());
+      md.insert(t);
+    }
+}
+
+void
+DynareDerEvalLoader::load(int i, int iord, const int *vars, double res)
+{
+  FSSparseTensor *t = md.get(Symmetry(iord));
+  IntSequence s(iord, 0);
+  for (int j = 0; j < iord; j++)
+    s[j] = atoms.get_pos_of_all(vars[j]);
+  t->insert(s, i, res);
+}
+
+DynareJacobian::DynareJacobian(Dynare &dyn)
+  : Jacobian(dyn.ny()), d(dyn)
+{
+  zeros();
+}
+
+void
+DynareJacobian::eval(const Vector &yy)
+{
+  ogdyn::DynareSteadyAtomValues
+    dav(d.getModel().getAtoms(), d.getModel().getParams(), yy);
+  zeros();
+  d.fde->eval(dav, *this, 1);
+}
+
+void
+DynareJacobian::load(int i, int iord, const int *vars, double res)
+{
+  if (iord != 1)
+    throw DynareException(__FILE__, __LINE__,
+                          "Derivative order different from order=1 in DynareJacobian::load");
+
+  int t = vars[0];
+  int j = d.getModel().getAtoms().get_pos_of_all(t);
+  if (j < d.nyss())
+    get(i, j+d.nstat()+d.npred()) += res;
+  else if (j < d.nyss()+d.ny())
+    get(i, j-d.nyss()) += res;
+  else if (j < d.nyss()+d.ny()+d.nys())
+    get(i, j-d.nyss()-d.ny()+d.nstat()) += res;
+}
+
+void
+DynareVectorFunction::eval(const ConstVector &in, Vector &out)
+{
+  check_for_eval(in, out);
+  Vector xx(d.nexog());
+  xx.zeros();
+  d.evaluateSystem(out, in, xx);
+}
diff --git a/dynare++/src/dynare3.cpp b/dynare++/src/dynare3.cpp
deleted file mode 100644
index a5f0cbdabca088b46162d0030c253eaeb06c8999..0000000000000000000000000000000000000000
--- a/dynare++/src/dynare3.cpp
+++ /dev/null
@@ -1,364 +0,0 @@
-
-#include "dynare3.h"
-#include "dynare_exception.h"
-#include "planner_builder.h"
-#include "forw_subst_builder.h"
-
-#include "utils/cc/memory_file.h"
-#include "utils/cc/exception.h"
-#include "parser/cc/parser_exception.h"
-#include "parser/cc/atom_substitutions.h"
-#include "../tl/cc/tl_exception.hh"
-#include "../kord/kord_exception.hh"
-
-#ifndef DYNVERSION
-#define DYNVERSION "unknown"
-#endif
-
-
-/**************************************************************************************/
-/*       DynareNameList class                                                         */
-/**************************************************************************************/
-vector<int> DynareNameList::selectIndices(const vector<const char*>& ns) const
-{
-	vector<int> res;
-	for (unsigned int i = 0; i < ns.size(); i++) {
-		int j = 0;
-		while (j < getNum() && strcmp(getName(j), ns[i]) != 0)
-			j++;
-		if (j == getNum())
-			throw DynareException(__FILE__, __LINE__,
-								  string("Couldn't find name for ") + ns[i] +
-								  " in DynareNameList::selectIndices");
-		res.push_back(j);
-	}
-	return res;
-}
-
-/**************************************************************************************/
-/*       Dynare class                                                                 */
-/**************************************************************************************/
-
-Dynare::Dynare(const char* modname, int ord, double sstol, Journal& jr)
-	: journal(jr), model(NULL), ysteady(NULL), md(1), dnl(NULL), denl(NULL), dsnl(NULL),
-	  fe(NULL), fde(NULL), ss_tol(sstol)
-{
-	// make memory file
-	ogu::MemoryFile mf(modname);
-	if (mf.exists()) {
-		try {
-			model = new ogdyn::DynareParser(mf.base(), mf.length(), ord);
-		} catch (const ogp::ParserException& pe) {
-			int line;
-			int col;
-			mf.line_and_col(pe.offset(), line, col);
-			throw DynareException(pe.message(), modname, line, col);
-		}
-		ysteady = new Vector(model->getAtoms().ny());
-		dnl = new DynareNameList(*this);
-		denl = new DynareExogNameList(*this);
-		dsnl = new DynareStateNameList(*this, *dnl, *denl);
-		fe = new ogp::FormulaEvaluator(model->getParser());
-		fde = new ogp::FormulaDerEvaluator(model->getParser());
-		writeModelInfo(journal);
-	} else {
-		throw DynareException(__FILE__, __LINE__, string("Could not open model file ")+modname);
-	}
-}
-
-Dynare::Dynare(const char** endo, int num_endo,
-			   const char** exo, int num_exo,
-			   const char** par, int num_par,
-			   const char* equations, int len, int ord,
-			   double sstol, Journal& jr)
-	: journal(jr), model(NULL), ysteady(NULL), md(1), dnl(NULL), denl(NULL), dsnl(NULL),
-	  fe(NULL), fde(NULL), ss_tol(sstol)
-{
-	try {
-		model = new ogdyn::DynareSPModel(endo, num_endo, exo, num_exo, par, num_par,
-										 equations, len, ord);
-	} catch (const ogp::ParserException& pe) {
-		throw DynareException(pe.message(), pe.offset());
-	}
-	ysteady = new Vector(model->getAtoms().ny());
-	dnl = new DynareNameList(*this);
-	denl = new DynareExogNameList(*this);
-	dsnl = new DynareStateNameList(*this, *dnl, *denl);
-	fe = new ogp::FormulaEvaluator(model->getParser());
-	fde = new ogp::FormulaDerEvaluator(model->getParser());
-	writeModelInfo(journal);
-}
-
-Dynare::Dynare(const Dynare& dynare)
-	: journal(dynare.journal), model(NULL),
-	  ysteady(NULL), md(dynare.md),
-	  dnl(NULL), denl(NULL), dsnl(NULL), fe(NULL), fde(NULL),
-	  ss_tol(dynare.ss_tol)
-{
-	model = dynare.model->clone();
-	ysteady = new Vector(*(dynare.ysteady));
-	dnl = new DynareNameList(*this);
-	denl = new DynareExogNameList(*this);
-	dsnl = new DynareStateNameList(*this, *dnl, *denl);
-	fe = new ogp::FormulaEvaluator(model->getParser());
-	fde = new ogp::FormulaDerEvaluator(model->getParser());
-}
-
-Dynare::~Dynare()
-{
-	if (model)
-		delete model;
-	if (ysteady)
-		delete ysteady;
-	if (dnl)
-		delete dnl;
-	if (dsnl)
-		delete dsnl;
-	if (denl)
-		delete denl;
-	if (fe)
-		delete fe;
-	if (fde)
-		delete fde;
-}
-
-void Dynare::writeMat(mat_t* fd, const char* prefix) const
-{
-	char tmp[100];
-	sprintf(tmp, "%s_vars", prefix);
-	getAllEndoNames().writeMat(fd, tmp);
-	getAllEndoNames().writeMatIndices(fd, prefix);
-	sprintf(tmp, "%s_state_vars", prefix);
-	getStateNames().writeMat(fd, tmp);
-	sprintf(tmp, "%s_shocks", prefix);
-	getExogNames().writeMat(fd, tmp);
-	getExogNames().writeMatIndices(fd, prefix);
-	sprintf(tmp, "%s_vcov_exo", prefix);
-	model->getVcov().writeMat(fd, tmp);
-	TwoDMatrix aux(1,1);
-	sprintf(tmp, "%s_nstat", prefix);
-	aux.get(0,0) = nstat();
-	aux.writeMat(fd, tmp);
-	sprintf(tmp, "%s_npred", prefix);
-	aux.get(0,0) = npred();
-	aux.writeMat(fd, tmp);
-	sprintf(tmp, "%s_nboth", prefix);
-	aux.get(0,0) = nboth();
-	aux.writeMat(fd, tmp);
-	sprintf(tmp, "%s_nforw", prefix);
-	aux.get(0,0) = nforw();
-	aux.writeMat(fd, tmp);
-}
-
-void Dynare::writeDump(const std::string&  basename) const
-{
-	std::string fname(basename);
-	fname += ".dump";
-	std::ofstream out(fname.c_str());
-	model->dump_model(out);
-	out.close();
-}
-
-void Dynare::solveDeterministicSteady(Vector& steady)
-{
-	JournalRecordPair pa(journal);
-	pa << "Non-linear solver for deterministic steady state" << endrec;
-	steady = (const Vector&) model->getInit();
-	DynareVectorFunction dvf(*this);
-	DynareJacobian dj(*this);
-	ogu::NLSolver nls(dvf, dj, 500, ss_tol, journal);
-	int iter;
-	if (! nls.solve(steady, iter))
-		throw DynareException(__FILE__, __LINE__,
-							  "Could not obtain convergence in non-linear solver");
-}
-
-// evaluate system at given y_t=y_{t+1}=y_{t-1}, and given shocks x_t
-void Dynare::evaluateSystem(Vector& out, const Vector& yy, const Vector& xx)
-{
-	ConstVector yym(yy, nstat(), nys());
-	ConstVector yyp(yy, nstat()+npred(), nyss());
-	evaluateSystem(out, yym, yy, yyp, xx);
-}
-
-// evaluate system at given y^*_{t-1}, y_t, y^{**}_{t+1} and at
-// exogenous x_t, all three vectors yym, yy, and yyp have the
-// respective lengths of y^*_{t-1}, y_t, y^{**}_{t+1}
-void Dynare::evaluateSystem(Vector& out, const Vector& yym, const Vector& yy,
-							const Vector& yyp, const Vector& xx)
-{
-	ogdyn::DynareAtomValues dav(model->getAtoms(), model->getParams(), yym, yy, yyp, xx);
-	DynareEvalLoader del(model->getAtoms(), out);
-	fe->eval(dav, del);
-}
-
-void Dynare::calcDerivatives(const Vector& yy, const Vector& xx)
-{
-	ConstVector yym(yy, nstat(), nys());
-	ConstVector yyp(yy, nstat()+npred(), nyss());
-	ogdyn::DynareAtomValues dav(model->getAtoms(), model->getParams(), yym, yy, yyp, xx);
-	DynareDerEvalLoader ddel(model->getAtoms(), md, model->getOrder());
-	for (int iord = 1; iord <= model->getOrder(); iord++)
-		fde->eval(dav, ddel, iord);
-}
-
-void Dynare::calcDerivativesAtSteady()
-{
-	Vector xx(nexog());
-	xx.zeros();
-	calcDerivatives(*ysteady, xx);
-}
-
-void Dynare::writeModelInfo(Journal& jr) const
-{
-	// write info on variables
-	{
-		JournalRecordPair rp(journal);
-		rp << "Information on variables" << endrec;
-		JournalRecord rec1(journal);
-		rec1 << "Number of endogenous:            " << ny() << endrec;
-		JournalRecord rec2(journal);
-		rec2 << "Number of exogenous:             " << nexog() << endrec;
-		JournalRecord rec3(journal);
-		rec3 << "Number of static:                " << nstat() << endrec;
-		JournalRecord rec4(journal);
-		rec4 << "Number of predetermined:         " << npred()+nboth() << endrec;
-		JournalRecord rec5(journal);
-		rec5 << "Number of forward looking:       " << nforw()+nboth() << endrec;
-		JournalRecord rec6(journal);
-		rec6 << "Number of both:                  " << nboth() << endrec;
-	}
-
-	// write info on planner variables
-	const ogdyn::PlannerInfo* pinfo = model->get_planner_info();
-	if (pinfo) {
-		JournalRecordPair rp(journal);
-		rp << "Information on planner variables" << endrec;
-		JournalRecord rec1(journal);
-		rec1 << "Number of Lagrange multipliers:  " << pinfo->num_lagrange_mults << endrec;
-		JournalRecord rec2(journal);
-		rec2 << "Number of auxiliary variables:   " << pinfo->num_aux_variables << endrec;
-		JournalRecord rec3(journal);
-		rec3 << "Number of new terms in the tree: " << pinfo->num_new_terms << endrec;
-	}
-
-	// write info on forward substitutions
-	const ogdyn::ForwSubstInfo* finfo = model->get_forw_subst_info();
-	if (finfo) {
-		JournalRecordPair rp(journal);
-		rp << "Information on forward substitutions" << endrec;
-		JournalRecord rec1(journal);
-		rec1 << "Number of affected equations:    " << finfo->num_affected_equations << endrec;
-		JournalRecord rec2(journal);
-		rec2 << "Number of substituted terms:     " << finfo->num_subst_terms << endrec;
-		JournalRecord rec3(journal);
-		rec3 << "Number of auxiliary variables:   " << finfo->num_aux_variables << endrec;
-		JournalRecord rec4(journal);
-		rec4 << "Number of new terms in the tree: " << finfo->num_new_terms << endrec;
-	}
-
-	// write info on substitutions
-	const ogp::SubstInfo* sinfo = model->get_subst_info();
-	if (sinfo) {
-		JournalRecordPair rp(journal);
-		rp << "Information on substitutions" << endrec;
-		JournalRecord rec1(journal);
-		rec1 << "Number of substitutions:         " << sinfo->num_substs << endrec;
-	}
-}
-
-DynareNameList::DynareNameList(const Dynare& dynare)
-{
-	for (int i = 0; i < dynare.ny(); i++) {
-		int j = dynare.model->getAtoms().y2outer_endo()[i];
-		const char* name = dynare.model->getAtoms().get_endovars()[j];
-		names.push_back(name);
-	}
-}
-
-DynareStateNameList::DynareStateNameList(const Dynare& dynare, const DynareNameList& dnl,
-										 const DynareExogNameList& denl)
-{
-	for (int i = 0; i < dynare.nys(); i++)
-		names.push_back(dnl.getName(i+dynare.nstat()));
-	for (int i = 0; i < dynare.nexog(); i++)
-		names.push_back(denl.getName(i));
-}
-
-DynareExogNameList::DynareExogNameList(const Dynare& dynare)
-{
-	for (int i = 0; i < dynare.nexog(); i++) {
-		int j = dynare.model->getAtoms().y2outer_exo()[i];
-		const char* name = dynare.model->getAtoms().get_exovars()[j];
-		names.push_back(name);
-	}
-}
-
-DynareEvalLoader::DynareEvalLoader(const ogp::FineAtoms& a, Vector& out)
-	: Vector(out)
-{
-	if (a.ny() != out.length())
-		throw DynareException(__FILE__, __LINE__, "Wrong length of out vector in DynareEvalLoader constructor");
-}
-
-/** This clears the container of model derivatives and initializes it
- * inserting empty sparse tensors up to the given order. */
-DynareDerEvalLoader::DynareDerEvalLoader(const ogp::FineAtoms& a,
-										 TensorContainer<FSSparseTensor>& mod_ders,
-										 int order)
-	: atoms(a), md(mod_ders)
-{
-	md.clear();
-	for (int iord = 1; iord <= order; iord++) {
-		FSSparseTensor* t = new FSSparseTensor(iord, atoms.ny()+atoms.nys()+atoms.nyss()+atoms.nexo(), atoms.ny());
-		md.insert(t);
-	}
-}
-
-void DynareDerEvalLoader::load(int i, int iord, const int* vars, double res)
-{
-	FSSparseTensor* t = md.get(Symmetry(iord));
-	IntSequence s(iord, 0);
-	for (int j = 0; j < iord; j++)
-		s[j] = atoms.get_pos_of_all(vars[j]);
-	t->insert(s, i, res);
-}
-
-DynareJacobian::DynareJacobian(Dynare& dyn)
-	: Jacobian(dyn.ny()), d(dyn)
-{
-	zeros();
-}
-
-void DynareJacobian::eval(const Vector& yy)
-{
-	ogdyn::DynareSteadyAtomValues
-		dav(d.getModel().getAtoms(), d.getModel().getParams(), yy);
-	zeros();
-	d.fde->eval(dav, *this, 1);
-}
-
-void DynareJacobian::load(int i, int iord, const int* vars, double res)
-{
-	if (iord != 1)
-		throw DynareException(__FILE__, __LINE__,
-							  "Derivative order different from order=1 in DynareJacobian::load");
-
-	int t = vars[0];
-	int j = d.getModel().getAtoms().get_pos_of_all(t);
-	if (j < d.nyss())
-		get(i, j+d.nstat()+d.npred()) += res;
-	else if (j < d.nyss()+d.ny())
-		get(i, j-d.nyss()) += res;
-	else if (j < d.nyss()+d.ny()+d.nys())
-		get(i, j-d.nyss()-d.ny()+d.nstat()) += res;
-}
-
-void DynareVectorFunction::eval(const ConstVector& in, Vector& out)
-{
-	check_for_eval(in, out);
-	Vector xx(d.nexog());
-	xx.zeros();
-	d.evaluateSystem(out, in, xx);
-}
-
diff --git a/dynare++/src/dynare3.h b/dynare++/src/dynare3.hh
similarity index 99%
rename from dynare++/src/dynare3.h
rename to dynare++/src/dynare3.hh
index 59d37055ee4c00f1f1530893184a59fa09f02d03..04eea833ed0459d2b7a7675ed2a36e862f33d57d 100644
--- a/dynare++/src/dynare3.h
+++ b/dynare++/src/dynare3.hh
@@ -9,8 +9,8 @@
 #include "../kord/decision_rule.hh"
 #include "../kord/dynamic_model.hh"
 
-#include "dynare_model.h"
-#include "nlsolve.h"
+#include "dynare_model.hh"
+#include "nlsolve.hh"
 
 #include <vector>
 
diff --git a/dynare++/src/dynare_atoms.cc b/dynare++/src/dynare_atoms.cc
new file mode 100644
index 0000000000000000000000000000000000000000..026631d9f2d5d94355e8094566ecf2add11e7d26
--- /dev/null
+++ b/dynare++/src/dynare_atoms.cc
@@ -0,0 +1,310 @@
+// Copyright (C) 2006, Ondra Kamenik
+
+// $Id: dynare_atoms.cpp 1765 2008-03-31 14:32:08Z kamenik $
+
+#include "parser/cc/parser_exception.hh"
+#include "utils/cc/exception.hh"
+
+#include "dynare_atoms.hh"
+
+#include <string>
+#include <cmath>
+
+using namespace ogdyn;
+using std::string;
+
+void
+DynareStaticAtoms::register_name(const char *name)
+{
+  if (varnames.query(name))
+    throw ogp::ParserException(string("The name ")+name+" is not unique.", 0);
+  StaticAtoms::register_name(name);
+}
+
+int
+DynareStaticAtoms::check_variable(const char *name) const
+{
+  if (0 == varnames.query(name))
+    throw ogp::ParserException(std::string("Unknown name <")+name+">", 0);
+  Tvarmap::const_iterator it = vars.find(name);
+  if (it == vars.end())
+    return -1;
+  else
+    return (*it).second;
+}
+
+DynareDynamicAtoms::DynareDynamicAtoms(const DynareDynamicAtoms &dda)
+  : SAtoms(dda)
+{
+  // fill atom_type
+  for (Tatypemap::const_iterator it = dda.atom_type.begin();
+       it != dda.atom_type.end(); ++it)
+    atom_type.insert(Tatypemap::value_type(varnames.query((*it).first), (*it).second));
+}
+
+void
+DynareDynamicAtoms::parse_variable(const char *in, std::string &out, int &ll) const
+{
+  ll = 0;
+  std::string str = in;
+  int left = str.find_first_of("({");
+  if (left != -1)
+    {
+      out = str.substr(0, left);
+      left++;
+      int right = str.find_first_of(")}", left);
+      if ((int) string::npos == right)
+        throw ogp::ParserException(
+                                   string("Syntax error when parsing Dynare atom <")+in+">.", 0);
+      std::string tmp(str, left, right-left);
+      sscanf(tmp.c_str(), "%d", &ll);
+    }
+  else
+    {
+      out = in;
+    }
+}
+
+void
+DynareDynamicAtoms::register_uniq_endo(const char *name)
+{
+  FineAtoms::register_uniq_endo(name);
+  atom_type.insert(Tatypemap::value_type(varnames.query(name), endovar));
+}
+
+void
+DynareDynamicAtoms::register_uniq_exo(const char *name)
+{
+  FineAtoms::register_uniq_exo(name);
+  atom_type.insert(Tatypemap::value_type(varnames.query(name), exovar));
+}
+
+void
+DynareDynamicAtoms::register_uniq_param(const char *name)
+{
+  FineAtoms::register_uniq_param(name);
+  atom_type.insert(Tatypemap::value_type(varnames.query(name), param));
+}
+
+bool
+DynareDynamicAtoms::is_type(const char *name, atype tp) const
+{
+  Tatypemap::const_iterator it = atom_type.find(name);
+  if (it != atom_type.end() && (*it).second == tp)
+    return true;
+  else
+    return false;
+}
+
+void
+DynareDynamicAtoms::print() const
+{
+  SAtoms::print();
+  printf("Name types:\n");
+  for (Tatypemap::const_iterator it = atom_type.begin();
+       it != atom_type.end(); ++it)
+    printf("name=%s type=%s\n", (*it).first,
+           ((*it).second == endovar) ? "endovar" : (((*it).second == exovar) ? "exovar" : "param"));
+}
+
+std::string
+DynareDynamicAtoms::convert(int t) const
+{
+  if (t < ogp::OperationTree::num_constants)
+    {
+      throw ogu::Exception(__FILE__, __LINE__,
+                           "Tree index is a built-in constant in DynareDynamicAtoms::convert");
+      return std::string();
+    }
+  if (is_constant(t))
+    {
+      double v = get_constant_value(t);
+      char buf[100];
+      sprintf(buf, "%20.16g", v);
+      const char *s = buf;
+      while (*s == ' ')
+        ++s;
+      return std::string(s);
+    }
+
+  const char *s = name(t);
+  if (is_type(s, endovar))
+    {
+      int ll = lead(t);
+      char buf[100];
+      if (ll)
+        sprintf(buf, "%s(%d)", s, ll);
+      else
+        sprintf(buf, "%s", s);
+      return std::string(buf);
+    }
+
+  return std::string(s);
+}
+
+void
+DynareAtomValues::setValues(ogp::EvalTree &et) const
+{
+  // set constants
+  atoms.setValues(et);
+
+  // set parameteres
+  for (unsigned int i = 0; i < atoms.get_params().size(); i++)
+    {
+      if (atoms.is_referenced(atoms.get_params()[i]))
+        {
+          const ogp::DynamicAtoms::Tlagmap &lmap = atoms.lagmap(atoms.get_params()[i]);
+          for (ogp::DynamicAtoms::Tlagmap::const_iterator it = lmap.begin();
+               it != lmap.end(); ++it)
+            {
+              int t = (*it).second;
+              et.set_nulary(t, paramvals[i]);
+            }
+        }
+    }
+
+  // set endogenous
+  for (unsigned int outer_i = 0; outer_i < atoms.get_endovars().size(); outer_i++)
+    {
+      if (atoms.is_referenced(atoms.get_endovars()[outer_i]))
+        {
+          const ogp::DynamicAtoms::Tlagmap &lmap = atoms.lagmap(atoms.get_endovars()[outer_i]);
+          for (ogp::DynamicAtoms::Tlagmap::const_iterator it = lmap.begin();
+               it != lmap.end(); ++it)
+            {
+              int ll = (*it).first;
+              int t = (*it).second;
+              int i = atoms.outer2y_endo()[outer_i];
+              if (ll == -1)
+                {
+                  et.set_nulary(t, yym[i-atoms.nstat()]);
+                }
+              else if (ll == 0)
+                et.set_nulary(t, yy[i]);
+              else
+                et.set_nulary(t, yyp[i-atoms.nstat()-atoms.npred()]);
+            }
+        }
+    }
+
+  // set exogenous
+  for (unsigned int outer_i = 0; outer_i < atoms.get_exovars().size(); outer_i++)
+    {
+      if (atoms.is_referenced(atoms.get_exovars()[outer_i]))
+        {
+          const ogp::DynamicAtoms::Tlagmap &lmap = atoms.lagmap(atoms.get_exovars()[outer_i]);
+          for (ogp::DynamicAtoms::Tlagmap::const_iterator it = lmap.begin();
+               it != lmap.end(); ++it)
+            {
+              int ll = (*it).first;
+              if (ll == 0)   // this is always true because of checks
+                {
+                  int t = (*it).second;
+                  int i = atoms.outer2y_exo()[outer_i];
+                  et.set_nulary(t, xx[i]);
+                }
+            }
+        }
+    }
+}
+
+void
+DynareStaticSteadyAtomValues::setValues(ogp::EvalTree &et) const
+{
+  // set constants
+  atoms_static.setValues(et);
+
+  // set parameters
+  for (unsigned int i = 0; i < atoms_static.get_params().size(); i++)
+    {
+      const char *name = atoms_static.get_params()[i];
+      int t = atoms_static.index(name);
+      if (t != -1)
+        {
+          int idyn = atoms.name2outer_param(name);
+          et.set_nulary(t, paramvals[idyn]);
+        }
+    }
+
+  // set endogenous
+  for (unsigned int i = 0; i < atoms_static.get_endovars().size(); i++)
+    {
+      const char *name = atoms_static.get_endovars()[i];
+      int t = atoms_static.index(name);
+      if (t != -1)
+        {
+          int idyn = atoms.outer2y_endo()[atoms.name2outer_endo(name)];
+          et.set_nulary(t, yy[idyn]);
+        }
+    }
+
+  // set exogenous
+  for (unsigned int i = 0; i < atoms_static.get_exovars().size(); i++)
+    {
+      const char *name = atoms_static.get_exovars()[i];
+      int t = atoms_static.index(name);
+      if (t != -1)
+        et.set_nulary(t, 0.0);
+    }
+}
+
+DynareSteadySubstitutions::DynareSteadySubstitutions(const ogp::FineAtoms &a,
+                                                     const ogp::OperationTree &tree,
+                                                     const Tsubstmap &subst,
+                                                     const Vector &pvals, Vector &yy)
+  : atoms(a), y(yy)
+{
+  // fill the vector of left and right hand sides
+  for (Tsubstmap::const_iterator it = subst.begin();
+       it != subst.end(); ++it)
+    {
+      left_hand_sides.push_back((*it).first);
+      right_hand_sides.push_back((*it).second);
+    }
+
+  // evaluate right hand sides
+  DynareSteadyAtomValues dsav(atoms, pvals, y);
+  ogp::FormulaCustomEvaluator fe(tree, right_hand_sides);
+  fe.eval(dsav, *this);
+}
+
+void
+DynareSteadySubstitutions::load(int i, double res)
+{
+  const char *name = left_hand_sides[i];
+  int iouter = atoms.name2outer_endo(name);
+  int iy = atoms.outer2y_endo()[iouter];
+  if (!std::isfinite(y[iy]))
+    y[iy] = res;
+}
+
+DynareStaticSteadySubstitutions::
+DynareStaticSteadySubstitutions(const ogp::FineAtoms &a, const ogp::StaticFineAtoms &sa,
+                                const ogp::OperationTree &tree,
+                                const Tsubstmap &subst,
+                                const Vector &pvals, Vector &yy)
+  : atoms(a), atoms_static(sa), y(yy)
+{
+  // fill the vector of left and right hand sides
+  for (Tsubstmap::const_iterator it = subst.begin();
+       it != subst.end(); ++it)
+    {
+      left_hand_sides.push_back((*it).first);
+      right_hand_sides.push_back((*it).second);
+    }
+
+  // evaluate right hand sides
+  DynareStaticSteadyAtomValues dsav(atoms, atoms_static, pvals, y);
+  ogp::FormulaCustomEvaluator fe(tree, right_hand_sides);
+  fe.eval(dsav, *this);
+}
+
+void
+DynareStaticSteadySubstitutions::load(int i, double res)
+{
+  const char *name = left_hand_sides[i];
+  int iouter = atoms.name2outer_endo(name);
+  int iy = atoms.outer2y_endo()[iouter];
+  if (!std::isfinite(y[iy]))
+    y[iy] = res;
+}
diff --git a/dynare++/src/dynare_atoms.cpp b/dynare++/src/dynare_atoms.cpp
deleted file mode 100644
index c1ae58bc40c7db5a1010124025b4bfcef5314121..0000000000000000000000000000000000000000
--- a/dynare++/src/dynare_atoms.cpp
+++ /dev/null
@@ -1,274 +0,0 @@
-// Copyright (C) 2006, Ondra Kamenik
-
-// $Id: dynare_atoms.cpp 1765 2008-03-31 14:32:08Z kamenik $
-
-#include "parser/cc/parser_exception.h"
-#include "utils/cc/exception.h"
-
-#include "dynare_atoms.h"
-
-#include <string>
-#include <cmath>
-
-using namespace ogdyn;
-using std::string;
-
-void DynareStaticAtoms::register_name(const char* name)
-{
-	if (varnames.query(name))
-		throw ogp::ParserException(string("The name ")+name+" is not unique.", 0);
-	StaticAtoms::register_name(name);
-}
-
-int DynareStaticAtoms::check_variable(const char* name) const
-{
-	if (0 == varnames.query(name))
-		throw ogp::ParserException(std::string("Unknown name <")+name+">", 0);
-	Tvarmap::const_iterator it = vars.find(name);
-	if (it == vars.end())
-		return -1;
-	else
-		return (*it).second;
-}
-
-DynareDynamicAtoms::DynareDynamicAtoms(const DynareDynamicAtoms& dda)
-	: SAtoms(dda)
-{
-	// fill atom_type
-	for (Tatypemap::const_iterator it = dda.atom_type.begin();
-		 it != dda.atom_type.end(); ++it)
-		atom_type.insert(Tatypemap::value_type(varnames.query((*it).first), (*it).second));
-}
-
-void DynareDynamicAtoms::parse_variable(const char* in, std::string& out, int& ll) const
-{
-	ll = 0;
-	std::string str = in;
-	int left = str.find_first_of("({");
-	if (left != -1) {
-		out = str.substr(0, left);
-		left++;
-		int right = str.find_first_of(")}", left);
-		if ((int)string::npos == right)
-			throw ogp::ParserException(
-				string("Syntax error when parsing Dynare atom <")+in+">.", 0);
-		std::string tmp(str, left, right-left);
-		sscanf(tmp.c_str(), "%d", &ll);
-	} else {
-		out = in;
-	}
-}
-
-void DynareDynamicAtoms::register_uniq_endo(const char* name)
-{
-	FineAtoms::register_uniq_endo(name);
-	atom_type.insert(Tatypemap::value_type(varnames.query(name), endovar));
-}
-
-void DynareDynamicAtoms::register_uniq_exo(const char* name)
-{
-	FineAtoms::register_uniq_exo(name);
-	atom_type.insert(Tatypemap::value_type(varnames.query(name), exovar));
-}
-
-void DynareDynamicAtoms::register_uniq_param(const char* name)
-{
-	FineAtoms::register_uniq_param(name);
-	atom_type.insert(Tatypemap::value_type(varnames.query(name), param));
-}
-
-bool DynareDynamicAtoms::is_type(const char* name, atype tp) const
-{
-	Tatypemap::const_iterator it = atom_type.find(name);
-	if (it != atom_type.end() && (*it).second == tp)
-		return true;
-	else
-		return false;
-}
-
-void DynareDynamicAtoms::print() const
-{
-	SAtoms::print();
-	printf("Name types:\n");
-	for (Tatypemap::const_iterator it = atom_type.begin();
-		 it != atom_type.end(); ++it)
-		printf("name=%s type=%s\n", (*it).first,
-			   ((*it).second == endovar) ? "endovar" : (((*it).second == exovar)? "exovar" : "param"));
-}
-
-std::string DynareDynamicAtoms::convert(int t) const
-{
-	if (t < ogp::OperationTree::num_constants) {
-		throw ogu::Exception(__FILE__,__LINE__,
-							 "Tree index is a built-in constant in DynareDynamicAtoms::convert");
-		return std::string();
-	}
-	if (is_constant(t)) {
-		double v = get_constant_value(t);
-		char buf[100];
-		sprintf(buf, "%20.16g", v);
-		const char* s = buf;
-		while (*s == ' ')
-			++s;
-		return std::string(s);
-	}
-	
-	const char* s = name(t);
-	if (is_type(s, endovar)) {
-		int ll = lead(t);
-		char buf[100];
-		if (ll)
-			sprintf(buf, "%s(%d)", s, ll);
-		else
-			sprintf(buf, "%s", s);
-		return std::string(buf);
-	}
-
-	return std::string(s);
-}
-
-
-void DynareAtomValues::setValues(ogp::EvalTree& et) const
-{
-	// set constants
-	atoms.setValues(et);
-
-	// set parameteres
-	for (unsigned int i = 0; i < atoms.get_params().size(); i++) {
-        if (atoms.is_referenced(atoms.get_params()[i])) {
-			const ogp::DynamicAtoms::Tlagmap& lmap = atoms.lagmap(atoms.get_params()[i]);
-			for (ogp::DynamicAtoms::Tlagmap::const_iterator it = lmap.begin();
-				 it != lmap.end(); ++it) {
-				int t = (*it).second;
-				et.set_nulary(t, paramvals[i]);
-			}
-		}
-	}
-
-	// set endogenous
-	for (unsigned int outer_i = 0; outer_i < atoms.get_endovars().size(); outer_i++) {
-        if (atoms.is_referenced(atoms.get_endovars()[outer_i])) {
-			const ogp::DynamicAtoms::Tlagmap& lmap = atoms.lagmap(atoms.get_endovars()[outer_i]);
-			for (ogp::DynamicAtoms::Tlagmap::const_iterator it = lmap.begin();
-				 it != lmap.end(); ++it) {
-				int ll = (*it).first;
-				int t = (*it).second;
-				int i = atoms.outer2y_endo()[outer_i];
-				if (ll == -1) {
-					et.set_nulary(t, yym[i-atoms.nstat()]);
-				}
-				else if (ll == 0)
-					et.set_nulary(t, yy[i]);
-				else
-					et.set_nulary(t, yyp[i-atoms.nstat()-atoms.npred()]);
-			}
-		}
-	}
-
-	// set exogenous
-	for (unsigned int outer_i = 0; outer_i < atoms.get_exovars().size(); outer_i++) {
-        if (atoms.is_referenced(atoms.get_exovars()[outer_i])) {
-			const ogp::DynamicAtoms::Tlagmap& lmap = atoms.lagmap(atoms.get_exovars()[outer_i]);
-			for (ogp::DynamicAtoms::Tlagmap::const_iterator it = lmap.begin();
-				 it != lmap.end(); ++it) {
-				int ll = (*it).first;
-				if (ll == 0) { // this is always true because of checks
-					int t = (*it).second;
-					int i = atoms.outer2y_exo()[outer_i];			
-					et.set_nulary(t, xx[i]);
-				}
-			}
-		}
-	}
-}
-
-void DynareStaticSteadyAtomValues::setValues(ogp::EvalTree& et) const
-{
-	// set constants
-	atoms_static.setValues(et);
-
-	// set parameters
-	for (unsigned int i = 0; i < atoms_static.get_params().size(); i++) {
-		const char* name = atoms_static.get_params()[i];
-		int t = atoms_static.index(name);
-		if (t != -1) {
-			int idyn = atoms.name2outer_param(name);
-			et.set_nulary(t, paramvals[idyn]);
-		}
-	}
-
-	// set endogenous
-	for (unsigned int i = 0; i < atoms_static.get_endovars().size(); i++) {
-		const char* name = atoms_static.get_endovars()[i];
-		int t = atoms_static.index(name);
-		if (t != -1) {
-			int idyn = atoms.outer2y_endo()[atoms.name2outer_endo(name)];
-			et.set_nulary(t, yy[idyn]);
-		}
-	}
-
-	// set exogenous
-	for (unsigned int i = 0; i < atoms_static.get_exovars().size(); i++) {
-		const char* name = atoms_static.get_exovars()[i];
-		int t = atoms_static.index(name);
-		if (t != -1)
-			et.set_nulary(t, 0.0);
-	}
-}
-
-DynareSteadySubstitutions::DynareSteadySubstitutions(const ogp::FineAtoms& a,
-													 const ogp::OperationTree& tree,
-													 const Tsubstmap& subst,
-													 const Vector& pvals, Vector& yy)
-	: atoms(a), y(yy)
-{
-	// fill the vector of left and right hand sides
-	for (Tsubstmap::const_iterator it = subst.begin();
-		 it != subst.end(); ++it) {
-		left_hand_sides.push_back((*it).first);
-		right_hand_sides.push_back((*it).second);
-	}
-
-	// evaluate right hand sides
-	DynareSteadyAtomValues dsav(atoms, pvals, y);
-	ogp::FormulaCustomEvaluator fe(tree, right_hand_sides);
-	fe.eval(dsav, *this);
-}
-
-void DynareSteadySubstitutions::load(int i, double res)
-{
-	const char* name = left_hand_sides[i];
-	int iouter = atoms.name2outer_endo(name);
-	int iy = atoms.outer2y_endo()[iouter];
-	if (! std::isfinite(y[iy]))
-		y[iy] = res;
-}
-
-DynareStaticSteadySubstitutions::
-DynareStaticSteadySubstitutions(const ogp::FineAtoms& a, const ogp::StaticFineAtoms& sa,
-								const ogp::OperationTree& tree,
-								const Tsubstmap& subst,
-								const Vector& pvals, Vector& yy)
-	: atoms(a), atoms_static(sa), y(yy)
-{
-	// fill the vector of left and right hand sides
-	for (Tsubstmap::const_iterator it = subst.begin();
-		 it != subst.end(); ++it) {
-		left_hand_sides.push_back((*it).first);
-		right_hand_sides.push_back((*it).second);
-	}
-
-	// evaluate right hand sides
-	DynareStaticSteadyAtomValues dsav(atoms, atoms_static, pvals, y);
-	ogp::FormulaCustomEvaluator fe(tree, right_hand_sides);
-	fe.eval(dsav, *this);
-}
-
-void DynareStaticSteadySubstitutions::load(int i, double res)
-{
-	const char* name = left_hand_sides[i];
-	int iouter = atoms.name2outer_endo(name);
-	int iy = atoms.outer2y_endo()[iouter];
-	if (! std::isfinite(y[iy]))
-		y[iy] = res;
-}
diff --git a/dynare++/src/dynare_atoms.h b/dynare++/src/dynare_atoms.hh
similarity index 97%
rename from dynare++/src/dynare_atoms.h
rename to dynare++/src/dynare_atoms.hh
index 68b9381990a3afbdec4897906e0958001815dad8..d43b56a4578f53f9e1d914c81a84252524ccd18e 100644
--- a/dynare++/src/dynare_atoms.h
+++ b/dynare++/src/dynare_atoms.hh
@@ -5,12 +5,12 @@
 #ifndef OGDYN_DYNARE_ATOMS_H
 #define OGDYN_DYNARE_ATOMS_H
 
-#include "sylv/cc/Vector.h"
+#include "sylv/cc/Vector.hh"
 
-#include "parser/cc/static_atoms.h"
-#include "parser/cc/static_fine_atoms.h"
-#include "parser/cc/atom_substitutions.h"
-#include "parser/cc/tree.h"
+#include "parser/cc/static_atoms.hh"
+#include "parser/cc/static_fine_atoms.hh"
+#include "parser/cc/atom_substitutions.hh"
+#include "parser/cc/tree.hh"
 
 #include <map>
 #include <vector>
diff --git a/dynare++/src/dynare_exception.h b/dynare++/src/dynare_exception.hh
similarity index 100%
rename from dynare++/src/dynare_exception.h
rename to dynare++/src/dynare_exception.hh
diff --git a/dynare++/src/dynare_model.cc b/dynare++/src/dynare_model.cc
new file mode 100644
index 0000000000000000000000000000000000000000..1b40fae1d96f926edf3267120a6fb998c9b4b14e
--- /dev/null
+++ b/dynare++/src/dynare_model.cc
@@ -0,0 +1,1075 @@
+// Copyright (C) 2006-2011, Ondra Kamenik
+
+#include "parser/cc/parser_exception.hh"
+#include "parser/cc/location.hh"
+#include "utils/cc/exception.hh"
+#include "dynare_model.hh"
+#include "dynare_exception.hh"
+#include "planner_builder.hh"
+#include "forw_subst_builder.hh"
+
+#include <cstdlib>
+
+#include <string>
+#include <cmath>
+#include <climits>
+
+using namespace ogdyn;
+
+ParsedMatrix::ParsedMatrix(const ogp::MatrixParser &mp)
+  : TwoDMatrix(mp.nrows(), mp.ncols())
+{
+  zeros();
+  for (ogp::MPIterator it = mp.begin(); it != mp.end(); ++it)
+    get(it.row(), it.col()) = *it;
+}
+
+DynareModel::DynareModel()
+  : atoms(), eqs(atoms), order(-1),
+    param_vals(0), init_vals(0), vcov_mat(0),
+    t_plobjective(-1), t_pldiscount(-1),
+    pbuilder(NULL), fbuilder(NULL),
+    atom_substs(NULL), old_atoms(NULL)
+{
+}
+
+DynareModel::DynareModel(const DynareModel &dm)
+  : atoms(dm.atoms), eqs(dm.eqs, atoms), order(dm.order),
+    param_vals(0), init_vals(0), vcov_mat(0),
+    t_plobjective(dm.t_plobjective),
+    t_pldiscount(dm.t_pldiscount),
+    pbuilder(NULL), fbuilder(NULL),
+    atom_substs(NULL), old_atoms(NULL)
+{
+  if (dm.param_vals)
+    param_vals = new Vector((const Vector &) *(dm.param_vals));
+  if (dm.init_vals)
+    init_vals = new Vector((const Vector &) *(dm.init_vals));
+  if (dm.vcov_mat)
+    vcov_mat = new TwoDMatrix((const TwoDMatrix &) *(dm.vcov_mat));
+  if (dm.old_atoms)
+    old_atoms = new DynareDynamicAtoms((const DynareDynamicAtoms &) *(dm.old_atoms));
+  if (dm.atom_substs)
+    atom_substs = new ogp::AtomSubstitutions((*dm.atom_substs), *old_atoms, atoms);
+  if (dm.pbuilder)
+    pbuilder = new PlannerBuilder(*(dm.pbuilder), *this);
+  if (dm.fbuilder)
+    fbuilder = new ForwSubstBuilder(*(dm.fbuilder), *this);
+}
+
+DynareModel::~DynareModel()
+{
+  if (param_vals)
+    delete param_vals;
+  if (init_vals)
+    delete init_vals;
+  if (vcov_mat)
+    delete vcov_mat;
+  if (old_atoms)
+    delete old_atoms;
+  if (atom_substs)
+    delete atom_substs;
+  if (pbuilder)
+    delete pbuilder;
+  if (fbuilder)
+    delete fbuilder;
+}
+
+const PlannerInfo *
+DynareModel::get_planner_info() const
+{
+  if (pbuilder)
+    return &(pbuilder->get_info());
+  return NULL;
+}
+
+const ForwSubstInfo *
+DynareModel::get_forw_subst_info() const
+{
+  if (fbuilder)
+    return &(fbuilder->get_info());
+  return NULL;
+}
+
+const ogp::SubstInfo *
+DynareModel::get_subst_info() const
+{
+  if (atom_substs)
+    return &(atom_substs->get_info());
+  return NULL;
+}
+
+void
+DynareModel::setInitOuter(const Vector &x)
+{
+  if (x.length() != atoms.ny())
+    throw DynareException(__FILE__, __LINE__,
+                          "Wrong length of vector in DynareModel::setInitOuter");
+  for (int i = 0; i < atoms.ny(); i++)
+    (*init_vals)[i] = x[atoms.y2outer_endo()[i]];
+}
+
+void
+DynareModel::print() const
+{
+  printf("all atoms:\n");
+  atoms.print();
+  printf("formulas:\n");
+  DebugOperationFormatter dof(*this);
+  for (int i = 0; i < eqs.nformulas(); i++)
+    {
+      int tf = eqs.formula(i);
+      printf("formula %d:\n", tf);
+      eqs.getTree().print_operation_tree(tf, stdout, dof);
+    }
+}
+
+void
+DynareModel::dump_model(std::ostream &os) const
+{
+  // endogenous variable declaration
+  os << "var";
+  for (int i = 0; i < (int) atoms.get_endovars().size(); i++)
+    os << " " << atoms.get_endovars()[i];
+  os << ";\n\n";
+
+  // exogenous variables
+  os << "varexo";
+  for (int i = 0; i < (int) atoms.get_exovars().size(); i++)
+    os << " " << atoms.get_exovars()[i];
+  os << ";\n\n";
+
+  // parameters
+  os << "parameters";
+  for (int i = 0; i < (int) atoms.get_params().size(); i++)
+    os << " " << atoms.get_params()[i];
+  os << ";\n\n";
+
+  // parameter values
+  os.precision(16);
+  for (int i = 0; i < (int) atoms.get_params().size(); i++)
+    os << atoms.get_params()[i] << "=" << getParams()[i] << ";\n";
+  os << "\n\n";
+
+  // model section
+  ogp::OperationStringConvertor osc(atoms, getParser().getTree());
+  os << "model;\n";
+  for (int i = 0; i < getParser().nformulas(); i++)
+    {
+      os << "// Equation " << i << "\n0 = ";
+      int t = getParser().formula(i);
+      os << osc.convert(getParser().getTree().operation(t), t);
+      os << ";\n";
+    }
+  os << "end;\n";
+
+  // initval as steady state
+  os << "initval;\n";
+  for (int i = 0; i < (int) atoms.get_endovars().size(); i++)
+    os << atoms.get_endovars()[atoms.y2outer_endo()[i]] << "=" << getInit()[i] << ";\n";
+  os << "end;\n";
+}
+
+void
+DynareModel::add_name(const char *name, int flag)
+{
+  if (flag == 1)
+    {
+      // endogenous
+      atoms.register_uniq_endo(name);
+    }
+  else if (flag == 2)
+    {
+      // exogenous
+      atoms.register_uniq_exo(name);
+    }
+  else if (flag == 3)
+    {
+      // parameter
+      atoms.register_uniq_param(name);
+    }
+  else
+    {
+      throw DynareException(__FILE__, __LINE__,
+                            "Unrecognized flag value.");
+    }
+}
+
+void
+DynareModel::check_model() const
+{
+  if (order == -1)
+    throw DynareException(__FILE__, __LINE__,
+                          "Order of approximation not set in DynareModel::check_model");
+
+  if (atoms.ny() != eqs.nformulas())
+    {
+      char mes[1000];
+      sprintf(mes, "Model has %d equations for %d endogenous variables", eqs.nformulas(), atoms.ny());
+      throw DynareException(__FILE__, __LINE__, mes);
+    }
+
+  // check whether all nulary terms of all formulas in eqs are
+  // either constant or assigned to a name
+  for (int i = 0; i < eqs.nformulas(); i++)
+    {
+      int ft = eqs.formula(i);
+      const unordered_set<int> &nuls = eqs.nulary_of_term(ft);
+      for (unordered_set<int>::const_iterator it = nuls.begin();
+           it != nuls.end(); ++it)
+        if (!atoms.is_constant(*it) && !atoms.is_named_atom(*it))
+          throw DynareException(__FILE__, __LINE__,
+                                "Dangling nulary term found, internal error.");
+    }
+
+  int mlag, mlead;
+  atoms.exovarspan(mlead, mlag);
+  if (atoms.nexo() > 0 && (mlead != 0 || mlag != 0))
+    throw DynareException(__FILE__, __LINE__,
+                          "The model contains occurrences of lagged/leaded exogenous variables");
+
+  atoms.endovarspan(mlead, mlag);
+  if (mlead > 1 || mlag < -1)
+    throw DynareException(__FILE__, __LINE__,
+                          "The model contains occurrences of too lagged/leaded endogenous variables");
+
+  // check the dimension of vcov matrix
+  if (getAtoms().nexo() != getVcov().nrows())
+    throw DynareException(__FILE__, __LINE__,
+                          "Dimension of VCOV matrix does not correspond to the shocks");
+}
+
+int
+DynareModel::variable_shift(int t, int tshift)
+{
+  const char *name = atoms.name(t);
+  if (atoms.is_type(name, DynareDynamicAtoms::param)
+      || atoms.is_constant(t))
+    throw DynareException(__FILE__, __LINE__,
+                          "The tree index is not a variable in DynareModel::variable_shift");
+  int ll = atoms.lead(t) + tshift;
+  int res = atoms.index(name, ll);
+  if (res == -1)
+    {
+      std::string str(name);
+      str += '(';
+      char tmp[50];
+      sprintf(tmp, "%d", ll);
+      str += tmp;
+      str += ')';
+      res = eqs.add_nulary(str.c_str());
+    }
+  return res;
+}
+
+void
+DynareModel::variable_shift_map(const unordered_set<int> &a_set, int tshift,
+                                map<int, int> &s_map)
+{
+  s_map.clear();
+  for (unordered_set<int>::const_iterator it = a_set.begin();
+       it != a_set.end(); ++it)
+    {
+      int t = *it;
+      // make shift map only for non-constants and non-parameters
+      if (!atoms.is_constant(t))
+        {
+          const char *name = atoms.name(t);
+          if (atoms.is_type(name, DynareDynamicAtoms::endovar)
+              || atoms.is_type(name, DynareDynamicAtoms::exovar))
+            {
+              int tt = variable_shift(t, tshift);
+              s_map.insert(map<int, int>::value_type(t, tt));
+            }
+        }
+    }
+}
+
+void
+DynareModel::termspan(int t, int &mlead, int &mlag) const
+{
+  mlead = INT_MIN;
+  mlag = INT_MAX;
+  const unordered_set<int> &nul_terms = eqs.nulary_of_term(t);
+  for (unordered_set<int>::const_iterator ni = nul_terms.begin();
+       ni != nul_terms.end(); ++ni)
+    {
+      if (!atoms.is_constant(*ni)
+          && (atoms.is_type(atoms.name(*ni), DynareDynamicAtoms::endovar)
+              || atoms.is_type(atoms.name(*ni), DynareDynamicAtoms::exovar)))
+        {
+          int ll = atoms.lead(*ni);
+          if (ll < mlag)
+            mlag = ll;
+          if (ll > mlead)
+            mlead = ll;
+        }
+    }
+}
+
+bool
+DynareModel::is_constant_term(int t) const
+{
+  const unordered_set<int> &nul_terms = eqs.nulary_of_term(t);
+  for (unordered_set<int>::const_iterator ni = nul_terms.begin();
+       ni != nul_terms.end(); ++ni)
+    if (!atoms.is_constant(*ni)
+        && !atoms.is_type(atoms.name(*ni), DynareDynamicAtoms::param))
+      return false;
+  return true;
+}
+
+unordered_set<int>
+DynareModel::get_nonlinear_subterms(int t) const
+{
+  NLSelector nls(*this);
+  return eqs.getTree().select_terms(t, nls);
+}
+
+void
+DynareModel::substitute_atom_for_term(const char *name, int ll, int t)
+{
+  // if the term t is itself a named atom (parameter, exo, endo),
+  // then we have to unassign it first
+  if (atoms.is_named_atom(t))
+    atoms.unassign_variable(atoms.name(t), atoms.lead(t), t);
+  // assign allocated tree index
+  // for the term now to name(ll)
+  atoms.assign_variable(name, ll, t);
+  // make operation t nulary in operation tree
+  eqs.nularify(t);
+}
+
+void
+DynareModel::final_job()
+{
+  if (t_plobjective != -1 && t_pldiscount != -1)
+    {
+      // at this moment include all equations and all variables; in
+      // future we will exclude purely exogenous processes; todo:
+      PlannerBuilder::Tvarset vset;
+      for (int i = 0; i < atoms.ny(); i++)
+        vset.insert(atoms.get_endovars()[i]);
+      PlannerBuilder::Teqset eset;
+      for (int i = 0; i < eqs.nformulas(); i++)
+        eset.push_back(i);
+
+      // construct the planner builder, this adds a lot of stuff to
+      // the model
+      if (pbuilder)
+        delete pbuilder;
+      pbuilder = new PlannerBuilder(*this, vset, eset);
+    }
+
+  // construct ForwSubstBuilder
+  if (fbuilder)
+    delete fbuilder;
+  fbuilder = new ForwSubstBuilder(*this);
+
+  // call parsing_finished (this will define an outer ordering of all variables)
+  atoms.parsing_finished(ogp::VarOrdering::bfspbfpb);
+  // make a copy of atoms and name it old_atoms
+  if (old_atoms)
+    delete old_atoms;
+  old_atoms = new DynareDynamicAtoms(atoms);
+  // construct empty substitutions from old_atoms to atoms
+  if (atom_substs)
+    delete atom_substs;
+  atom_substs = new ogp::AtomSubstitutions(*old_atoms, atoms);
+  // do the actual substitution, it will also call
+  // parsing_finished for atoms which creates internal orderings
+  atoms.substituteAllLagsAndExo1Leads(eqs, *atom_substs);
+}
+
+extern ogp::location_type dynglob_lloc;
+
+DynareParser::DynareParser(const char *stream, int len, int ord)
+  : DynareModel(),
+    pa_atoms(), paramset(pa_atoms),
+    ia_atoms(), initval(ia_atoms), vcov(),
+    model_beg(0), model_end(-1),
+    paramset_beg(0), paramset_end(-1),
+    initval_beg(0), initval_end(-1),
+    vcov_beg(0), vcov_end(-1),
+    order_beg(0), order_end(-1),
+    plobjective_beg(0), plobjective_end(-1),
+    pldiscount_beg(0), pldiscount_end(-1)
+{
+  // global parse
+  try
+    {
+      parse_glob(len, stream);
+    }
+  catch (const ogp::ParserException &e)
+    {
+      throw ogp::ParserException(e, dynglob_lloc.off);
+    }
+  // setting parameters parse
+  try
+    {
+      if (paramset_end > paramset_beg)
+        paramset.parse(paramset_end-paramset_beg, stream+paramset_beg);
+    }
+  catch (const ogp::ParserException &e)
+    {
+      throw ogp::ParserException(e, paramset_beg);
+    }
+  // model parse
+  try
+    {
+      if (model_end > model_beg)
+        eqs.parse(model_end-model_beg, stream+model_beg);
+      else
+        throw ogp::ParserException("Model section not found.", 0);
+    }
+  catch (const ogp::ParserException &e)
+    {
+      throw ogp::ParserException(e, model_beg);
+    }
+  // initval setting parse
+  try
+    {
+      if (initval_end > initval_beg)
+        initval.parse(initval_end-initval_beg, stream+initval_beg);
+    }
+  catch (const ogp::ParserException &e)
+    {
+      throw ogp::ParserException(e, initval_beg);
+    }
+  // vcov parse
+  try
+    {
+      if (vcov_end > vcov_beg)
+        {
+          vcov.parse(vcov_end-vcov_beg, stream+vcov_beg);
+        }
+    }
+  catch (const ogp::ParserException &e)
+    {
+      throw ogp::ParserException(e, vcov_beg);
+    }
+  // planner objective parse
+  try
+    {
+      if (plobjective_end > plobjective_beg)
+        {
+          eqs.parse(plobjective_end-plobjective_beg, stream+plobjective_beg);
+          t_plobjective = eqs.pop_last_formula();
+        }
+    }
+  catch (const ogp::ParserException &e)
+    {
+      throw ogp::ParserException(e, plobjective_beg);
+    }
+  // planner discount parse
+  try
+    {
+      if (pldiscount_end > pldiscount_beg)
+        {
+          t_pldiscount = parse_pldiscount(pldiscount_end - pldiscount_beg,
+                                          stream + pldiscount_beg);
+        }
+    }
+  catch (const ogp::ParserException &e)
+    {
+      throw ogp::ParserException(e, pldiscount_beg);
+    }
+  // order parse
+  try
+    {
+      if (order_end > order_beg)
+        {
+          order = parse_order(order_end > order_beg, stream + order_beg);
+        }
+    }
+  catch (const ogp::ParserException &e)
+    {
+      throw ogp::ParserException(e, order_beg);
+    }
+
+  // check the overridden order
+  if (ord != -1)
+    order = ord;
+
+  // end parsing job, add planner's FOCs, make substitutions
+  DynareModel::final_job();
+
+  // calculate parameters
+  calc_params();
+  // calculate initial values
+  calc_init();
+
+  if (vcov_end > vcov_beg)
+    vcov_mat = new ParsedMatrix(vcov);
+  else
+    {
+      // vcov has not been asserted, set it to unit matrix
+      vcov_mat = new TwoDMatrix(atoms.nexo(), atoms.nexo());
+      vcov_mat->unit();
+    }
+
+  // check the model
+  check_model();
+
+  // differentiate
+  if (order >= 1)
+    eqs.differentiate(order);
+}
+
+DynareParser::DynareParser(const DynareParser &dp)
+  : DynareModel(dp),
+    pa_atoms(dp.pa_atoms), paramset(dp.paramset, pa_atoms),
+    ia_atoms(dp.ia_atoms), initval(dp.initval, ia_atoms), vcov(dp.vcov),
+    model_beg(dp.model_beg), model_end(dp.model_end),
+    paramset_beg(dp.paramset_beg), paramset_end(dp.paramset_end),
+    initval_beg(dp.initval_beg), initval_end(dp.initval_end),
+    vcov_beg(dp.vcov_beg), vcov_end(dp.vcov_end),
+    order_beg(dp.order_beg), order_end(dp.order_end),
+    plobjective_beg(dp.plobjective_beg), plobjective_end(dp.plobjective_end),
+    pldiscount_beg(dp.pldiscount_beg), pldiscount_end(dp.pldiscount_end)
+{
+}
+
+DynareParser::~DynareParser()
+{
+}
+
+void
+DynareParser::add_name(const char *name, int flag)
+{
+  DynareModel::add_name(name, flag);
+  // register with static atoms used for atom assignements
+  if (flag == 1)
+    {
+      // endogenous
+      ia_atoms.register_name(name);
+    }
+  else if (flag == 2)
+    {
+      // exogenous
+      ia_atoms.register_name(name);
+    }
+  else if (flag == 3)
+    {
+      // parameter
+      pa_atoms.register_name(name);
+      ia_atoms.register_name(name);
+    }
+  else
+    {
+      throw DynareException(__FILE__, __LINE__,
+                            "Unrecognized flag value.");
+    }
+}
+
+void
+DynareParser::error(const char *mes)
+{
+  // throwing zero offset since this exception will be caugth at
+  // constructor
+  throw ogp::ParserException(mes, 0);
+}
+
+void
+DynareParser::print() const
+{
+  DynareModel::print();
+  printf("parameter atoms:\n");
+  paramset.print();
+  printf("initval atoms:\n");
+  initval.print();
+  printf("model position: %d %d\n", model_beg, model_end);
+  printf("paramset position: %d %d\n", paramset_beg, paramset_end);
+  printf("initval position: %d %d\n", initval_beg, initval_end);
+}
+
+/** A global symbol for passing info to the DynareParser from
+ * parser. */
+DynareParser *dynare_parser;
+
+/** The declarations of functions defined in dynglob_ll.cc and
+ * dynglob_tab.cc generated from dynglob.lex and dynglob.y */
+void *dynglob__scan_buffer(char *, size_t);
+void dynglob__destroy_buffer(void *);
+void dynglob_parse();
+extern ogp::location_type dynglob_lloc;
+
+void
+DynareParser::parse_glob(int length, const char *stream)
+{
+  char *buffer = new char[length+2];
+  strncpy(buffer, stream, length);
+  buffer[length] = '\0';
+  buffer[length+1] = '\0';
+  void *p = dynglob__scan_buffer(buffer, (unsigned int) length+2);
+  dynare_parser = this;
+  dynglob_parse();
+  delete [] buffer;
+  dynglob__destroy_buffer(p);
+}
+
+int
+DynareParser::parse_order(int len, const char *str)
+{
+  char *buf = new char[len+1];
+  strncpy(buf, str, len);
+  buf[len] = '\0';
+  int res;
+  sscanf(buf, "%d", &res);
+  delete [] buf;
+  return res;
+}
+
+int
+DynareParser::parse_pldiscount(int len, const char *str)
+{
+  char *buf = new char[len+1];
+  strncpy(buf, str, len);
+  buf[len] = '\0';
+  if (!atoms.is_type(buf, DynareDynamicAtoms::param))
+    throw ogp::ParserException(std::string("Name ") + buf + " is not a parameter", 0);
+
+  int t = atoms.index(buf, 0);
+  if (t == -1)
+    t = eqs.add_nulary(buf);
+
+  delete [] buf;
+  return t;
+}
+
+void
+DynareParser::calc_params()
+{
+  if (param_vals)
+    delete param_vals;
+
+  param_vals = new Vector(atoms.np());
+  ogp::AtomAsgnEvaluator aae(paramset);
+  aae.eval();
+  for (int i = 0; i < atoms.np(); i++)
+    (*param_vals)[i] = aae.get_value(atoms.get_params()[i]);
+
+  for (unsigned int i = 0; i < atoms.get_params().size(); i++)
+    if (!std::isfinite((*param_vals)[i]))
+      printf("dynare++: warning: value for parameter %s is not finite\n",
+             atoms.get_params()[i]);
+}
+
+void
+DynareParser::calc_init()
+{
+  // update initval atoms assignings according to substitutions
+  if (atom_substs)
+    initval.apply_subst(atom_substs->get_old2new());
+
+  // calculate the vector of initial values
+  if (init_vals)
+    delete init_vals;
+  init_vals = new Vector(atoms.ny());
+  ogp::AtomAsgnEvaluator aae(initval);
+  // set parameters
+  for (int ip = 0; ip < atoms.np(); ip++)
+    aae.set_user_value(atoms.get_params()[ip], (*param_vals)[ip]);
+  // set exogenous to zeros
+  for (int ie = 0; ie < atoms.nexo(); ie++)
+    aae.set_user_value(atoms.get_exovars()[ie], 0.0);
+  // evaluate
+  aae.eval();
+  // set results to internally ordered vector init_vals
+  for (int outer = 0; outer < atoms.ny(); outer++)
+    {
+      int i = atoms.outer2y_endo()[outer];
+      (*init_vals)[i] = aae.get_value(atoms.get_endovars()[outer]);
+    }
+
+  // if the planner's FOCs have been added, then add estimate of
+  // Lagrange multipliers to the vector
+  if (pbuilder)
+    {
+      MultInitSS mis(*pbuilder, *param_vals, *init_vals);
+    }
+
+  // if forward substitution builder has been created, we have to
+  // its substitutions and evaluate them
+  if (fbuilder)
+    ogdyn::DynareSteadySubstitutions dss(atoms, eqs.getTree(),
+                                         fbuilder->get_aux_map(), *param_vals, *init_vals);
+
+  for (unsigned int i = 0; i < atoms.get_endovars().size(); i++)
+    if (!std::isfinite((*init_vals)[i]))
+      printf("dynare++: warning: initval for <%s> is not finite\n",
+             atoms.get_endovars()[atoms.y2outer_endo()[i]]);
+}
+
+// this returns false for linear functions
+bool
+NLSelector::operator()(int t) const
+{
+  const ogp::Operation &op = model.getParser().getTree().operation(t);
+  const DynareDynamicAtoms &atoms = model.getAtoms();
+  // if the term is constant, return false
+  if (model.is_constant_term(t))
+    return false;
+  int nary = op.nary();
+  if (nary == 0)
+    {
+      if (atoms.is_type(atoms.name(t), DynareDynamicAtoms::endovar)
+          || atoms.is_type(atoms.name(t), DynareDynamicAtoms::exovar))
+        return true;
+      else
+        return false;
+    }
+  else if (nary == 1)
+    {
+      if (op.getCode() == ogp::UMINUS)
+        return false;
+      else
+        return true;
+    }
+  else
+    {
+      if (op.getCode() == ogp::TIMES)
+        // if at least one operand is constant, than the TIMES is linear
+        if (model.is_constant_term(op.getOp1())
+            || model.is_constant_term(op.getOp2()))
+          return false;
+        else
+          return true;
+      // both PLUS and MINUS are linear
+      if (op.getCode() == ogp::PLUS
+          || op.getCode() == ogp::MINUS)
+        return false;
+      // POWER is linear if exponent or base is 0 or one
+      if (op.getCode() == ogp::POWER
+          && (op.getOp1() == ogp::OperationTree::zero
+              || op.getOp1() == ogp::OperationTree::one
+              || op.getOp2() == ogp::OperationTree::zero
+              || op.getOp2() == ogp::OperationTree::one))
+        return false;
+      else
+        return true;
+      // DIVIDE is linear if the denominator is constant, or if
+      // the nominator is zero
+      if (op.getCode() == ogp::DIVIDE
+          && (op.getOp1() == ogp::OperationTree::zero
+              || model.is_constant_term(op.getOp2())))
+        return false;
+      else
+        return true;
+    }
+
+  throw DynareException(__FILE__, __LINE__,
+                        "Wrong operation in operation tree");
+  return false;
+}
+
+DynareSPModel::DynareSPModel(const char **endo, int num_endo,
+                             const char **exo, int num_exo,
+                             const char **par, int num_par,
+                             const char *equations, int len,
+                             int ord)
+  : DynareModel()
+{
+  // set the order
+  order = ord;
+
+  // add names
+  for (int i = 0; i < num_endo; i++)
+    add_name(endo[i], 1);
+  for (int i = 0; i < num_exo; i++)
+    add_name(exo[i], 2);
+  for (int i = 0; i < num_par; i++)
+    add_name(par[i], 3);
+
+  // parse the equations
+  eqs.parse(len, equations);
+
+  // parsing finished
+  atoms.parsing_finished(ogp::VarOrdering::bfspbfpb);
+
+  // create what has to be created from DynareModel
+  param_vals = new Vector(atoms.np());
+  init_vals = new Vector(atoms.ny());
+  vcov_mat = new TwoDMatrix(atoms.nexo(), atoms.nexo());
+
+  // check the model
+  check_model();
+
+  // differentiate
+  if (order >= 1)
+    eqs.differentiate(order);
+}
+
+void
+ModelSSWriter::write_der0(FILE *fd)
+{
+  write_der0_preamble(fd);
+  write_atom_assignment(fd);
+
+  stop_set.clear();
+  for (int fi = 0; fi < model.eqs.nformulas(); fi++)
+    otree.print_operation_tree(model.eqs.formula(fi), fd, *this);
+
+  write_der0_assignment(fd);
+}
+
+void
+ModelSSWriter::write_der1(FILE *fd)
+{
+  write_der1_preamble(fd);
+  write_atom_assignment(fd);
+
+  stop_set.clear();
+
+  const vector<int> &variables = model.getAtoms().variables();
+  const vector<int> &eam = model.getAtoms().get_endo_atoms_map();
+  for (int i = 0; i < model.getParser().nformulas(); i++)
+    {
+      const ogp::FormulaDerivatives &fder = model.getParser().derivatives(i);
+      for (unsigned int j = 0; j < eam.size(); j++)
+        {
+          int t = fder.derivative(ogp::FoldMultiIndex(variables.size(), 1, eam[j]));
+          if (t > 0)
+            otree.print_operation_tree(t, fd, *this);
+        }
+    }
+
+  write_der1_assignment(fd);
+}
+
+MatlabSSWriter::MatlabSSWriter(const DynareModel &dm, const char *idd)
+  : ModelSSWriter(dm), id(new char[strlen(idd)+1])
+{
+  strcpy(id, idd);
+}
+
+void
+MatlabSSWriter::write_der0_preamble(FILE *fd) const
+{
+  fprintf(fd,
+          "%% Usage:\n"
+          "%%       out = %s_f(params, y)\n"
+          "%%   where\n"
+          "%%       out    is a (%d,1) column vector of the residuals\n"
+          "%%              of the static system\n",
+          id, model.getAtoms().ny());
+  write_common1_preamble(fd);
+  fprintf(fd,
+          "function out = %s_f(params, y)\n", id);
+  write_common2_preamble(fd);
+}
+
+void
+MatlabSSWriter::write_der1_preamble(FILE *fd) const
+{
+  fprintf(fd,
+          "%% Usage:\n"
+          "%%       out = %s_ff(params, y)\n"
+          "%%   where\n"
+          "%%       out    is a (%d,%d) matrix of the first order\n"
+          "%%              derivatives of the static system residuals\n"
+          "%%              columns correspond to endo variables in\n"
+          "%%              the ordering as declared\n",
+          id, model.getAtoms().ny(), model.getAtoms().ny());
+  write_common1_preamble(fd);
+  fprintf(fd,
+          "function out = %s_ff(params, y)\n", id);
+  write_common2_preamble(fd);
+}
+
+void
+MatlabSSWriter::write_common1_preamble(FILE *fd) const
+{
+  fprintf(fd,
+          "%%       params is a (%d,1) vector of parameter values\n"
+          "%%              in the ordering as declared\n"
+          "%%       y      is a (%d,1) vector of endogenous variables\n"
+          "%%              in the ordering as declared\n"
+          "%%\n"
+          "%% Created by Dynare++ v. %s\n", model.getAtoms().np(),
+          model.getAtoms().ny(), DYNVERSION);
+  // write ordering of parameters
+  fprintf(fd, "\n%% params ordering\n%% =====================\n");
+  for (unsigned int ip = 0; ip < model.getAtoms().get_params().size(); ip++)
+    {
+      const char *parname = model.getAtoms().get_params()[ip];
+      fprintf(fd, "%% %s\n", parname);
+    }
+  // write endogenous variables
+  fprintf(fd, "%%\n%% y ordering\n%% =====================\n");
+  for (unsigned int ie = 0; ie < model.getAtoms().get_endovars().size(); ie++)
+    {
+      const char *endoname = model.getAtoms().get_endovars()[ie];
+      fprintf(fd, "%% %s\n", endoname);
+    }
+  fprintf(fd, "\n");
+}
+
+void
+MatlabSSWriter::write_common2_preamble(FILE *fd) const
+{
+  fprintf(fd, "if size(y) ~= [%d,1]\n\terror('Wrong size of y, must be [%d,1]');\nend\n",
+          model.getAtoms().ny(), model.getAtoms().ny());
+  fprintf(fd, "if size(params) ~= [%d,1]\n\terror('Wrong size of params, must be [%d,1]');\nend\n\n",
+          model.getAtoms().np(), model.getAtoms().np());
+}
+
+void
+MatlabSSWriter::write_atom_assignment(FILE *fd) const
+{
+  // write OperationTree::num_constants
+  fprintf(fd, "%% hardwired constants\n");
+  ogp::EvalTree etree(model.getParser().getTree(), ogp::OperationTree::num_constants-1);
+  for (int i = 0; i < ogp::OperationTree::num_constants; i++)
+    {
+      format_nulary(i, fd);
+      double g = etree.eval(i);
+      if (std::isnan(g))
+        fprintf(fd, " = NaN;\n");
+      else
+        fprintf(fd, " = %12.8g;\n", etree.eval(i));
+    }
+  // write numerical constants
+  fprintf(fd, "%% numerical constants\n");
+  const ogp::Constants::Tconstantmap &cmap = model.getAtoms().get_constantmap();
+  for (ogp::Constants::Tconstantmap::const_iterator it = cmap.begin();
+       it != cmap.end(); ++it)
+    {
+      format_nulary((*it).first, fd);
+      fprintf(fd, " = %12.8g;\n", (*it).second);
+    }
+  // write parameters
+  fprintf(fd, "%% parameter values\n");
+  for (unsigned int ip = 0; ip < model.getAtoms().get_params().size(); ip++)
+    {
+      const char *parname = model.getAtoms().get_params()[ip];
+      int t = model.getAtoms().index(parname, 0);
+      if (t == -1)
+        {
+          fprintf(fd, "%% %s not used in the model\n", parname);
+        }
+      else
+        {
+          format_nulary(t, fd);
+          fprintf(fd, " = params(%d); %% %s\n", ip+1, parname);
+        }
+    }
+  // write exogenous variables
+  fprintf(fd, "%% exogenous variables to zeros\n");
+  for (unsigned int ie = 0; ie < model.getAtoms().get_exovars().size(); ie++)
+    {
+      const char *exoname = model.getAtoms().get_exovars()[ie];
+      try
+        {
+          const ogp::DynamicAtoms::Tlagmap &lmap = model.getAtoms().lagmap(exoname);
+          for (ogp::DynamicAtoms::Tlagmap::const_iterator it = lmap.begin();
+               it != lmap.end(); ++it)
+            {
+              format_nulary((*it).second, fd);
+              fprintf(fd, " = 0.0; %% %s\n", exoname);
+            }
+        }
+      catch (const ogu::Exception &e)
+        {
+          // ignore the error of not found variable in the tree
+        }
+    }
+  // write endogenous variables
+  fprintf(fd, "%% endogenous variables to y\n");
+  for (unsigned int ie = 0; ie < model.getAtoms().get_endovars().size(); ie++)
+    {
+      const char *endoname = model.getAtoms().get_endovars()[ie];
+      const ogp::DynamicAtoms::Tlagmap &lmap = model.getAtoms().lagmap(endoname);
+      for (ogp::DynamicAtoms::Tlagmap::const_iterator it = lmap.begin();
+           it != lmap.end(); ++it)
+        {
+          format_nulary((*it).second, fd);
+          fprintf(fd, " = y(%d); %% %s\n", ie+1, endoname);
+        }
+    }
+  fprintf(fd, "\n");
+}
+
+void
+MatlabSSWriter::write_der0_assignment(FILE *fd) const
+{
+
+  // initialize out variable
+  fprintf(fd, "%% setting the output variable\n");
+  fprintf(fd, "out = zeros(%d, 1);\n", model.getParser().nformulas());
+
+  // fill out with the terms
+  for (int i = 0; i < model.getParser().nformulas(); i++)
+    {
+      fprintf(fd, "out(%d) = ", i+1);
+      format_term(model.getParser().formula(i), fd);
+      fprintf(fd, ";\n");
+    }
+}
+
+void
+MatlabSSWriter::write_der1_assignment(FILE *fd) const
+{
+  // initialize out variable
+  fprintf(fd, "%% setting the output variable\n");
+  fprintf(fd, "out = zeros(%d, %d);\n", model.getParser().nformulas(), model.getAtoms().ny());
+
+  // fill out with the terms
+  const vector<int> &variables = model.getAtoms().variables();
+  const vector<int> &eam = model.getAtoms().get_endo_atoms_map();
+  for (int i = 0; i < model.getParser().nformulas(); i++)
+    {
+      const ogp::FormulaDerivatives &fder = model.getParser().derivatives(i);
+      for (unsigned int j = 0; j < eam.size(); j++)
+        {
+          int tvar = variables[eam[j]];
+          const char *name = model.getAtoms().name(tvar);
+          int yi = model.getAtoms().name2outer_endo(name);
+          int t = fder.derivative(ogp::FoldMultiIndex(variables.size(), 1, eam[j]));
+          if (t != ogp::OperationTree::zero)
+            {
+              fprintf(fd, "out(%d,%d) = out(%d,%d) + ", i+1, yi+1, i+1, yi+1);
+              format_term(t, fd);
+              fprintf(fd, "; %% %s(%d)\n", name, model.getAtoms().lead(tvar));
+            }
+        }
+    }
+}
+
+void
+MatlabSSWriter::format_term(int t, FILE *fd) const
+{
+  fprintf(fd, "t%d", t);
+}
+
+void
+MatlabSSWriter::format_nulary(int t, FILE *fd) const
+{
+  fprintf(fd, "a%d", t);
+}
+
+void
+DebugOperationFormatter::format_nulary(int t, FILE *fd) const
+{
+  const DynareDynamicAtoms &a = model.getAtoms();
+
+  if (t == ogp::OperationTree::zero)
+    fprintf(fd, "0");
+  else if (t == ogp::OperationTree::one)
+    fprintf(fd, "1");
+  else if (t == ogp::OperationTree::nan)
+    fprintf(fd, "NaN");
+  else if (t == ogp::OperationTree::two_over_pi)
+    fprintf(fd, "2/sqrt(PI)");
+  else if (a.is_constant(t))
+    fprintf(fd, "%g", a.get_constant_value(t));
+  else
+    {
+      int ll = a.lead(t);
+      const char *name = a.name(t);
+      if (ll == 0)
+        fprintf(fd, "%s", name);
+      else
+        fprintf(fd, "%s(%d)", name, ll);
+    }
+}
diff --git a/dynare++/src/dynare_model.cpp b/dynare++/src/dynare_model.cpp
deleted file mode 100644
index 91d8dda2e4018f1928c30f24aeb84571275194f5..0000000000000000000000000000000000000000
--- a/dynare++/src/dynare_model.cpp
+++ /dev/null
@@ -1,957 +0,0 @@
-// Copyright (C) 2006-2011, Ondra Kamenik
-
-#include "parser/cc/parser_exception.h"
-#include "parser/cc/location.h"
-#include "utils/cc/exception.h"
-#include "dynare_model.h"
-#include "dynare_exception.h"
-#include "planner_builder.h"
-#include "forw_subst_builder.h"
-
-#include <cstdlib>
-
-#include <string>
-#include <cmath>
-#include <climits>
-
-using namespace ogdyn;
-
-ParsedMatrix::ParsedMatrix(const ogp::MatrixParser& mp)
-	: TwoDMatrix(mp.nrows(), mp.ncols())
-{
-	zeros();
-	for (ogp::MPIterator it = mp.begin(); it != mp.end(); ++it)
-		get(it.row(), it.col()) = *it;
-}
-
-DynareModel::DynareModel()
-	: atoms(), eqs(atoms), order(-1),
-	  param_vals(0), init_vals(0), vcov_mat(0),
-	  t_plobjective(-1), t_pldiscount(-1),
-	  pbuilder(NULL), fbuilder(NULL),
-	  atom_substs(NULL), old_atoms(NULL)
-{}
-
-DynareModel::DynareModel(const DynareModel& dm)
-	: atoms(dm.atoms), eqs(dm.eqs, atoms), order(dm.order),
-	  param_vals(0), init_vals(0), vcov_mat(0),
-	  t_plobjective(dm.t_plobjective),
-	  t_pldiscount(dm.t_pldiscount),
-	  pbuilder(NULL), fbuilder(NULL),
-	  atom_substs(NULL), old_atoms(NULL)
-{
-	if (dm.param_vals)
-		param_vals = new Vector((const Vector&)*(dm.param_vals));
-	if (dm.init_vals)
-		init_vals = new Vector((const Vector&)*(dm.init_vals));
-	if (dm.vcov_mat)
-		vcov_mat = new TwoDMatrix((const TwoDMatrix&)*(dm.vcov_mat));
-	if (dm.old_atoms)
-		old_atoms = new DynareDynamicAtoms((const DynareDynamicAtoms&)*(dm.old_atoms));
-	if (dm.atom_substs)
-		atom_substs = new ogp::AtomSubstitutions((*dm.atom_substs), *old_atoms, atoms);
-	if (dm.pbuilder)
-		pbuilder = new PlannerBuilder(*(dm.pbuilder), *this);
-	if (dm.fbuilder)
-		fbuilder = new ForwSubstBuilder(*(dm.fbuilder), *this);
-}
-
-DynareModel::~DynareModel()
-{
-	if (param_vals)
-		delete param_vals;
-	if (init_vals)
-		delete init_vals;
-	if (vcov_mat)
-		delete vcov_mat;
-	if (old_atoms)
-		delete old_atoms;
-	if (atom_substs)
-		delete atom_substs;
-	if (pbuilder)
-		delete pbuilder;
-	if (fbuilder)
-		delete fbuilder;
-}
-
-const PlannerInfo* DynareModel::get_planner_info() const
-{
-	if (pbuilder)
-		return &(pbuilder->get_info());
-	return NULL;
-}
-
-const ForwSubstInfo* DynareModel::get_forw_subst_info() const
-{
-	if (fbuilder)
-		return &(fbuilder->get_info());
-	return NULL;
-}
-
-const ogp::SubstInfo* DynareModel::get_subst_info() const
-{
-	if (atom_substs)
-		return &(atom_substs->get_info());
-	return NULL;
-}
-
-void DynareModel::setInitOuter(const Vector& x)
-{
-	if (x.length() != atoms.ny())
-		throw DynareException(__FILE__, __LINE__,
-							  "Wrong length of vector in DynareModel::setInitOuter");
-	for (int i = 0; i < atoms.ny(); i++)
-		(*init_vals)[i] = x[atoms.y2outer_endo()[i]];
-}
-
-void DynareModel::print() const
-{
-	printf("all atoms:\n");
-	atoms.print();
-	printf("formulas:\n");
-	DebugOperationFormatter dof(*this);
-	for (int i = 0; i < eqs.nformulas(); i++) {
-		int tf = eqs.formula(i);
-		printf("formula %d:\n", tf);
-		eqs.getTree().print_operation_tree(tf, stdout, dof);
-	}
-}
-
-void DynareModel::dump_model(std::ostream& os) const
-{
-	// endogenous variable declaration
-	os << "var";
-	for (int i = 0; i < (int)atoms.get_endovars().size(); i++)
-		os << " " << atoms.get_endovars()[i];
-	os << ";\n\n";
-
-	// exogenous variables
-	os << "varexo";
-	for (int i = 0; i < (int)atoms.get_exovars().size(); i++)
-		os << " " << atoms.get_exovars()[i];
-	os << ";\n\n";
-
-	// parameters
-	os << "parameters";
-	for (int i = 0; i < (int)atoms.get_params().size(); i++)
-		os << " " << atoms.get_params()[i];
-	os << ";\n\n";
-
-	// parameter values
-	os.precision(16);
-	for (int i = 0; i < (int)atoms.get_params().size(); i++)
-		os << atoms.get_params()[i] << "=" << getParams()[i] << ";\n";
-	os << "\n\n";
-
-	// model section
-	ogp::OperationStringConvertor osc(atoms, getParser().getTree());
-	os << "model;\n";
-	for (int i = 0; i < getParser().nformulas(); i++) {
-		os << "// Equation " << i << "\n0 = ";
-		int t = getParser().formula(i);
-		os << osc.convert(getParser().getTree().operation(t), t);
-		os << ";\n";
-	}
-	os << "end;\n";
-
-	// initval as steady state
-	os << "initval;\n";
-	for (int i = 0; i < (int)atoms.get_endovars().size(); i++)
-		os << atoms.get_endovars()[atoms.y2outer_endo()[i]] << "=" << getInit()[i] << ";\n";
-	os << "end;\n";
-}
-
-void DynareModel::add_name(const char* name, int flag)
-{
-	if (flag == 1) {
-		// endogenous
-		atoms.register_uniq_endo(name);
-	} else if (flag == 2) {
-		// exogenous
-		atoms.register_uniq_exo(name);
-	} else if (flag == 3) {
-		// parameter
-		atoms.register_uniq_param(name);
-	} else {
-		throw DynareException(__FILE__, __LINE__,
-							  "Unrecognized flag value.");
-	}
-}
-
-void DynareModel::check_model() const
-{
-	if (order == -1)
-		throw DynareException(__FILE__,__LINE__,
-							  "Order of approximation not set in DynareModel::check_model");
-
-	if (atoms.ny() != eqs.nformulas()) {
-		char mes[1000];
-		sprintf(mes, "Model has %d equations for %d endogenous variables", eqs.nformulas(), atoms.ny());
-		throw DynareException(__FILE__, __LINE__, mes);
-	}
-	
-	// check whether all nulary terms of all formulas in eqs are
-	// either constant or assigned to a name
-	for (int i = 0; i < eqs.nformulas(); i++) {
-		int ft = eqs.formula(i);
-		const unordered_set<int>& nuls = eqs.nulary_of_term(ft);
-		for (unordered_set<int>::const_iterator it = nuls.begin();
-			 it != nuls.end(); ++it)
-			if (! atoms.is_constant(*it) && ! atoms.is_named_atom(*it))
-				throw DynareException(__FILE__,__LINE__,
-									  "Dangling nulary term found, internal error.");
-	}
-
-	int mlag, mlead;
-	atoms.exovarspan(mlead, mlag);
-	if (atoms.nexo() > 0 && (mlead != 0 || mlag != 0))
-		throw DynareException(__FILE__,__LINE__,
-							  "The model contains occurrences of lagged/leaded exogenous variables");
-
-	atoms.endovarspan(mlead, mlag);
-	if (mlead > 1 || mlag < -1)
-		throw DynareException(__FILE__,__LINE__,
-							  "The model contains occurrences of too lagged/leaded endogenous variables");
-
-	// check the dimension of vcov matrix
-	if (getAtoms().nexo() != getVcov().nrows())
-		throw DynareException(__FILE__,__LINE__,
-							  "Dimension of VCOV matrix does not correspond to the shocks");
-}
-
-int DynareModel::variable_shift(int t, int tshift)
-{
-	const char* name = atoms.name(t);
-	if (atoms.is_type(name, DynareDynamicAtoms::param) ||
-		atoms.is_constant(t))
-		throw DynareException(__FILE__, __LINE__,
-							  "The tree index is not a variable in DynareModel::variable_shift");
-	int ll = atoms.lead(t) + tshift;
-	int res = atoms.index(name, ll);
-	if (res == -1) {
-		std::string str(name);
-		str += '(';
-		char tmp[50];
-		sprintf(tmp,"%d",ll);
-		str += tmp;
-		str += ')';
-		res = eqs.add_nulary(str.c_str());
-	}
-	return res;
-}
-
-void DynareModel::variable_shift_map(const unordered_set<int>& a_set, int tshift,
-									 map<int,int>& s_map)
-{
-	s_map.clear();
-	for (unordered_set<int>::const_iterator it = a_set.begin();
-		 it != a_set.end(); ++it) {
-		int t = *it;
-		// make shift map only for non-constants and non-parameters
-		if (! atoms.is_constant(t)) {
-			const char* name = atoms.name(t);
-			if (atoms.is_type(name, DynareDynamicAtoms::endovar) ||
-				atoms.is_type(name, DynareDynamicAtoms::exovar)) {
-				int tt = variable_shift(t, tshift);
-				s_map.insert(map<int,int>::value_type(t,tt));
-			}
-		}
-	}
-}
-
-void DynareModel::termspan(int t, int& mlead, int& mlag) const
-{
-	mlead = INT_MIN;
-	mlag = INT_MAX;
-	const unordered_set<int>& nul_terms = eqs.nulary_of_term(t);
-	for (unordered_set<int>::const_iterator ni = nul_terms.begin();
-		 ni != nul_terms.end(); ++ni) {
-		if (!atoms.is_constant(*ni) &&
-			(atoms.is_type(atoms.name(*ni), DynareDynamicAtoms::endovar) ||
-			 atoms.is_type(atoms.name(*ni), DynareDynamicAtoms::exovar))) {
-			int ll = atoms.lead(*ni);
-			if (ll < mlag)
-				mlag = ll;
-			if (ll > mlead)
-				mlead = ll;
-		}
-	}
-}
-
-bool DynareModel::is_constant_term(int t) const
-{
-	const unordered_set<int>& nul_terms = eqs.nulary_of_term(t);
-	for (unordered_set<int>::const_iterator ni = nul_terms.begin();
-		 ni != nul_terms.end(); ++ni)
-		if (! atoms.is_constant(*ni) &&
-			! atoms.is_type(atoms.name(*ni), DynareDynamicAtoms::param))
-			return false;
-	return true;
-}
-
-unordered_set<int> DynareModel::get_nonlinear_subterms(int t) const
-{
-	NLSelector nls(*this);
-	return eqs.getTree().select_terms(t, nls);
-}
-
-void DynareModel::substitute_atom_for_term(const char* name, int ll, int t)
-{
-	// if the term t is itself a named atom (parameter, exo, endo),
-	// then we have to unassign it first
-	if (atoms.is_named_atom(t))
-		atoms.unassign_variable(atoms.name(t), atoms.lead(t), t);
-	// assign allocated tree index
-	// for the term now to name(ll)
-	atoms.assign_variable(name, ll, t);
-	// make operation t nulary in operation tree
-	eqs.nularify(t);
-}
-
-void DynareModel::final_job()
-{
-	if (t_plobjective != -1 && t_pldiscount != -1) {
-		// at this moment include all equations and all variables; in
-		// future we will exclude purely exogenous processes; todo:
-		PlannerBuilder::Tvarset vset;
-		for (int i = 0; i < atoms.ny(); i++)
-			vset.insert(atoms.get_endovars()[i]);
-		PlannerBuilder::Teqset eset;
-		for (int i = 0; i < eqs.nformulas(); i++)
-			eset.push_back(i);
-
-		// construct the planner builder, this adds a lot of stuff to
-		// the model
-		if (pbuilder)
-			delete pbuilder;
-		pbuilder = new PlannerBuilder(*this, vset, eset);
-	}
-
-	// construct ForwSubstBuilder
-	if (fbuilder)
-		delete fbuilder;
-	fbuilder = new ForwSubstBuilder(*this);
-
-	// call parsing_finished (this will define an outer ordering of all variables)
-	atoms.parsing_finished(ogp::VarOrdering::bfspbfpb);
-    // make a copy of atoms and name it old_atoms
-	if (old_atoms)
-		delete old_atoms;
-	old_atoms = new DynareDynamicAtoms(atoms);
-	// construct empty substitutions from old_atoms to atoms
-	if (atom_substs)
-		delete atom_substs;
-	atom_substs = new ogp::AtomSubstitutions(*old_atoms, atoms);
-	// do the actual substitution, it will also call
-	// parsing_finished for atoms which creates internal orderings
-	atoms.substituteAllLagsAndExo1Leads(eqs, *atom_substs);
-}
-
-extern ogp::location_type dynglob_lloc;
-
-DynareParser::DynareParser(const char* stream, int len, int ord)
-	: DynareModel(),
-	  pa_atoms(), paramset(pa_atoms),
-      ia_atoms(), initval(ia_atoms), vcov(),
-	  model_beg(0), model_end(-1),
-	  paramset_beg(0), paramset_end(-1),
-	  initval_beg(0), initval_end(-1),
-	  vcov_beg(0), vcov_end(-1),
-	  order_beg(0), order_end(-1),
-	  plobjective_beg(0), plobjective_end(-1),
-	  pldiscount_beg(0), pldiscount_end(-1)
-{
-	// global parse
-	try {
-		parse_glob(len, stream);
-	} catch (const ogp::ParserException& e) {
-		throw ogp::ParserException(e, dynglob_lloc.off);
-	}
-	// setting parameters parse
-	try {
-		if (paramset_end > paramset_beg)
-			paramset.parse(paramset_end-paramset_beg, stream+paramset_beg);
-	} catch (const ogp::ParserException& e) {
-		throw ogp::ParserException(e, paramset_beg);
-	}
-	// model parse
-	try {
-		if (model_end > model_beg)
-			eqs.parse(model_end-model_beg, stream+model_beg);
-		else
-			throw ogp::ParserException("Model section not found.", 0);
-	} catch (const ogp::ParserException& e) {
-		throw ogp::ParserException(e, model_beg);
-	}
-	// initval setting parse
-	try {
-		if (initval_end > initval_beg)
-			initval.parse(initval_end-initval_beg, stream+initval_beg);
-	} catch (const ogp::ParserException& e) {
-		throw ogp::ParserException(e, initval_beg);
-	}
-	// vcov parse
-	try {
-		if (vcov_end > vcov_beg) {
-			vcov.parse(vcov_end-vcov_beg, stream+vcov_beg);
-		}
-	} catch (const ogp::ParserException& e) {
-		throw ogp::ParserException(e, vcov_beg);
-	}
-	// planner objective parse
-	try {
-		if (plobjective_end > plobjective_beg) {
-			eqs.parse(plobjective_end-plobjective_beg, stream+plobjective_beg);
-			t_plobjective = eqs.pop_last_formula();
-		}
-	} catch (const ogp::ParserException& e) {
-		throw ogp::ParserException(e, plobjective_beg);
-	}
-	// planner discount parse
-	try {
-		if (pldiscount_end > pldiscount_beg) {
-			t_pldiscount = parse_pldiscount(pldiscount_end - pldiscount_beg,
-											stream + pldiscount_beg);
-		}
-	} catch (const ogp::ParserException& e) {
-		throw ogp::ParserException(e, pldiscount_beg);
-	}
-	// order parse
-	try {
-		if (order_end > order_beg) {
-			order = parse_order(order_end > order_beg, stream + order_beg);
-		}
-	} catch (const ogp::ParserException& e) {
-		throw ogp::ParserException(e, order_beg);
-	}
-
-	// check the overridden order
-	if (ord != -1)
-		order = ord;
-
-	// end parsing job, add planner's FOCs, make substitutions
-	DynareModel::final_job();
-
-	// calculate parameters
-	calc_params();
-	// calculate initial values
-	calc_init();
-
-	if (vcov_end > vcov_beg)
-		vcov_mat = new ParsedMatrix(vcov);
-	else {
-		// vcov has not been asserted, set it to unit matrix
-		vcov_mat = new TwoDMatrix(atoms.nexo(), atoms.nexo());
-		vcov_mat->unit();
-	}
-
-	// check the model
-	check_model();
-
-	// differentiate
-	if (order >= 1)
-		eqs.differentiate(order);
-}
-
-DynareParser::DynareParser(const DynareParser& dp)
-	: DynareModel(dp),
-	  pa_atoms(dp.pa_atoms), paramset(dp.paramset, pa_atoms),
-	  ia_atoms(dp.ia_atoms), initval(dp.initval, ia_atoms), vcov(dp.vcov),
-	  model_beg(dp.model_beg), model_end(dp.model_end),
-	  paramset_beg(dp.paramset_beg), paramset_end(dp.paramset_end),
-	  initval_beg(dp.initval_beg), initval_end(dp.initval_end),
-	  vcov_beg(dp.vcov_beg), vcov_end(dp.vcov_end),
-	  order_beg(dp.order_beg), order_end(dp.order_end),
-	  plobjective_beg(dp.plobjective_beg), plobjective_end(dp.plobjective_end),
-	  pldiscount_beg(dp.pldiscount_beg), pldiscount_end(dp.pldiscount_end)
-{
-}
-
-DynareParser::~DynareParser()
-{
-}
-
-void DynareParser::add_name(const char* name, int flag)
-{
-	DynareModel::add_name(name, flag);
-	// register with static atoms used for atom assignements
-	if (flag == 1) {
-		// endogenous
-		ia_atoms.register_name(name);
-	} else if (flag == 2) {
-		// exogenous
-		ia_atoms.register_name(name);
-	} else if (flag == 3) {
-		// parameter
-		pa_atoms.register_name(name);
-		ia_atoms.register_name(name);
-	} else {
-		throw DynareException(__FILE__, __LINE__,
-							  "Unrecognized flag value.");
-	}
-}
-
-void DynareParser::error(const char* mes)
-{
-	// throwing zero offset since this exception will be caugth at
-	// constructor
-	throw ogp::ParserException(mes, 0);
-}
-
-void DynareParser::print() const
-{
-	DynareModel::print();
-	printf("parameter atoms:\n");
-	paramset.print();
-	printf("initval atoms:\n");
-	initval.print();
-	printf("model position: %d %d\n", model_beg, model_end);
-	printf("paramset position: %d %d\n", paramset_beg, paramset_end);
-	printf("initval position: %d %d\n", initval_beg, initval_end);
-}
-
-/** A global symbol for passing info to the DynareParser from
- * parser. */
-DynareParser* dynare_parser;
-
-/** The declarations of functions defined in dynglob_ll.cc and
- * dynglob_tab.cc generated from dynglob.lex and dynglob.y */
-void* dynglob__scan_buffer(char*, size_t);
-void dynglob__destroy_buffer(void*);
-void dynglob_parse();
-extern ogp::location_type dynglob_lloc;
-
-void DynareParser::parse_glob(int length, const char* stream)
-{
-	char* buffer = new char[length+2];
-	strncpy(buffer, stream, length);
-	buffer[length] = '\0';
-	buffer[length+1] = '\0';
-	void* p = dynglob__scan_buffer(buffer, (unsigned int)length+2);
-	dynare_parser = this;
-	dynglob_parse();
-	delete [] buffer;
-	dynglob__destroy_buffer(p);
-}
-
-
-int DynareParser::parse_order(int len, const char* str)
-{
-	char* buf = new char[len+1];
-	strncpy(buf, str, len);
-	buf[len] = '\0';
-	int res;
-	sscanf(buf, "%d", &res);
-	delete [] buf;
-	return res;
-}
-
-int DynareParser::parse_pldiscount(int len, const char* str)
-{
-	char* buf = new char[len+1];
-	strncpy(buf, str, len);
-	buf[len] = '\0';
-	if (! atoms.is_type(buf, DynareDynamicAtoms::param))
-		throw ogp::ParserException(std::string("Name ") + buf + " is not a parameter", 0);
-
-	int t = atoms.index(buf, 0);
-	if (t == -1)
-		t = eqs.add_nulary(buf);
-
-	delete [] buf;
-	return t;
-}	
-
-void DynareParser::calc_params()
-{
-	if (param_vals)
-		delete param_vals;
-
-	param_vals = new Vector(atoms.np());
-	ogp::AtomAsgnEvaluator aae(paramset);
-	aae.eval();
-	for (int i = 0; i < atoms.np(); i++)
-		(*param_vals)[i] = aae.get_value(atoms.get_params()[i]);
-
-	for (unsigned int i = 0; i < atoms.get_params().size(); i++)
-		if (! std::isfinite((*param_vals)[i]))
-			printf("dynare++: warning: value for parameter %s is not finite\n",
-				   atoms.get_params()[i]);
-}
-
-void DynareParser::calc_init()
-{
-    // update initval atoms assignings according to substitutions
-	if (atom_substs)
-		initval.apply_subst(atom_substs->get_old2new());
-
-	// calculate the vector of initial values
-	if (init_vals)
-		delete init_vals;
-	init_vals = new Vector(atoms.ny());
-	ogp::AtomAsgnEvaluator aae(initval);
-	// set parameters
-	for (int ip = 0; ip < atoms.np(); ip++)
-		aae.set_user_value(atoms.get_params()[ip], (*param_vals)[ip]);
-	// set exogenous to zeros
-	for (int ie = 0; ie < atoms.nexo(); ie++)
-		aae.set_user_value(atoms.get_exovars()[ie], 0.0);
-	// evaluate
-	aae.eval();
-	// set results to internally ordered vector init_vals
-	for (int outer = 0; outer < atoms.ny(); outer++) {
-		int i = atoms.outer2y_endo()[outer];
-		(*init_vals)[i] = aae.get_value(atoms.get_endovars()[outer]);
-	}
-
-	// if the planner's FOCs have been added, then add estimate of
-	// Lagrange multipliers to the vector
-	if (pbuilder) {
-		MultInitSS mis(*pbuilder, *param_vals, *init_vals);
-	}
-
-	// if forward substitution builder has been created, we have to
-	// its substitutions and evaluate them
-	if (fbuilder)
-		ogdyn::DynareSteadySubstitutions dss(atoms, eqs.getTree(),
-											 fbuilder->get_aux_map(), *param_vals, *init_vals);
-
-	for (unsigned int i = 0; i < atoms.get_endovars().size(); i++)
-		if (! std::isfinite((*init_vals)[i]))
-			printf("dynare++: warning: initval for <%s> is not finite\n",
-				   atoms.get_endovars()[atoms.y2outer_endo()[i]]);
-}
-
-// this returns false for linear functions
-bool NLSelector::operator()(int t) const
-{
-	const ogp::Operation& op = model.getParser().getTree().operation(t);
-	const DynareDynamicAtoms& atoms = model.getAtoms();
-	// if the term is constant, return false
-	if (model.is_constant_term(t))
-		return false;
- 	int nary = op.nary();
-	if (nary == 0) {
-		if (atoms.is_type(atoms.name(t), DynareDynamicAtoms::endovar) ||
-			atoms.is_type(atoms.name(t), DynareDynamicAtoms::exovar))
-			return true;
-		else
-			return false;
-	} else if (nary == 1) {
-		if (op.getCode() == ogp::UMINUS)
-			return false;
-		else
-			return true;
-	} else {
-		if (op.getCode() == ogp::TIMES)
-			// if at least one operand is constant, than the TIMES is linear
-			if (model.is_constant_term(op.getOp1()) ||
-				model.is_constant_term(op.getOp2()))
-				return false;
-			else
-				return true;
-			// both PLUS and MINUS are linear
-		if (op.getCode() == ogp::PLUS ||
-			op.getCode() == ogp::MINUS)
-			return false;
-		// POWER is linear if exponent or base is 0 or one
-		if (op.getCode() == ogp::POWER &&
-			(op.getOp1() == ogp::OperationTree::zero ||
-			 op.getOp1() == ogp::OperationTree::one ||
-			 op.getOp2() == ogp::OperationTree::zero ||
-			 op.getOp2() == ogp::OperationTree::one))
-			return false;
-		else
-			return true;
-		// DIVIDE is linear if the denominator is constant, or if
-		// the nominator is zero
-		if (op.getCode() == ogp::DIVIDE &&
-			(op.getOp1() == ogp::OperationTree::zero ||
-			 model.is_constant_term(op.getOp2())))
-			return false;
-		else
-			return true;
-	}
-
-	throw DynareException(__FILE__, __LINE__,
-						  "Wrong operation in operation tree");
-	return false;
-}
-
-DynareSPModel::DynareSPModel(const char** endo, int num_endo,
-							 const char** exo, int num_exo,
-							 const char** par, int num_par,
-							 const char* equations, int len,
-							 int ord)
-	: DynareModel()
-{
-	// set the order
-	order = ord;
-
-	// add names
-	for (int i = 0; i < num_endo; i++)
-		add_name(endo[i], 1);
-	for (int i = 0; i < num_exo; i++)
-		add_name(exo[i], 2);
-	for (int i = 0; i < num_par; i++)
-		add_name(par[i], 3);
-
-	// parse the equations
-	eqs.parse(len, equations);
-
-	// parsing finished
-	atoms.parsing_finished(ogp::VarOrdering::bfspbfpb);
-
-	// create what has to be created from DynareModel
-	param_vals = new Vector(atoms.np());
-	init_vals = new Vector(atoms.ny());
-	vcov_mat = new TwoDMatrix(atoms.nexo(), atoms.nexo());
-
-	// check the model
-	check_model();
-
-	// differentiate
-	if (order >= 1)
-		eqs.differentiate(order);
-}
-
-void ModelSSWriter::write_der0(FILE* fd)
-{
-	write_der0_preamble(fd);
-	write_atom_assignment(fd);
-
-	stop_set.clear();
-	for (int fi = 0; fi < model.eqs.nformulas(); fi++)
-		otree.print_operation_tree(model.eqs.formula(fi), fd, *this);
-
-	write_der0_assignment(fd);
-}
-
-void ModelSSWriter::write_der1(FILE* fd)
-{
-	write_der1_preamble(fd);
-	write_atom_assignment(fd);
-
-	stop_set.clear();
-
-	const vector<int>& variables = model.getAtoms().variables();
-	const vector<int>& eam = model.getAtoms().get_endo_atoms_map();
-	for (int i = 0; i < model.getParser().nformulas(); i++) {
-		const ogp::FormulaDerivatives& fder = model.getParser().derivatives(i);
-		for (unsigned int j = 0; j < eam.size(); j++) {
-			int t = fder.derivative(ogp::FoldMultiIndex(variables.size(), 1, eam[j]));
-			if (t > 0)
-				otree.print_operation_tree(t, fd, *this);
-		}
-	}
-
-	write_der1_assignment(fd);
-}
-
-MatlabSSWriter::MatlabSSWriter(const DynareModel& dm, const char* idd)
-	: ModelSSWriter(dm), id(new char[strlen(idd)+1])
-{
-	strcpy(id, idd);
-}
-
-
-void MatlabSSWriter::write_der0_preamble(FILE* fd) const
-{
-	fprintf(fd,
-			"%% Usage:\n"
-			"%%       out = %s_f(params, y)\n"
-			"%%   where\n"
-			"%%       out    is a (%d,1) column vector of the residuals\n"
-            "%%              of the static system\n",
-			id, model.getAtoms().ny());
-	write_common1_preamble(fd);
-	fprintf(fd,
-			"function out = %s_f(params, y)\n", id);
-	write_common2_preamble(fd);
-}
-
-void MatlabSSWriter::write_der1_preamble(FILE* fd) const
-{
-	fprintf(fd,
-			"%% Usage:\n"
-			"%%       out = %s_ff(params, y)\n"
-			"%%   where\n"
-			"%%       out    is a (%d,%d) matrix of the first order\n"
-			"%%              derivatives of the static system residuals\n"
-			"%%              columns correspond to endo variables in\n"
-            "%%              the ordering as declared\n",
-			id, model.getAtoms().ny(), model.getAtoms().ny());
-	write_common1_preamble(fd);
-	fprintf(fd,
-			"function out = %s_ff(params, y)\n", id);
-	write_common2_preamble(fd);
-}
-
-void MatlabSSWriter::write_common1_preamble(FILE* fd) const
-{
-	fprintf(fd,
-			"%%       params is a (%d,1) vector of parameter values\n"
-			"%%              in the ordering as declared\n"
-			"%%       y      is a (%d,1) vector of endogenous variables\n"
-			"%%              in the ordering as declared\n"
-			"%%\n"
-			"%% Created by Dynare++ v. %s\n", model.getAtoms().np(),
-			model.getAtoms().ny(), DYNVERSION);
-	// write ordering of parameters
-	fprintf(fd, "\n%% params ordering\n%% =====================\n");
-	for (unsigned int ip = 0; ip < model.getAtoms().get_params().size(); ip++) {
-		const char* parname = model.getAtoms().get_params()[ip];
-		fprintf(fd, "%% %s\n", parname);
-	}
-	// write endogenous variables
-	fprintf(fd, "%%\n%% y ordering\n%% =====================\n");
-	for (unsigned int ie = 0; ie < model.getAtoms().get_endovars().size(); ie++) {
-		const char* endoname = model.getAtoms().get_endovars()[ie];
-		fprintf(fd, "%% %s\n", endoname);
-	}
-	fprintf(fd,"\n");
-}
-
-void MatlabSSWriter::write_common2_preamble(FILE* fd) const
-{
-	fprintf(fd, "if size(y) ~= [%d,1]\n\terror('Wrong size of y, must be [%d,1]');\nend\n",
-			model.getAtoms().ny(), model.getAtoms().ny());
-	fprintf(fd, "if size(params) ~= [%d,1]\n\terror('Wrong size of params, must be [%d,1]');\nend\n\n",
-			model.getAtoms().np(), model.getAtoms().np());
-}
-
-void MatlabSSWriter::write_atom_assignment(FILE* fd) const
-{
-	// write OperationTree::num_constants
-	fprintf(fd, "%% hardwired constants\n");
-	ogp::EvalTree etree(model.getParser().getTree(), ogp::OperationTree::num_constants-1);
-	for (int i = 0; i < ogp::OperationTree::num_constants; i++) {
-		format_nulary(i, fd);
-		double g = etree.eval(i);
-		if (std::isnan(g))
-			fprintf(fd, " = NaN;\n");
-		else
-			fprintf(fd, " = %12.8g;\n", etree.eval(i));		
-	}
-	// write numerical constants
-	fprintf(fd, "%% numerical constants\n");
-	const ogp::Constants::Tconstantmap& cmap = model.getAtoms().get_constantmap();
-	for (ogp::Constants::Tconstantmap::const_iterator it = cmap.begin();
-		 it != cmap.end(); ++it) {
-		format_nulary((*it).first, fd);
-		fprintf(fd, " = %12.8g;\n", (*it).second);
-	}
-	// write parameters
-	fprintf(fd, "%% parameter values\n");
-	for (unsigned int ip = 0; ip < model.getAtoms().get_params().size(); ip++) {
-		const char* parname = model.getAtoms().get_params()[ip];
-		int t = model.getAtoms().index(parname, 0);
-		if (t == -1) {
-			fprintf(fd, "%% %s not used in the model\n", parname);
-		} else {
-			format_nulary(t, fd);
-			fprintf(fd, " = params(%d); %% %s\n", ip+1, parname);
-		}
-	}
-	// write exogenous variables
-	fprintf(fd, "%% exogenous variables to zeros\n");
-	for (unsigned int ie = 0; ie < model.getAtoms().get_exovars().size(); ie++) {
-		const char* exoname = model.getAtoms().get_exovars()[ie];
-		try {
-			const ogp::DynamicAtoms::Tlagmap& lmap = model.getAtoms().lagmap(exoname);
-			for (ogp::DynamicAtoms::Tlagmap::const_iterator it = lmap.begin();
-				 it != lmap.end(); ++it) {
-				format_nulary((*it).second, fd);
-				fprintf(fd, " = 0.0; %% %s\n", exoname);
-			}
-		} catch (const ogu::Exception& e) {
-			// ignore the error of not found variable in the tree
-		}
-	}
-	// write endogenous variables
-	fprintf(fd, "%% endogenous variables to y\n");
-	for (unsigned int ie = 0; ie < model.getAtoms().get_endovars().size(); ie++) {
-		const char* endoname = model.getAtoms().get_endovars()[ie];
-		const ogp::DynamicAtoms::Tlagmap& lmap = model.getAtoms().lagmap(endoname);
-		for (ogp::DynamicAtoms::Tlagmap::const_iterator it = lmap.begin();
-			 it != lmap.end(); ++it) {
-			format_nulary((*it).second, fd);
-			fprintf(fd, " = y(%d); %% %s\n", ie+1, endoname);
-		}
-	}
-	fprintf(fd,"\n");
-}
-
-void MatlabSSWriter::write_der0_assignment(FILE* fd) const
-{
-
-	// initialize out variable
-	fprintf(fd, "%% setting the output variable\n");
-	fprintf(fd, "out = zeros(%d, 1);\n", model.getParser().nformulas());
-
-	// fill out with the terms
-	for (int i = 0; i < model.getParser().nformulas(); i++) {
-		fprintf(fd, "out(%d) = ", i+1);
-		format_term(model.getParser().formula(i), fd);
-		fprintf(fd, ";\n");
-	}
-}
-
-void MatlabSSWriter::write_der1_assignment(FILE* fd) const
-{
-	// initialize out variable
-	fprintf(fd, "%% setting the output variable\n");
-	fprintf(fd, "out = zeros(%d, %d);\n", model.getParser().nformulas(), model.getAtoms().ny());
-
-	// fill out with the terms
-	const vector<int>& variables = model.getAtoms().variables();
-	const vector<int>& eam = model.getAtoms().get_endo_atoms_map();
-	for (int i = 0; i < model.getParser().nformulas(); i++) {
-		const ogp::FormulaDerivatives& fder = model.getParser().derivatives(i);
-		for (unsigned int j = 0; j < eam.size(); j++) {
-			int tvar = variables[eam[j]];
-			const char* name = model.getAtoms().name(tvar);
-			int yi = model.getAtoms().name2outer_endo(name);
-			int t = fder.derivative(ogp::FoldMultiIndex(variables.size(), 1, eam[j]));
-			if (t != ogp::OperationTree::zero) {
-				fprintf(fd, "out(%d,%d) = out(%d,%d) + ", i+1, yi+1, i+1, yi+1);
-				format_term(t, fd);
-				fprintf(fd, "; %% %s(%d)\n", name, model.getAtoms().lead(tvar));
-			}
-		}
-	}
-}
-
-void MatlabSSWriter::format_term(int t, FILE* fd) const
-{
-	fprintf(fd, "t%d", t);
-}
-
-void MatlabSSWriter::format_nulary(int t, FILE* fd) const
-{
-	fprintf(fd, "a%d", t);
-}
-
-void DebugOperationFormatter::format_nulary(int t, FILE* fd) const
-{
-	const DynareDynamicAtoms& a = model.getAtoms();
-
-	if (t == ogp::OperationTree::zero)
-		fprintf(fd, "0");
-	else if (t == ogp::OperationTree::one)
-		fprintf(fd, "1");
-	else if (t == ogp::OperationTree::nan)
-		fprintf(fd, "NaN");
-	else if (t == ogp::OperationTree::two_over_pi)
-		fprintf(fd, "2/sqrt(PI)");
-	else if (a.is_constant(t))
-		fprintf(fd, "%g", a.get_constant_value(t));
-	else {
-		int ll = a.lead(t);
-		const char* name = a.name(t);
-		if (ll == 0)
-			fprintf(fd, "%s", name);
-		else
-			fprintf(fd, "%s(%d)", name, ll);
-	}
-}
diff --git a/dynare++/src/dynare_model.h b/dynare++/src/dynare_model.hh
similarity index 99%
rename from dynare++/src/dynare_model.h
rename to dynare++/src/dynare_model.hh
index 543a5e3937f7f4de59bc93fddee8c0c06b296418..5321bd6230c39748735e265e8c598a8a73e9e988 100644
--- a/dynare++/src/dynare_model.h
+++ b/dynare++/src/dynare_model.hh
@@ -3,14 +3,14 @@
 #ifndef OGDYN_DYNARE_MODEL
 #define OGDYN_DYNARE_MODEL
 
-#include "parser/cc/matrix_parser.h"
-#include "parser/cc/atom_assignings.h"
+#include "parser/cc/matrix_parser.hh"
+#include "parser/cc/atom_assignings.hh"
 
-#include "dynare_atoms.h"
+#include "dynare_atoms.hh"
 #include "twod_matrix.hh"
 
-#include "Vector.h"
-#include "GeneralMatrix.h"
+#include "Vector.hh"
+#include "GeneralMatrix.hh"
 
 #include <map>
 #include <boost/unordered_set.hpp>
diff --git a/dynare++/src/dynare_params.cc b/dynare++/src/dynare_params.cc
new file mode 100644
index 0000000000000000000000000000000000000000..c94f38ca12163bebb6c4e7de02f7bbaac2240b5b
--- /dev/null
+++ b/dynare++/src/dynare_params.cc
@@ -0,0 +1,278 @@
+// Copyright (C) 2004-2011, Ondra Kamenik
+
+#include "dynare_params.hh"
+
+#include <getopt.h>
+#include <cstdio>
+#include <cstring>
+
+const char *help_str
+= "usage: dynare++ [--help] [--version] [options] <model file>\n"
+  "\n"
+  "    --help               print this message and return\n"
+  "    --version            print version and return\n"
+  "\n"
+  "options:\n"
+  "    --per <num>          number of periods simulated after burnt [100]\n"
+  "    --burn <num>         number of periods burnt [0]\n"
+  "    --sim <num>          number of simulations [80]\n"
+  "    --rtper <num>        number of RT periods simulated after burnt [0]\n"
+  "    --rtsim <num>        number of RT simulations [0]\n"
+  "    --condper <num>      number of periods in cond. simulations [0]\n"
+  "    --condsim <num>      number of conditional simulations [0]\n"
+  "    --steps <num>        steps towards stoch. SS [0=deter.]\n"
+  "    --centralize         centralize the rule [do centralize]\n"
+  "    --no-centralize      do not centralize the rule [do centralize]\n"
+  "    --prefix <string>    prefix of variables in Mat-4 file [\"dyn\"]\n"
+  "    --seed <num>         random number generator seed [934098]\n"
+  "    --order <num>        order of approximation [no default]\n"
+  "    --threads <num>      number of max parallel threads [2]\n"
+  "    --ss-tol <num>       steady state calcs tolerance [1.e-13]\n"
+  "    --check pesPES       check model residuals [no checks]\n"
+  "                         lower/upper case switches off/on\n"
+  "                           pP  checking along simulation path\n"
+  "                           eE  checking on ellipse\n"
+  "                           sS  checking along shocks\n"
+  "    --check-evals <num>  max number of evals per residual [1000]\n"
+  "    --check-num <num>    number of checked points [10]\n"
+  "    --check-scale <num>  scaling of checked points [2.0]\n"
+  "    --no-irfs            shuts down IRF simulations [do IRFs]\n"
+  "    --irfs               performs IRF simulations [do IRFs]\n"
+  "    --qz-criterium <num> threshold for stable eigenvalues [1.000001]\n"
+  "\n\n";
+
+// returns the pointer to the first character after the last slash or
+// backslash in the string
+const char *dyn_basename(const char *str);
+
+DynareParams::DynareParams(int argc, char **argv)
+  : modname(NULL), num_per(100), num_burn(0), num_sim(80),
+    num_rtper(0), num_rtsim(0),
+    num_condper(0), num_condsim(0),
+    num_threads(2), num_steps(0),
+    prefix("dyn"), seed(934098), order(-1), ss_tol(1.e-13),
+    check_along_path(false), check_along_shocks(false),
+    check_on_ellipse(false), check_evals(1000), check_num(10), check_scale(2.0),
+    do_irfs_all(true), do_centralize(true), qz_criterium(1.0+1e-6),
+    help(false), version(false)
+{
+  if (argc == 1 || !strcmp(argv[1], "--help"))
+    {
+      help = true;
+      return;
+    }
+  if (argc == 1 || !strcmp(argv[1], "--version"))
+    {
+      version = true;
+      return;
+    }
+
+  modname = argv[argc-1];
+  argc--;
+
+  struct option const opts [] = {
+    {"periods", required_argument, NULL, opt_per},
+    {"per", required_argument, NULL, opt_per},
+    {"burn", required_argument, NULL, opt_burn},
+    {"simulations", required_argument, NULL, opt_sim},
+    {"sim", required_argument, NULL, opt_sim},
+    {"rtperiods", required_argument, NULL, opt_rtper},
+    {"rtper", required_argument, NULL, opt_rtper},
+    {"rtsimulations", required_argument, NULL, opt_rtsim},
+    {"rtsim", required_argument, NULL, opt_rtsim},
+    {"condperiods", required_argument, NULL, opt_condper},
+    {"condper", required_argument, NULL, opt_condper},
+    {"condsimulations", required_argument, NULL, opt_condsim},
+    {"condsim", required_argument, NULL, opt_condsim},
+    {"prefix", required_argument, NULL, opt_prefix},
+    {"threads", required_argument, NULL, opt_threads},
+    {"steps", required_argument, NULL, opt_steps},
+    {"seed", required_argument, NULL, opt_seed},
+    {"order", required_argument, NULL, opt_order},
+    {"ss-tol", required_argument, NULL, opt_ss_tol},
+    {"check", required_argument, NULL, opt_check},
+    {"check-scale", required_argument, NULL, opt_check_scale},
+    {"check-evals", required_argument, NULL, opt_check_evals},
+    {"check-num", required_argument, NULL, opt_check_num},
+    {"qz-criterium", required_argument, NULL, opt_qz_criterium},
+    {"no-irfs", no_argument, NULL, opt_noirfs},
+    {"irfs", no_argument, NULL, opt_irfs},
+    {"centralize", no_argument, NULL, opt_centralize},
+    {"no-centralize", no_argument, NULL, opt_no_centralize},
+    {"help", no_argument, NULL, opt_help},
+    {"version", no_argument, NULL, opt_version},
+    {NULL, 0, NULL, 0}
+  };
+
+  int ret;
+  int index;
+  while (-1 != (ret = getopt_long(argc, argv, "", opts, &index)))
+    {
+      switch (ret)
+        {
+        case opt_per:
+          if (1 != sscanf(optarg, "%d", &num_per))
+            fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg);
+          break;
+        case opt_burn:
+          if (1 != sscanf(optarg, "%d", &num_burn))
+            fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg);
+          break;
+        case opt_sim:
+          if (1 != sscanf(optarg, "%d", &num_sim))
+            fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg);
+          break;
+        case opt_rtper:
+          if (1 != sscanf(optarg, "%d", &num_rtper))
+            fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg);
+          break;
+        case opt_rtsim:
+          if (1 != sscanf(optarg, "%d", &num_rtsim))
+            fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg);
+          break;
+        case opt_condper:
+          if (1 != sscanf(optarg, "%d", &num_condper))
+            fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg);
+          break;
+        case opt_condsim:
+          if (1 != sscanf(optarg, "%d", &num_condsim))
+            fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg);
+          break;
+        case opt_prefix:
+          prefix = optarg;
+          break;
+        case opt_threads:
+          if (1 != sscanf(optarg, "%d", &num_threads))
+            fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg);
+          break;
+        case opt_steps:
+          if (1 != sscanf(optarg, "%d", &num_steps))
+            fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg);
+          break;
+        case opt_seed:
+          if (1 != sscanf(optarg, "%d", &seed))
+            fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg);
+          break;
+        case opt_order:
+          if (1 != sscanf(optarg, "%d", &order))
+            fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg);
+          break;
+        case opt_ss_tol:
+          if (1 != sscanf(optarg, "%lf", &ss_tol))
+            fprintf(stderr, "Couldn't parse float %s, ignored\n", optarg);
+          break;
+        case opt_check:
+          processCheckFlags(optarg);
+          break;
+        case opt_check_scale:
+          if (1 != sscanf(optarg, "%lf", &check_scale))
+            fprintf(stderr, "Couldn't parse float %s, ignored\n", optarg);
+          break;
+        case opt_check_evals:
+          if (1 != sscanf(optarg, "%d", &check_evals))
+            fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg);
+          break;
+        case opt_check_num:
+          if (1 != sscanf(optarg, "%d", &check_num))
+            fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg);
+          break;
+        case opt_noirfs:
+          irf_list.clear();
+          do_irfs_all = false;
+          break;
+        case opt_irfs:
+          processIRFList(argc, argv);
+          if (irf_list.empty())
+            do_irfs_all = true;
+          else
+            do_irfs_all = false;
+          break;
+        case opt_centralize:
+          do_centralize = true;
+          break;
+        case opt_no_centralize:
+          do_centralize = false;
+          break;
+        case opt_qz_criterium:
+          if (1 != sscanf(optarg, "%lf", &qz_criterium))
+            fprintf(stderr, "Couldn't parse float %s, ignored\n", optarg);
+          break;
+        case opt_help:
+          help = true;
+          break;
+        case opt_version:
+          version = true;
+          break;
+        case '?':
+          fprintf(stderr, "Unknown option, ignored\n");
+          break;
+        }
+    }
+
+  // make basename (get rid of the extension)
+  basename = dyn_basename(modname);
+  std::string::size_type i = basename.rfind('.');
+  if (i != std::string::npos)
+    basename.erase(i);
+}
+
+void
+DynareParams::printHelp() const
+{
+  printf("%s", help_str);
+}
+
+void
+DynareParams::processCheckFlags(const char *flags)
+{
+  for (unsigned int i = 0; i < strlen(flags); i++)
+    {
+      switch (flags[i])
+        {
+        case 'p':
+          check_along_path = false;
+          break;
+        case 'P':
+          check_along_path = true;
+          break;
+        case 'e':
+          check_on_ellipse = false;
+          break;
+        case 'E':
+          check_on_ellipse = true;
+          break;
+        case 's':
+          check_along_shocks = false;
+          break;
+        case 'S':
+          check_along_shocks = true;
+          break;
+        default:
+          fprintf(stderr, "Unknown check type selection character <%c>, ignored.\n", flags[i]);
+        }
+    }
+}
+
+void
+DynareParams::processIRFList(int argc, char **argv)
+{
+  irf_list.clear();
+  while (optind < argc && *(argv[optind]) != '-')
+    {
+      irf_list.push_back(argv[optind]);
+      optind++;
+    }
+}
+
+const char *
+dyn_basename(const char *str)
+{
+  int i = strlen(str);
+  while (i > 0 && str[i-1] != '/' && str[i-1] != '\\')
+    i--;
+  return str+i;
+}
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/dynare++/src/dynare_params.cpp b/dynare++/src/dynare_params.cpp
deleted file mode 100644
index 95a76a674c8c3b4c7e27b0f8dbfe38552fdc0c23..0000000000000000000000000000000000000000
--- a/dynare++/src/dynare_params.cpp
+++ /dev/null
@@ -1,267 +0,0 @@
-// Copyright (C) 2004-2011, Ondra Kamenik
-
-#include "dynare_params.h"
-
-#include <getopt.h>
-#include <cstdio>
-#include <cstring>
-
-const char* help_str = 
-"usage: dynare++ [--help] [--version] [options] <model file>\n"
-"\n"
-"    --help               print this message and return\n"
-"    --version            print version and return\n"
-"\n"
-"options:\n"
-"    --per <num>          number of periods simulated after burnt [100]\n"
-"    --burn <num>         number of periods burnt [0]\n"
-"    --sim <num>          number of simulations [80]\n"
-"    --rtper <num>        number of RT periods simulated after burnt [0]\n"
-"    --rtsim <num>        number of RT simulations [0]\n"
-"    --condper <num>      number of periods in cond. simulations [0]\n"
-"    --condsim <num>      number of conditional simulations [0]\n"
-"    --steps <num>        steps towards stoch. SS [0=deter.]\n"
-"    --centralize         centralize the rule [do centralize]\n"
-"    --no-centralize      do not centralize the rule [do centralize]\n"
-"    --prefix <string>    prefix of variables in Mat-4 file [\"dyn\"]\n"
-"    --seed <num>         random number generator seed [934098]\n"
-"    --order <num>        order of approximation [no default]\n"
-"    --threads <num>      number of max parallel threads [2]\n"
-"    --ss-tol <num>       steady state calcs tolerance [1.e-13]\n"
-"    --check pesPES       check model residuals [no checks]\n"
-"                         lower/upper case switches off/on\n"
-"                           pP  checking along simulation path\n"
-"                           eE  checking on ellipse\n"
-"                           sS  checking along shocks\n"
-"    --check-evals <num>  max number of evals per residual [1000]\n"
-"    --check-num <num>    number of checked points [10]\n"
-"    --check-scale <num>  scaling of checked points [2.0]\n"
-"    --no-irfs            shuts down IRF simulations [do IRFs]\n"
-"    --irfs               performs IRF simulations [do IRFs]\n"
-"    --qz-criterium <num> threshold for stable eigenvalues [1.000001]\n"
-"\n\n";
-
-// returns the pointer to the first character after the last slash or
-// backslash in the string
-const char* dyn_basename(const char* str);
-
-DynareParams::DynareParams(int argc, char** argv)
-	: modname(NULL), num_per(100), num_burn(0), num_sim(80), 
-	  num_rtper(0), num_rtsim(0),
-	  num_condper(0), num_condsim(0),
-	  num_threads(2), num_steps(0),
-	  prefix("dyn"), seed(934098), order(-1), ss_tol(1.e-13),
-	  check_along_path(false), check_along_shocks(false),
-	  check_on_ellipse(false), check_evals(1000), check_num(10), check_scale(2.0),
-	  do_irfs_all(true), do_centralize(true), qz_criterium(1.0+1e-6),
-	  help(false), version(false)
-{
-	if (argc == 1 || !strcmp(argv[1],"--help")) {
-		help = true;
-		return;
-	}
-	if (argc == 1 || !strcmp(argv[1],"--version")) {
-		version = true;
-		return;
-	}
-
-	modname = argv[argc-1];
-	argc--;
-
-	struct option const opts [] = {
-		{"periods", required_argument, NULL, opt_per},
-		{"per", required_argument, NULL, opt_per},
-		{"burn", required_argument, NULL, opt_burn},
-		{"simulations", required_argument, NULL, opt_sim},
-		{"sim", required_argument, NULL, opt_sim},
-		{"rtperiods", required_argument, NULL, opt_rtper},
-		{"rtper", required_argument, NULL, opt_rtper},
-		{"rtsimulations", required_argument, NULL, opt_rtsim},
-		{"rtsim", required_argument, NULL, opt_rtsim},
-		{"condperiods", required_argument, NULL, opt_condper},
-		{"condper", required_argument, NULL, opt_condper},
-		{"condsimulations", required_argument, NULL, opt_condsim},
-		{"condsim", required_argument, NULL, opt_condsim},
-		{"prefix", required_argument, NULL, opt_prefix},
-		{"threads", required_argument, NULL, opt_threads},
-		{"steps", required_argument, NULL, opt_steps},
-		{"seed", required_argument, NULL, opt_seed},
-		{"order", required_argument, NULL, opt_order},
-		{"ss-tol", required_argument, NULL, opt_ss_tol},
-		{"check", required_argument, NULL, opt_check},
-		{"check-scale", required_argument, NULL, opt_check_scale},
-		{"check-evals", required_argument, NULL, opt_check_evals},
-		{"check-num", required_argument, NULL, opt_check_num},
-		{"qz-criterium",required_argument, NULL, opt_qz_criterium},
-		{"no-irfs", no_argument, NULL, opt_noirfs},
-		{"irfs", no_argument, NULL, opt_irfs},
-		{"centralize", no_argument, NULL, opt_centralize},
-		{"no-centralize", no_argument, NULL, opt_no_centralize},
-		{"help", no_argument, NULL, opt_help},
-		{"version", no_argument, NULL, opt_version},
-		{NULL, 0, NULL, 0}
-	};
-
-	int ret;
-	int index;
-	while (-1 != (ret = getopt_long(argc, argv, "", opts, &index))) {
-		switch (ret) {
-		case opt_per:
-			if (1 != sscanf(optarg, "%d", &num_per))
-				fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg);
-			break;
-		case opt_burn:
-			if (1 != sscanf(optarg, "%d", &num_burn))
-				fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg);
-			break;
-		case opt_sim:
-			if (1 != sscanf(optarg, "%d", &num_sim))
-				fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg);
-			break;
-		case opt_rtper:
-			if (1 != sscanf(optarg, "%d", &num_rtper))
-				fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg);
-			break;
-		case opt_rtsim:
-			if (1 != sscanf(optarg, "%d", &num_rtsim))
-				fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg);
-			break;
-		case opt_condper:
-			if (1 != sscanf(optarg, "%d", &num_condper))
-				fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg);
-			break;
-		case opt_condsim:
-			if (1 != sscanf(optarg, "%d", &num_condsim))
-				fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg);
-			break;
-		case opt_prefix:
-			prefix = optarg;
-			break;
-		case opt_threads:
-			if (1 != sscanf(optarg, "%d", &num_threads))
-				fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg);
-			break;
-		case opt_steps:
-			if (1 != sscanf(optarg, "%d", &num_steps))
-				fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg);
-			break;
-		case opt_seed:
-			if (1 != sscanf(optarg, "%d", &seed))
-				fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg);
-			break;
-		case opt_order:
-			if (1 != sscanf(optarg, "%d", &order))
-				fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg);
-			break;
-		case opt_ss_tol:
-			if (1 != sscanf(optarg, "%lf", &ss_tol))
-				fprintf(stderr, "Couldn't parse float %s, ignored\n", optarg);
-			break;
-		case opt_check:
-			processCheckFlags(optarg);
-			break;
-		case opt_check_scale:
-			if (1 != sscanf(optarg, "%lf", &check_scale))
-				fprintf(stderr, "Couldn't parse float %s, ignored\n", optarg);
-			break;
-		case opt_check_evals:
-			if (1 != sscanf(optarg, "%d", &check_evals))
-				fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg);
-			break;
-		case opt_check_num:
-			if (1 != sscanf(optarg, "%d", &check_num))
-				fprintf(stderr, "Couldn't parse integer %s, ignored\n", optarg);
-			break;
-		case opt_noirfs:
-			irf_list.clear();
-			do_irfs_all = false;
-			break;
-		case opt_irfs:
-			processIRFList(argc, argv);
-			if (irf_list.empty())
-				do_irfs_all = true;
-			else
-				do_irfs_all = false;
-			break;
-		case opt_centralize:
-			do_centralize = true;
-			break;
-		case opt_no_centralize:
-			do_centralize = false;
-			break;
-		case opt_qz_criterium:
-			if (1 != sscanf(optarg, "%lf", &qz_criterium))
-				fprintf(stderr, "Couldn't parse float %s, ignored\n", optarg);
-			break;
-		case opt_help:
-			help = true;
-			break;
-		case opt_version:
-			version = true;
-			break;
-		case '?':
-			fprintf(stderr, "Unknown option, ignored\n");
-			break;
-		}
-	}
-
-	// make basename (get rid of the extension)
-	basename = dyn_basename(modname);
-	std::string::size_type i = basename.rfind('.');
-	if (i != std::string::npos)
-		basename.erase(i);
-}
-
-void DynareParams::printHelp() const
-{
-	printf("%s", help_str);
-}
-
-void DynareParams::processCheckFlags(const char* flags)
-{
-	for (unsigned int i = 0; i < strlen(flags); i++) {
-		switch (flags[i]) {
-		case 'p':
-			check_along_path = false;
-			break;
-		case 'P':
-			check_along_path = true;
-			break;
-		case 'e':
-			check_on_ellipse = false;
-			break;
-		case 'E':
-			check_on_ellipse = true;
-			break;
-		case 's':
-			check_along_shocks = false;
-			break;
-		case 'S':
-			check_along_shocks = true;
-			break;
-		default:
-			fprintf(stderr, "Unknown check type selection character <%c>, ignored.\n", flags[i]);
-		}
-	}
-}
-
-void DynareParams::processIRFList(int argc, char** argv)
-{
-	irf_list.clear();
-	while (optind < argc && *(argv[optind]) != '-') {
-		irf_list.push_back(argv[optind]);
-		optind++;
-	}
-}
-
-const char* dyn_basename(const char* str)
-{
-	int i = strlen(str);
-	while (i > 0 && str[i-1] != '/' && str[i-1] != '\\')
-		i--;
-	return str+i;
-}
-
-// Local Variables:
-// mode:C++
-// End:
diff --git a/dynare++/src/dynare_params.h b/dynare++/src/dynare_params.hh
similarity index 100%
rename from dynare++/src/dynare_params.h
rename to dynare++/src/dynare_params.hh
diff --git a/dynare++/src/dynglob.lex b/dynare++/src/dynglob.ll
similarity index 97%
rename from dynare++/src/dynglob.lex
rename to dynare++/src/dynglob.ll
index aaf4e4a5f264341799b316a43e18bce88cdf671b..6450bd63a95706d8d6236fabdbd3471d75ab69f5 100644
--- a/dynare++/src/dynglob.lex
+++ b/dynare++/src/dynglob.ll
@@ -1,5 +1,5 @@
 %{
-#include "parser/cc/location.h"
+#include "parser/cc/location.hh"
 #include "dynglob_tab.hh"
 
 	extern YYLTYPE dynglob_lloc;
diff --git a/dynare++/src/dynglob.y b/dynare++/src/dynglob.yy
similarity index 98%
rename from dynare++/src/dynglob.y
rename to dynare++/src/dynglob.yy
index 536a474a2ce4239fceccac2f1b1145742a6a9647..a15287abbdc0965eec005899789bcaa4384d0457 100644
--- a/dynare++/src/dynglob.y
+++ b/dynare++/src/dynglob.yy
@@ -1,8 +1,8 @@
 %{
 // Copyright (C) 2006-2011, Ondra Kamenik
 
-#include "parser/cc/location.h"
-#include "dynare_model.h"
+#include "parser/cc/location.hh"
+#include "dynare_model.hh"
 #include "dynglob_tab.hh"
 
 #include <stdio.h>
diff --git a/dynare++/src/forw_subst_builder.cc b/dynare++/src/forw_subst_builder.cc
new file mode 100644
index 0000000000000000000000000000000000000000..10a97fb997cbd9c98cad434202fcf22bc175bc4e
--- /dev/null
+++ b/dynare++/src/forw_subst_builder.cc
@@ -0,0 +1,133 @@
+// Copyright (C) 2006-2011, Ondra Kamenik
+
+#include "forw_subst_builder.hh"
+
+using namespace ogdyn;
+
+ForwSubstBuilder::ForwSubstBuilder(DynareModel &m)
+  : model(m)
+{
+  info.num_new_terms -= model.getParser().getTree().get_num_op();
+
+  // go through all equations
+  int neq = model.eqs.nformulas();
+  for (int i = 0; i < neq; i++)
+    {
+      int ft = model.eqs.formula(i);
+      int mlead, mlag;
+      model.termspan(ft, mlead, mlag);
+      // if equation is too forward looking
+      if (mlead > 1)
+        {
+          info.num_affected_equations++;
+          // break it to non-linear terms
+          unordered_set<int> nlt = model.get_nonlinear_subterms(ft);
+          int j = 0; // indexes subterms
+          // and make substitutions for all these non-linear subterms
+          for (unordered_set<int>::const_iterator it = nlt.begin();
+               it != nlt.end(); ++it, ++j)
+            substitute_for_term(*it, i, j);
+        }
+    }
+  // unassign all variables with lead greater than 1
+  unassign_gt_1_leads();
+
+  // forget the derivatives in the tree because some variables could
+  // have been unassigned
+  model.eqs.getTree().forget_derivative_maps();
+
+  info.num_new_terms += model.getParser().getTree().get_num_op();
+}
+
+void
+ForwSubstBuilder::substitute_for_term(int t, int i, int j)
+{
+  int mlead, mlag;
+  model.termspan(t, mlead, mlag);
+  if (mlead > 1)
+    {
+      info.num_subst_terms++;
+      // Example for comments: let t = f(x(+4))
+      // first make lagsubst be substitution setting f(x(+4)) to f(x(+1))
+      // this is lag = -3 (1-mlead)
+      map<int, int> lagsubst;
+      unordered_set<int> nult = model.eqs.nulary_of_term(t);// make copy of nult!
+      model.variable_shift_map(nult, 1-mlead, lagsubst);
+      int lagt = model.eqs.add_substitution(t, lagsubst);
+
+      // now maxlead of lagt is +1
+      // add AUXLD_*_*_1 = f(x(+1)) to the model
+      char name[100];
+      sprintf(name, "AUXLD_%d_%d_%d", i, j, 1);
+      model.atoms.register_uniq_endo(name);
+      info.num_aux_variables++;
+      const char *ss = model.atoms.get_name_storage().query(name);
+      int auxt = model.eqs.add_nulary(name);
+      model.eqs.add_formula(model.eqs.add_binary(ogp::MINUS, auxt, lagt));
+      aux_map.insert(Tsubstmap::value_type(ss, lagt));
+      // now add variables and equations
+      // AUXLD_*_*_2 = AUXLD_*_*_1(+1) through
+      // AUXLD_*_*_{mlead-1} = AUXLD_*_*_{mlead-2}(+1)
+      for (int ll = 1; ll <= mlead-2; ll++)
+        {
+          // create AUXLD_*_*_{ll}(+1)
+          sprintf(name, "AUXLD_%d_%d_%d(+1)", i, j, ll);
+          int lastauxt_lead = model.eqs.add_nulary(name);
+          // create AUXLD_*_*{ll+1}
+          sprintf(name, "AUXLD_%d_%d_%d", i, j, ll+1);
+          model.atoms.register_uniq_endo(name);
+          info.num_aux_variables++;
+          ss = model.atoms.get_name_storage().query(name);
+          auxt = model.eqs.add_nulary(name);
+          // add AUXLD_*_*_{ll+1} = AUXLD_*_*_{ll}(+1)
+          model.eqs.add_formula(model.eqs.add_binary(ogp::MINUS, auxt, lastauxt_lead));
+          // add substitution to the map; todo: this
+          // works well because in the context where
+          // aux_map is used the timing doesn't matter,
+          // however, it is misleading, needs to be
+          // changed
+          aux_map.insert(Tsubstmap::value_type(ss, lagt));
+        }
+
+      // now we have to substitute AUXLD_*_*{mlead-1}(+1) for t
+      sprintf(name, "AUXLD_%d_%d_%d", i, j, mlead-1);
+      ss = model.atoms.get_name_storage().query(name);
+      model.substitute_atom_for_term(ss, +1, t);
+    }
+}
+
+void
+ForwSubstBuilder::unassign_gt_1_leads(const char *name)
+{
+  const char *ss = model.atoms.get_name_storage().query(name);
+  int mlead, mlag;
+  model.atoms.varspan(name, mlead, mlag);
+  for (int ll = 2; ll <= mlead; ll++)
+    {
+      int t = model.atoms.index(ss, ll);
+      if (t != -1)
+        model.atoms.unassign_variable(ss, ll, t);
+    }
+}
+
+void
+ForwSubstBuilder::unassign_gt_1_leads()
+{
+  const vector<const char *> &endovars = model.atoms.get_endovars();
+  for (unsigned int i = 0; i < endovars.size(); i++)
+    unassign_gt_1_leads(endovars[i]);
+  const vector<const char *> &exovars = model.atoms.get_exovars();
+  for (unsigned int i = 0; i < exovars.size(); i++)
+    unassign_gt_1_leads(exovars[i]);
+}
+
+ForwSubstBuilder::ForwSubstBuilder(const ForwSubstBuilder &b, DynareModel &m)
+  : model(m)
+{
+  for (Tsubstmap::const_iterator it = b.aux_map.begin();
+       it != b.aux_map.end(); ++it)
+    {
+      const char *ss = m.atoms.get_name_storage().query((*it).first);
+      aux_map.insert(Tsubstmap::value_type(ss, (*it).second));
+    }
+}
diff --git a/dynare++/src/forw_subst_builder.cpp b/dynare++/src/forw_subst_builder.cpp
deleted file mode 100644
index e2fa6cf55838c502afdcc17a3ce0e8c03b4cb8ae..0000000000000000000000000000000000000000
--- a/dynare++/src/forw_subst_builder.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright (C) 2006-2011, Ondra Kamenik
-
-
-#include "forw_subst_builder.h"
-
-using namespace ogdyn;
-
-ForwSubstBuilder::ForwSubstBuilder(DynareModel& m)
-	: model(m)
-{
-	info.num_new_terms -= model.getParser().getTree().get_num_op();
-
-	// go through all equations
-	int neq = model.eqs.nformulas();
-	for (int i = 0; i < neq; i++) {
-		int ft = model.eqs.formula(i);
-		int mlead, mlag;
-		model.termspan(ft, mlead, mlag);
-		// if equation is too forward looking
-		if (mlead > 1) {
-			info.num_affected_equations++;
-			// break it to non-linear terms
-			unordered_set<int> nlt = model.get_nonlinear_subterms(ft);
-			int j = 0; // indexes subterms
-			// and make substitutions for all these non-linear subterms
-			for (unordered_set<int>::const_iterator it = nlt.begin();
-				 it != nlt.end(); ++it, ++j)
-				substitute_for_term(*it, i, j);
-		}
-	}
-	// unassign all variables with lead greater than 1
-	unassign_gt_1_leads();
-
-	// forget the derivatives in the tree because some variables could
-	// have been unassigned
-	model.eqs.getTree().forget_derivative_maps();
-
-	info.num_new_terms += model.getParser().getTree().get_num_op();
-}
-
-void ForwSubstBuilder::substitute_for_term(int t, int i, int j)
-{
-	int mlead, mlag;
-	model.termspan(t, mlead, mlag);
-	if (mlead > 1) {
-		info.num_subst_terms++;
-		// Example for comments: let t = f(x(+4))
-		// first make lagsubst be substitution setting f(x(+4)) to f(x(+1))
-		// this is lag = -3 (1-mlead)
-		map<int,int> lagsubst;
-        unordered_set<int> nult = model.eqs.nulary_of_term(t);// make copy of nult!
-		model.variable_shift_map(nult, 1-mlead, lagsubst);
-		int lagt = model.eqs.add_substitution(t, lagsubst);
-
-        // now maxlead of lagt is +1
-        // add AUXLD_*_*_1 = f(x(+1)) to the model
-        char name[100];
-        sprintf(name, "AUXLD_%d_%d_%d", i, j, 1);
-        model.atoms.register_uniq_endo(name);
-        info.num_aux_variables++;
-        const char* ss = model.atoms.get_name_storage().query(name);
-        int auxt = model.eqs.add_nulary(name);
-        model.eqs.add_formula(model.eqs.add_binary(ogp::MINUS, auxt, lagt));
-        aux_map.insert(Tsubstmap::value_type(ss, lagt));
-		// now add variables and equations
-		// AUXLD_*_*_2 = AUXLD_*_*_1(+1) through
-		// AUXLD_*_*_{mlead-1} = AUXLD_*_*_{mlead-2}(+1)
-		for (int ll = 1; ll <= mlead-2; ll++) {
-			// create AUXLD_*_*_{ll}(+1)
-			sprintf(name, "AUXLD_%d_%d_%d(+1)", i, j, ll);
-			int lastauxt_lead = model.eqs.add_nulary(name);
-			// create AUXLD_*_*{ll+1}
-			sprintf(name, "AUXLD_%d_%d_%d", i, j, ll+1);
-			model.atoms.register_uniq_endo(name);
-			info.num_aux_variables++;
-			ss = model.atoms.get_name_storage().query(name);
-			auxt = model.eqs.add_nulary(name);
-			// add AUXLD_*_*_{ll+1} = AUXLD_*_*_{ll}(+1)
-			model.eqs.add_formula(model.eqs.add_binary(ogp::MINUS, auxt, lastauxt_lead));
-			// add substitution to the map; todo: this
-			// works well because in the context where
-			// aux_map is used the timing doesn't matter,
-			// however, it is misleading, needs to be
-			// changed
-			aux_map.insert(Tsubstmap::value_type(ss, lagt));
-		}
-
-		// now we have to substitute AUXLD_*_*{mlead-1}(+1) for t
-        sprintf(name, "AUXLD_%d_%d_%d", i, j, mlead-1);
-        ss = model.atoms.get_name_storage().query(name);
-		model.substitute_atom_for_term(ss, +1, t);
-	}
-}
-
-void ForwSubstBuilder::unassign_gt_1_leads(const char* name)
-{
-	const char* ss = model.atoms.get_name_storage().query(name);
-	int mlead, mlag;
-	model.atoms.varspan(name, mlead, mlag);
-	for (int ll = 2; ll <= mlead; ll++) {
-		int t = model.atoms.index(ss, ll);
-		if (t != -1)
-			model.atoms.unassign_variable(ss, ll, t);
-	}
-}
-
-void ForwSubstBuilder::unassign_gt_1_leads()
-{
-	const vector<const char*>& endovars = model.atoms.get_endovars();
-	for (unsigned int i = 0; i < endovars.size(); i++)
-		unassign_gt_1_leads(endovars[i]);
-	const vector<const char*>& exovars = model.atoms.get_exovars();
-	for (unsigned int i = 0; i < exovars.size(); i++)
-		unassign_gt_1_leads(exovars[i]);	
-}
-
-ForwSubstBuilder::ForwSubstBuilder(const ForwSubstBuilder& b, DynareModel& m)
-	: model(m)
-{
-	for (Tsubstmap::const_iterator it = b.aux_map.begin();
-		 it != b.aux_map.end(); ++it) {
-		const char* ss = m.atoms.get_name_storage().query((*it).first);
-		aux_map.insert(Tsubstmap::value_type(ss, (*it).second));
-	}
-}
diff --git a/dynare++/src/forw_subst_builder.h b/dynare++/src/forw_subst_builder.hh
similarity index 99%
rename from dynare++/src/forw_subst_builder.h
rename to dynare++/src/forw_subst_builder.hh
index 9a51c2cbce1f114aac6ea756ea670dec2c58e091..3b920748f477ca1847df819fa8467f0c1dd12caf 100644
--- a/dynare++/src/forw_subst_builder.h
+++ b/dynare++/src/forw_subst_builder.hh
@@ -5,7 +5,7 @@
 #ifndef FORW_SUBST_BUILDER_H
 #define FORW_SUBST_BUILDER_H
 
-#include "dynare_model.h"
+#include "dynare_model.hh"
 
 namespace ogdyn
 {
diff --git a/dynare++/src/main.cc b/dynare++/src/main.cc
new file mode 100644
index 0000000000000000000000000000000000000000..9169a998d0d2bd1a1f392ecba3dbd624291514a7
--- /dev/null
+++ b/dynare++/src/main.cc
@@ -0,0 +1,214 @@
+// Copyright (C) 2004-2011, Ondra Kamenik
+
+#include "dynare3.hh"
+#include "dynare_exception.hh"
+#include "dynare_params.hh"
+
+#include "utils/cc/exception.hh"
+#include "parser/cc/parser_exception.hh"
+#include "../sylv/cc/SylvException.hh"
+#include "../kord/random.hh"
+#include "../kord/global_check.hh"
+#include "../kord/approximation.hh"
+
+int
+main(int argc, char **argv)
+{
+  DynareParams params(argc, argv);
+  if (params.help)
+    {
+      params.printHelp();
+      return 0;
+    }
+  if (params.version)
+    {
+      printf("Dynare++ v. %s. Copyright (C) 2004-2011, Ondra Kamenik\n",
+             DYNVERSION);
+      printf("Dynare++ comes with ABSOLUTELY NO WARRANTY and is distributed under\n");
+      printf("GPL: modules integ, tl, kord, sylv, src, extern and documentation\n");
+      printf("LGPL: modules parser, utils\n");
+      printf(" for GPL  see http://www.gnu.org/licenses/gpl.html\n");
+      printf(" for LGPL see http://www.gnu.org/licenses/lgpl.html\n");
+      return 0;
+    }
+  THREAD_GROUP::max_parallel_threads = params.num_threads;
+
+  try
+    {
+      // make journal name and journal
+      std::string jname(params.basename);
+      jname += ".jnl";
+      Journal journal(jname.c_str());
+
+      // make dynare object
+      Dynare dynare(params.modname, params.order, params.ss_tol, journal);
+      // make list of shocks for which we will do IRFs
+      vector<int> irf_list_ind;
+      if (params.do_irfs_all)
+        for (int i = 0; i < dynare.nexog(); i++)
+          irf_list_ind.push_back(i);
+      else
+        irf_list_ind = ((const DynareNameList &) dynare.getExogNames()).selectIndices(params.irf_list);
+
+      // write matlab files
+      FILE *mfd;
+      std::string mfile1(params.basename);
+      mfile1 += "_f.m";
+      if (NULL == (mfd = fopen(mfile1.c_str(), "w")))
+        {
+          fprintf(stderr, "Couldn't open %s for writing.\n", mfile1.c_str());
+          exit(1);
+        }
+      ogdyn::MatlabSSWriter writer0(dynare.getModel(), params.basename.c_str());
+      writer0.write_der0(mfd);
+      fclose(mfd);
+
+      std::string mfile2(params.basename);
+      mfile2 += "_ff.m";
+      if (NULL == (mfd = fopen(mfile2.c_str(), "w")))
+        {
+          fprintf(stderr, "Couldn't open %s for writing.\n", mfile2.c_str());
+          exit(1);
+        }
+      ogdyn::MatlabSSWriter writer1(dynare.getModel(), params.basename.c_str());
+      writer1.write_der1(mfd);
+      fclose(mfd);
+
+      // open mat file
+      std::string matfile(params.basename);
+      matfile += ".mat";
+      mat_t *matfd = Mat_Create(matfile.c_str(), NULL);
+      if (matfd == NULL)
+        {
+          fprintf(stderr, "Couldn't open %s for writing.\n", matfile.c_str());
+          exit(1);
+        }
+
+      // write info about the model (dimensions and variables)
+      dynare.writeMat(matfd, params.prefix);
+      // write the dump file corresponding to the input
+      dynare.writeDump(params.basename);
+
+      system_random_generator.initSeed(params.seed);
+
+      tls.init(dynare.order(),
+               dynare.nstat()+2*dynare.npred()+3*dynare.nboth()
+               +2*dynare.nforw()+dynare.nexog());
+
+      Approximation app(dynare, journal, params.num_steps, params.do_centralize, params.qz_criterium);
+      try
+        {
+          app.walkStochSteady();
+        }
+      catch (const KordException &e)
+        {
+          // tell about the exception and continue
+          printf("Caught (not yet fatal) Kord exception: ");
+          e.print();
+          JournalRecord rec(journal);
+          rec << "Solution routine not finished (" << e.get_message()
+              << "), see what happens" << endrec;
+        }
+
+      std::string ss_matrix_name(params.prefix);
+      ss_matrix_name += "_steady_states";
+      ConstTwoDMatrix(app.getSS()).writeMat(matfd, ss_matrix_name.c_str());
+
+      // check the approximation
+      if (params.check_along_path || params.check_along_shocks
+          || params.check_on_ellipse)
+        {
+          GlobalChecker gcheck(app, THREAD_GROUP::max_parallel_threads, journal);
+          if (params.check_along_shocks)
+            gcheck.checkAlongShocksAndSave(matfd, params.prefix,
+                                           params.getCheckShockPoints(),
+                                           params.getCheckShockScale(),
+                                           params.check_evals);
+          if (params.check_on_ellipse)
+            gcheck.checkOnEllipseAndSave(matfd, params.prefix,
+                                         params.getCheckEllipsePoints(),
+                                         params.getCheckEllipseScale(),
+                                         params.check_evals);
+          if (params.check_along_path)
+            gcheck.checkAlongSimulationAndSave(matfd, params.prefix,
+                                               params.getCheckPathPoints(),
+                                               params.check_evals);
+        }
+
+      // write the folded decision rule to the Mat-4 file
+      app.getFoldDecisionRule().writeMat(matfd, params.prefix);
+
+      // simulate conditional
+      if (params.num_condper > 0 && params.num_condsim > 0)
+        {
+          SimResultsDynamicStats rescond(dynare.numeq(), params.num_condper, 0);
+          ConstVector det_ss(app.getSS(), 0);
+          rescond.simulate(params.num_condsim, app.getFoldDecisionRule(), det_ss, dynare.getVcov(), journal);
+          rescond.writeMat(matfd, params.prefix);
+        }
+
+      // simulate unconditional
+      //const DecisionRule& dr = app.getUnfoldDecisionRule();
+      const DecisionRule &dr = app.getFoldDecisionRule();
+      if (params.num_per > 0 && params.num_sim > 0)
+        {
+          SimResultsStats res(dynare.numeq(), params.num_per, params.num_burn);
+          res.simulate(params.num_sim, dr, dynare.getSteady(), dynare.getVcov(), journal);
+          res.writeMat(matfd, params.prefix);
+
+          // impulse response functions
+          if (!irf_list_ind.empty())
+            {
+              IRFResults irf(dynare, dr, res, irf_list_ind, journal);
+              irf.writeMat(matfd, params.prefix);
+            }
+        }
+
+      // simulate with real-time statistics
+      if (params.num_rtper > 0 && params.num_rtsim > 0)
+        {
+          RTSimResultsStats rtres(dynare.numeq(), params.num_rtper, params.num_burn);
+          rtres.simulate(params.num_rtsim, dr, dynare.getSteady(), dynare.getVcov(), journal);
+          rtres.writeMat(matfd, params.prefix);
+        }
+
+      Mat_Close(matfd);
+
+    }
+  catch (const KordException &e)
+    {
+      printf("Caugth Kord exception: ");
+      e.print();
+      return e.code();
+    }
+  catch (const TLException &e)
+    {
+      printf("Caugth TL exception: ");
+      e.print();
+      return 255;
+    }
+  catch (SylvException &e)
+    {
+      printf("Caught Sylv exception: ");
+      e.printMessage();
+      return 255;
+    }
+  catch (const DynareException &e)
+    {
+      printf("Caught Dynare exception: %s\n", e.message());
+      return 255;
+    }
+  catch (const ogu::Exception &e)
+    {
+      printf("Caught ogu::Exception: ");
+      e.print();
+      return 255;
+    }
+  catch (const ogp::ParserException &e)
+    {
+      printf("Caught parser exception: %s\n", e.message());
+      return 255;
+    }
+
+  return 0;
+}
diff --git a/dynare++/src/main.cpp b/dynare++/src/main.cpp
deleted file mode 100644
index 665ab468d9aa614e1a5eb17b8cc094b3515e1192..0000000000000000000000000000000000000000
--- a/dynare++/src/main.cpp
+++ /dev/null
@@ -1,188 +0,0 @@
-// Copyright (C) 2004-2011, Ondra Kamenik
-
-#include "dynare3.h"
-#include "dynare_exception.h"
-#include "dynare_params.h"
-
-#include "utils/cc/exception.h"
-#include "parser/cc/parser_exception.h"
-#include "../sylv/cc/SylvException.h"
-#include "../kord/random.hh"
-#include "../kord/global_check.hh"
-#include "../kord/approximation.hh"
-
-int main(int argc, char** argv)
-{
-	DynareParams params(argc, argv);
-	if (params.help) {
-		params.printHelp();
-		return 0;
-	}
-	if (params.version) {
-		printf("Dynare++ v. %s. Copyright (C) 2004-2011, Ondra Kamenik\n",
-			   DYNVERSION);
-		printf("Dynare++ comes with ABSOLUTELY NO WARRANTY and is distributed under\n");
-		printf("GPL: modules integ, tl, kord, sylv, src, extern and documentation\n");
-		printf("LGPL: modules parser, utils\n");
-		printf(" for GPL  see http://www.gnu.org/licenses/gpl.html\n");
-		printf(" for LGPL see http://www.gnu.org/licenses/lgpl.html\n");
-		return 0;
-	}
-	THREAD_GROUP::max_parallel_threads = params.num_threads;
-
-	try {
-		// make journal name and journal
-		std::string jname(params.basename);
-		jname += ".jnl";
-		Journal journal(jname.c_str());
-
-		// make dynare object
-		Dynare dynare(params.modname, params.order, params.ss_tol, journal);
-		// make list of shocks for which we will do IRFs
-        vector<int> irf_list_ind;
-		if (params.do_irfs_all)
-			for (int i = 0; i < dynare.nexog(); i++)
-				irf_list_ind.push_back(i);
-		else
-			irf_list_ind = ((const DynareNameList&)dynare.getExogNames()).selectIndices(params.irf_list);
-
-		// write matlab files
-		FILE* mfd;
-		std::string mfile1(params.basename);
-		mfile1 += "_f.m";
-		if (NULL == (mfd=fopen(mfile1.c_str(), "w"))) {
-			fprintf(stderr, "Couldn't open %s for writing.\n", mfile1.c_str());
-			exit(1);
-		}
-		ogdyn::MatlabSSWriter writer0(dynare.getModel(), params.basename.c_str());
-		writer0.write_der0(mfd);
-		fclose(mfd);
-
-		std::string mfile2(params.basename);
-		mfile2 += "_ff.m";
-		if (NULL == (mfd=fopen(mfile2.c_str(), "w"))) {
-			fprintf(stderr, "Couldn't open %s for writing.\n", mfile2.c_str());
-			exit(1);
-		}
-		ogdyn::MatlabSSWriter writer1(dynare.getModel(), params.basename.c_str());
-		writer1.write_der1(mfd);
-		fclose(mfd);
-
-		// open mat file
-		std::string matfile(params.basename);
-		matfile += ".mat";
-		mat_t* matfd = Mat_Create(matfile.c_str(), NULL);
-		if (matfd == NULL) {
-			fprintf(stderr, "Couldn't open %s for writing.\n", matfile.c_str());
-			exit(1);
-		}
-
-		// write info about the model (dimensions and variables)
-		dynare.writeMat(matfd, params.prefix);
-		// write the dump file corresponding to the input
-		dynare.writeDump(params.basename);
-
-
-		system_random_generator.initSeed(params.seed);
-
-		tls.init(dynare.order(),
-				 dynare.nstat()+2*dynare.npred()+3*dynare.nboth()+
-				 2*dynare.nforw()+dynare.nexog());
-
-		Approximation app(dynare, journal, params.num_steps, params.do_centralize, params.qz_criterium);
-		try {
-			app.walkStochSteady();
-		} catch (const KordException& e) {
-			// tell about the exception and continue
-			printf("Caught (not yet fatal) Kord exception: ");
-			e.print();
-			JournalRecord rec(journal);
-			rec << "Solution routine not finished (" << e.get_message()
-				<< "), see what happens" << endrec; 
-		}
-
-		std::string ss_matrix_name(params.prefix);
-		ss_matrix_name += "_steady_states";
-		ConstTwoDMatrix(app.getSS()).writeMat(matfd, ss_matrix_name.c_str());
-
-		// check the approximation
-		if (params.check_along_path || params.check_along_shocks
-			|| params.check_on_ellipse) {
-			GlobalChecker gcheck(app, THREAD_GROUP::max_parallel_threads, journal);
-			if (params.check_along_shocks)
-				gcheck.checkAlongShocksAndSave(matfd, params.prefix,
-											   params.getCheckShockPoints(),
-											   params.getCheckShockScale(),
-											   params.check_evals);
-			if (params.check_on_ellipse)
-				gcheck.checkOnEllipseAndSave(matfd, params.prefix,
-											 params.getCheckEllipsePoints(),
-											 params.getCheckEllipseScale(),
-											 params.check_evals);
-			if (params.check_along_path)
-				gcheck.checkAlongSimulationAndSave(matfd, params.prefix,
-												   params.getCheckPathPoints(),
-												   params.check_evals);
-		}
-
-		// write the folded decision rule to the Mat-4 file
-		app.getFoldDecisionRule().writeMat(matfd, params.prefix);
-
-		// simulate conditional
-		if (params.num_condper > 0 && params.num_condsim > 0) {
-			SimResultsDynamicStats rescond(dynare.numeq(), params.num_condper, 0);
-			ConstVector det_ss(app.getSS(),0);
-			rescond.simulate(params.num_condsim, app.getFoldDecisionRule(), det_ss, dynare.getVcov(), journal);
-			rescond.writeMat(matfd, params.prefix);
-		}
-
-		// simulate unconditional
-		//const DecisionRule& dr = app.getUnfoldDecisionRule();
-		const DecisionRule& dr = app.getFoldDecisionRule();
-		if (params.num_per > 0 && params.num_sim > 0) {
-			SimResultsStats res(dynare.numeq(), params.num_per, params.num_burn);
-			res.simulate(params.num_sim, dr, dynare.getSteady(), dynare.getVcov(), journal);
-			res.writeMat(matfd, params.prefix);
-			
-			// impulse response functions
-			if (! irf_list_ind.empty()) {
-				IRFResults irf(dynare, dr, res, irf_list_ind, journal);
-				irf.writeMat(matfd, params.prefix);
-			}
-		}
-
-		// simulate with real-time statistics
-		if (params.num_rtper > 0 && params.num_rtsim > 0) {
-			RTSimResultsStats rtres(dynare.numeq(), params.num_rtper, params.num_burn);
-			rtres.simulate(params.num_rtsim, dr, dynare.getSteady(), dynare.getVcov(), journal);
-			rtres.writeMat(matfd, params.prefix);
-		}
-
-		Mat_Close(matfd);
-
-	} catch (const KordException& e) {
-		printf("Caugth Kord exception: ");
-		e.print();
-		return e.code();
-	} catch (const TLException& e) {
-		printf("Caugth TL exception: ");
-		e.print();
-		return 255;
-	} catch (SylvException& e) {
-		printf("Caught Sylv exception: ");
-		e.printMessage();
-		return 255;
-	} catch (const DynareException& e) {
-		printf("Caught Dynare exception: %s\n", e.message());
-		return 255;
-	} catch (const ogu::Exception& e) {
-		printf("Caught ogu::Exception: ");
-		e.print();
-		return 255;
-	} catch (const ogp::ParserException& e) {
-		printf("Caught parser exception: %s\n", e.message());
-		return 255;
-	}
-
-  return 0;
-}
diff --git a/dynare++/src/nlsolve.cc b/dynare++/src/nlsolve.cc
new file mode 100644
index 0000000000000000000000000000000000000000..8b5419ca2f6ecf45c577a7ff08bdd9b878edfb2f
--- /dev/null
+++ b/dynare++/src/nlsolve.cc
@@ -0,0 +1,265 @@
+// Copyright (C) 2006, Ondra Kamenik
+
+// $Id: nlsolve.cpp 762 2006-05-22 13:00:07Z kamenik $
+
+#include "nlsolve.hh"
+#include "dynare_exception.hh"
+
+#include <cmath>
+
+using namespace ogu;
+
+/** This should not be greater than DBL_EPSILON^(1/2). */
+double GoldenSectionSearch::tol = 1.e-4;
+
+/** This is equal to the golden section ratio. */
+double GoldenSectionSearch::golden = (3.-std::sqrt(5.))/2;
+
+double
+GoldenSectionSearch::search(OneDFunction &f, double x1, double x2)
+{
+  double b;
+  if (init_bracket(f, x1, x2, b))
+    {
+      double fb = f.eval(b);
+      double f1 = f.eval(x1);
+      f.eval(x2);
+      double dx;
+      do
+        {
+          double w = (b-x1)/(x2-x1);
+          dx = std::abs((1-2*w)*(x2-x1));
+          double x;
+          if (b-x1 > x2-b)
+            x = b - dx;
+          else
+            x = b + dx;
+          double fx = f.eval(x);
+          if (!std::isfinite(fx))
+            return x1;
+          if (b-x1 > x2-b)
+            {
+              // x is on the left from b
+              if (f1 > fx && fx < fb)
+                {
+                  // pickup bracket [f1,fx,fb]
+                  x2 = b;
+                  fb = fx;
+                  b = x;
+                }
+              else
+                {
+                  // pickup bracket [fx,fb,fx2]
+                  f1 = fx;
+                  x1 = x;
+                }
+            }
+          else
+            {
+              // x is on the right from b
+              if (f1 > fb && fb < fx)
+                {
+                  // pickup bracket [f1,fb,fx]
+                  x2 = x;
+                }
+              else
+                {
+                  // pickup bracket [fb,fx,f2]
+                  f1 = fb;
+                  x1 = b;
+                  fb = fx;
+                  b = x;
+                }
+            }
+        }
+      while (dx > tol);
+    }
+  return b;
+}
+
+bool
+GoldenSectionSearch::init_bracket(OneDFunction &f, double x1, double &x2, double &b)
+{
+  double f1 = f.eval(x1);
+  if (!std::isfinite(f1))
+    throw DynareException(__FILE__, __LINE__,
+                          "Safer point not finite in GoldenSectionSearch::init_bracket");
+
+  int cnt = 0;
+  bool bracket_found = false;
+  do
+    {
+      bool finite_found = search_for_finite(f, x1, x2, b);
+      if (!finite_found)
+        {
+          b = x1;
+          return false;
+        }
+      double f2 = f.eval(x2);
+      double fb = f.eval(b);
+      double bsym = 2*x2 - b;
+      double fbsym = f.eval(bsym);
+      // now we know that f1, f2, and fb are finite
+      if (std::isfinite(fbsym))
+        {
+          // we have four numbers f1, fb, f2, fbsym, we test for the
+          // following combinations to find the bracket:
+          // [f1,f2,fbsym], [f1,fb,fbsym] and [f1,fb,fbsym]
+          if (f1 > f2 && f2 < fbsym)
+            {
+              bracket_found = true;
+              b = x2;
+              x2 = bsym;
+            }
+          else if (f1 > fb && fb < fbsym)
+            {
+              bracket_found = true;
+              x2 = bsym;
+            }
+          else if (f1 > fb && fb < f2)
+            {
+              bracket_found = true;
+            }
+          else
+            {
+              double newx2 = b;
+              // choose the smallest value in case we end
+              if (f1 > fbsym)
+                {
+                  // the smallest value is on the other end, we do
+                  // not want to continue
+                  b = bsym;
+                  return false;
+                }
+              else
+                b = x1;
+              // move x2 to b in case we continue
+              x2 = newx2;
+            }
+        }
+      else
+        {
+          // we have only three numbers, we test for the bracket,
+          // and if not found, we set b as potential result and
+          // shorten x2 as potential init value for next cycle
+          if (f1 > fb && fb < f2)
+            bracket_found = true;
+          else
+            {
+              double newx2 = b;
+              // choose the smaller value in case we end
+              if (f1 > f2)
+                b = x2;
+              else
+                b = x1;
+              // move x2 to b in case we continue
+              x2 = newx2;
+            }
+        }
+      cnt++;
+    }
+  while (!bracket_found && cnt < 5);
+
+  return bracket_found;
+}
+
+/** This moves x2 toward to x1 until the function at x2 is finite and
+ * b as a golden section between x1 and x2 yields also finite f. */
+bool
+GoldenSectionSearch::search_for_finite(OneDFunction &f, double x1, double &x2, double &b)
+{
+  int cnt = 0;
+  bool found = false;
+  do
+    {
+      double f2 = f.eval(x2);
+      b = (1-golden)*x1 + golden*x2;
+      double fb = f.eval(b);
+      found = std::isfinite(f2) && std::isfinite(fb);
+      if (!found)
+        x2 = b;
+      cnt++;
+    }
+  while (!found && cnt < 5);
+
+  return found;
+}
+
+void
+VectorFunction::check_for_eval(const ConstVector &in, Vector &out) const
+{
+  if (inDim() != in.length() || outDim() != out.length())
+    throw DynareException(__FILE__, __LINE__,
+                          "Wrong dimensions in VectorFunction::check_for_eval");
+}
+
+double
+NLSolver::eval(double lambda)
+{
+  Vector xx((const Vector &)x);
+  xx.add(1-lambda, xcauchy);
+  xx.add(lambda, xnewton);
+  Vector ff(func.outDim());
+  func.eval(xx, ff);
+  return ff.dot(ff);
+}
+
+bool
+NLSolver::solve(Vector &xx, int &iter)
+{
+  JournalRecord rec(journal);
+  rec << "Iter   lambda      residual" << endrec;
+  JournalRecord rec1(journal);
+  rec1 << "---------------------------" << endrec;
+  char tmpbuf[14];
+
+  x = (const Vector &) xx;
+  iter = 0;
+  // setup fx
+  Vector fx(func.outDim());
+  func.eval(x, fx);
+  if (!fx.isFinite())
+    throw DynareException(__FILE__, __LINE__,
+                          "Initial guess does not yield finite residual in NLSolver::solve");
+  bool converged = fx.getMax() < tol;
+  JournalRecord rec2(journal);
+  sprintf(tmpbuf, "%10.6g", fx.getMax());
+  rec2 << iter << "         N/A   " << tmpbuf << endrec;
+  while (!converged && iter < max_iter)
+    {
+      // setup Jacobian
+      jacob.eval(x);
+      // calculate cauchy step
+      Vector g(func.inDim());
+      g.zeros();
+      ConstTwoDMatrix(jacob).multaVecTrans(g, fx);
+      Vector Jg(func.inDim());
+      Jg.zeros();
+      ConstTwoDMatrix(jacob).multaVec(Jg, g);
+      double m = -g.dot(g)/Jg.dot(Jg);
+      xcauchy = (const Vector &) g;
+      xcauchy.mult(m);
+      // calculate newton step
+      xnewton = (const Vector &) fx;
+      ConstTwoDMatrix(jacob).multInvLeft(xnewton);
+      xnewton.mult(-1);
+
+      // line search
+      double lambda = GoldenSectionSearch::search(*this, 0, 1);
+      x.add(1-lambda, xcauchy);
+      x.add(lambda, xnewton);
+      // evaluate func
+      func.eval(x, fx);
+      converged = fx.getMax() < tol;
+
+      // iter
+      iter++;
+
+      JournalRecord rec3(journal);
+      sprintf(tmpbuf, "%10.6g", fx.getMax());
+      rec3 << iter << "    " << lambda << "   " << tmpbuf << endrec;
+    }
+  xx = (const Vector &) x;
+
+  return converged;
+}
diff --git a/dynare++/src/nlsolve.cpp b/dynare++/src/nlsolve.cpp
deleted file mode 100644
index 1210176b3f6d8a853e198976754f1c66ba057e51..0000000000000000000000000000000000000000
--- a/dynare++/src/nlsolve.cpp
+++ /dev/null
@@ -1,228 +0,0 @@
-// Copyright (C) 2006, Ondra Kamenik
-
-// $Id: nlsolve.cpp 762 2006-05-22 13:00:07Z kamenik $
-
-#include "nlsolve.h"
-#include "dynare_exception.h"
-
-#include <cmath>
-
-using namespace ogu;
-
-/** This should not be greater than DBL_EPSILON^(1/2). */
-double GoldenSectionSearch::tol = 1.e-4;
-
-/** This is equal to the golden section ratio. */
-double GoldenSectionSearch::golden = (3.-std::sqrt(5.))/2;
-
-double GoldenSectionSearch::search(OneDFunction& f, double x1, double x2)
-{
-	double b;
-	if (init_bracket(f, x1, x2, b)) {
-		double fb = f.eval(b);
-		double f1 = f.eval(x1);
-		f.eval(x2);
-		double dx;
-		do {
-			double w = (b-x1)/(x2-x1);
-			dx = std::abs((1-2*w)*(x2-x1));
-			double x;
-			if (b-x1 > x2-b)
-				x = b - dx;
-			else
-				x = b + dx;
-			double fx = f.eval(x);
-			if (! std::isfinite(fx))
-				return x1;
-			if (b-x1 > x2-b) {
-				// x is on the left from b
-				if (f1 > fx && fx < fb) {
-					// pickup bracket [f1,fx,fb]
-					x2 = b;
-					fb = fx;
-					b = x;
-				} else {
-					// pickup bracket [fx,fb,fx2]
-					f1 = fx;
-					x1 = x;
-				}
-			} else {
-				// x is on the right from b
-				if (f1 > fb && fb < fx) {
-					// pickup bracket [f1,fb,fx]
-					x2 = x;
-				} else {
-					// pickup bracket [fb,fx,f2]
-					f1 = fb;
-					x1 = b;
-					fb = fx;
-					b = x;
-				}
-			}
-		} while(dx > tol);
-	}
-	return b;
-}
-
-bool GoldenSectionSearch::init_bracket(OneDFunction& f, double x1, double& x2, double& b)
-{
-	double f1 = f.eval(x1);
-	if (! std::isfinite(f1))
-		throw DynareException(__FILE__, __LINE__,
-							  "Safer point not finite in GoldenSectionSearch::init_bracket");
-
-	int cnt = 0;
-	bool bracket_found = false;
-	do {
-		bool finite_found = search_for_finite(f, x1, x2, b);
-		if (! finite_found) {
-			b = x1;
-			return false;
-		}
-		double f2 = f.eval(x2);
-		double fb = f.eval(b);
-		double bsym = 2*x2 - b;
-		double fbsym = f.eval(bsym);
-		// now we know that f1, f2, and fb are finite
-		if (std::isfinite(fbsym)) {
-			// we have four numbers f1, fb, f2, fbsym, we test for the
-			// following combinations to find the bracket:
-			// [f1,f2,fbsym], [f1,fb,fbsym] and [f1,fb,fbsym]
-			if (f1 > f2 && f2 < fbsym) {
-				bracket_found = true;
-				b = x2;
-				x2 = bsym;
-			} else if (f1 > fb && fb < fbsym) {
-				bracket_found = true;
-				x2 = bsym;
-			} else if (f1 > fb && fb < f2) {
-				bracket_found = true;
-			} else {
-				double newx2 = b;
-				// choose the smallest value in case we end
-				if (f1 > fbsym) {
-					// the smallest value is on the other end, we do
-					// not want to continue
-					b = bsym;
-					return false;
-				} else
-					b = x1;
-					// move x2 to b in case we continue 
-					x2 = newx2;
-			}
-		} else {
-			// we have only three numbers, we test for the bracket,
-			// and if not found, we set b as potential result and
-			// shorten x2 as potential init value for next cycle
-			if (f1 > fb && fb < f2)
-				bracket_found = true;
-			else {
-				double newx2 = b;
-				// choose the smaller value in case we end
-				if (f1 > f2)
-					b = x2;
-				else
-					b = x1;
-				// move x2 to b in case we continue
-				x2 = newx2;
-			}
-		}
-		cnt++;
-	} while (! bracket_found && cnt < 5);
-	
-	return bracket_found;
-}
-
-/** This moves x2 toward to x1 until the function at x2 is finite and
- * b as a golden section between x1 and x2 yields also finite f. */
-bool GoldenSectionSearch::search_for_finite(OneDFunction& f, double x1, double& x2, double&b)
-{
-	int cnt = 0;
-	bool found = false;
-	do {
-		double f2 = f.eval(x2);
-		b = (1-golden)*x1 + golden*x2;
-		double fb = f.eval(b);
-		found = std::isfinite(f2) && std::isfinite(fb);
-		if (! found)
-			x2 = b;
-		cnt++;
-	} while (! found && cnt < 5);
-
-	return found;
-}
-
-void VectorFunction::check_for_eval(const ConstVector& in, Vector& out) const
-{
-	if (inDim() != in.length() || outDim() != out.length())
-		throw DynareException(__FILE__, __LINE__,
-							  "Wrong dimensions in VectorFunction::check_for_eval");
-}
-
-double NLSolver::eval(double lambda)
-{
-	Vector xx((const Vector&)x);
-	xx.add(1-lambda, xcauchy);
-	xx.add(lambda, xnewton);
-	Vector ff(func.outDim());
-	func.eval(xx, ff);
-	return ff.dot(ff);
-}
-
-bool NLSolver::solve(Vector& xx, int& iter)
-{
-	JournalRecord rec(journal);
-	rec << "Iter   lambda      residual" << endrec;
-	JournalRecord rec1(journal);
-	rec1 << "---------------------------" << endrec;
-	char tmpbuf[14];
-
-	x = (const Vector&)xx;
-	iter = 0;
-	// setup fx
-	Vector fx(func.outDim());
-	func.eval(x, fx);
-	if (!fx.isFinite())
-		throw DynareException(__FILE__,__LINE__,
-							  "Initial guess does not yield finite residual in NLSolver::solve");
-	bool converged = fx.getMax() < tol;
-	JournalRecord rec2(journal);
-	sprintf(tmpbuf, "%10.6g", fx.getMax());
-	rec2 << iter << "         N/A   " << tmpbuf << endrec;
-	while (! converged && iter < max_iter) {
-		// setup Jacobian
-		jacob.eval(x);
-		// calculate cauchy step
-		Vector g(func.inDim());
-		g.zeros();
-		ConstTwoDMatrix(jacob).multaVecTrans(g, fx);
-		Vector Jg(func.inDim());
-		Jg.zeros();
-		ConstTwoDMatrix(jacob).multaVec(Jg, g);
-		double m = -g.dot(g)/Jg.dot(Jg);
-		xcauchy = (const Vector&) g;
-		xcauchy.mult(m);
-		// calculate newton step
-		xnewton = (const Vector&) fx;
-		ConstTwoDMatrix(jacob).multInvLeft(xnewton);
-		xnewton.mult(-1);
-
-		// line search
-		double lambda = GoldenSectionSearch::search(*this, 0, 1);
-		x.add(1-lambda, xcauchy);
-		x.add(lambda, xnewton);
-		// evaluate func
-		func.eval(x, fx);
-		converged = fx.getMax() < tol;
-
-		// iter
-		iter++;
-
-		JournalRecord rec3(journal);
-		sprintf(tmpbuf, "%10.6g", fx.getMax());
-		rec3 << iter << "    " << lambda << "   " << tmpbuf << endrec;
-	}
-	xx = (const Vector&)x;
-
-	return converged;
-}
diff --git a/dynare++/src/nlsolve.h b/dynare++/src/nlsolve.hh
similarity index 100%
rename from dynare++/src/nlsolve.h
rename to dynare++/src/nlsolve.hh
diff --git a/dynare++/src/planner_builder.cc b/dynare++/src/planner_builder.cc
new file mode 100644
index 0000000000000000000000000000000000000000..b3d4035259b9502f13ae40ca8d46742a539b8e69
--- /dev/null
+++ b/dynare++/src/planner_builder.cc
@@ -0,0 +1,419 @@
+// Copyright (C) 2006, Ondra Kamenik
+
+// $Id$
+
+#include "planner_builder.hh"
+#include "dynare_exception.hh"
+
+#include <cmath>
+
+using namespace ogdyn;
+
+const IntegerMatrix &
+IntegerMatrix::operator=(const IntegerMatrix &im)
+{
+  if (nr != im.nr || nc != im.nc)
+    throw DynareException(__FILE__, __LINE__,
+                          "Matrices have different dimensions in IntegerMatrix::operator=");
+  memcpy(data, im.data, nr*nc*sizeof(int));
+  return *this;
+}
+
+const IntegerArray3 &
+IntegerArray3::operator=(const IntegerArray3 &ia3)
+{
+  if (n1 != ia3.n1 || n2 != ia3.n2 || n3 != ia3.n3)
+    throw DynareException(__FILE__, __LINE__,
+                          "Arrays have different dimensions in IntegerArray3::operator=");
+  memcpy(data, ia3.data, n1*n2*n3*sizeof(int));
+  return *this;
+}
+
+PlannerBuilder::PlannerBuilder(DynareModel &m, const Tvarset &yyset,
+                               const Teqset &ffset)
+  : yset(), fset(ffset), model(m),
+    tb(model.t_plobjective), tbeta(model.t_pldiscount),
+    maxlead(model.atoms.get_maxlead()),
+    minlag(model.atoms.get_minlag()),
+    diff_b(yyset.size(), 1-minlag),
+    diff_f(yyset.size(), fset.size(), 1+maxlead-minlag),
+    static_atoms(),
+    static_tree(),
+    diff_b_static(yyset.size(), 1-minlag),
+    diff_f_static(yyset.size(), fset.size(), 1+maxlead-minlag)
+{
+  info.num_new_terms -= model.getParser().getTree().get_num_op();
+
+  fill_yset(m.atoms.get_name_storage(), yyset);
+
+  add_derivatives_of_b();
+  add_derivatives_of_f();
+  shift_derivatives_of_b();
+  shift_derivatives_of_f();
+  beta_multiply_b();
+  beta_multiply_f();
+  make_static_version();
+  lagrange_mult_f();
+  form_equations();
+
+  info.num_new_terms += model.getParser().getTree().get_num_op();
+}
+
+PlannerBuilder::PlannerBuilder(const PlannerBuilder &pb, ogdyn::DynareModel &m)
+  : yset(), fset(pb.fset), model(m),
+    tb(pb.tb), tbeta(pb.tbeta),
+    maxlead(pb.maxlead), minlag(pb.minlag),
+    diff_b(pb.diff_b), diff_f(pb.diff_f),
+    static_atoms(pb.static_atoms),
+    static_tree(pb.static_tree),
+    diff_b_static(pb.diff_b_static),
+    diff_f_static(pb.diff_f_static),
+    aux_map(), static_aux_map()
+
+{
+  fill_yset(m.atoms.get_name_storage(), pb.yset);
+  fill_aux_map(m.atoms.get_name_storage(), pb.aux_map, pb.static_aux_map);
+}
+
+void
+PlannerBuilder::add_derivatives_of_b()
+{
+  int yi = 0;
+  for (Tvarset::const_iterator yname = yset.begin();
+       yname != yset.end(); ++yname, yi++)
+    for (int ll = minlag; ll <= 0; ll++)
+      {
+        int yt = model.atoms.index(*yname, ll);
+        if (yt != -1)
+          diff_b(yi, ll-minlag) = model.eqs.add_derivative(tb, yt);
+        else
+          diff_b(yi, ll-minlag) = ogp::OperationTree::zero;
+      }
+}
+
+void
+PlannerBuilder::add_derivatives_of_f()
+{
+  int yi = 0;
+  for (Tvarset::const_iterator yname = yset.begin();
+       yname != yset.end(); ++yname, yi++)
+    for (unsigned int fi = 0; fi < fset.size(); fi++)
+      for (int ll = minlag; ll <= maxlead; ll++)
+        {
+          int yt = model.atoms.index(*yname, ll);
+          if (yt != -1)
+            diff_f(yi, fi, ll-minlag)
+              = model.eqs.add_derivative(model.eqs.formula(fset[fi]), yt);
+          else
+            diff_f(yi, fi, ll-minlag) = ogp::OperationTree::zero;
+        }
+}
+
+void
+PlannerBuilder::shift_derivatives_of_b()
+{
+  map<int, int> subst;
+  for (int yi = 0; yi < diff_b.nrows(); yi++)
+    for (int ll = minlag; ll < 0; ll++)
+      if (diff_b(yi, ll-minlag) != ogp::OperationTree::zero)
+        {
+          model.variable_shift_map(model.eqs.nulary_of_term(diff_b(yi, ll-minlag)),
+                                   -ll, subst);
+          diff_b(yi, ll-minlag) = model.eqs.add_substitution(diff_b(yi, ll-minlag), subst);
+        }
+}
+
+void
+PlannerBuilder::shift_derivatives_of_f()
+{
+  map<int, int> subst;
+  for (int yi = 0; yi < diff_f.dim1(); yi++)
+    for (int fi = 0; fi < diff_f.dim2(); fi++)
+      {
+        // first do it leads which are put under expectation before t: no problem
+        for (int ll = 0; ll <= maxlead; ll++)
+          if (diff_f(yi, fi, ll-minlag) != ogp::OperationTree::zero)
+            {
+              model.variable_shift_map(model.eqs.nulary_of_term(diff_f(yi, fi, ll-minlag)),
+                                       -ll, subst);
+              diff_f(yi, fi, ll-minlag)
+                = model.eqs.add_substitution(diff_f(yi, fi, ll-minlag), subst);
+            }
+        // now do it for lags, these are put as leads under
+        // expectations after time t, so we have to introduce
+        // auxiliary variables at time t, and make leads of them here
+        for (int ll = minlag; ll < 0; ll++)
+          {
+            int ft = diff_f(yi, fi, ll-minlag);
+            if (ft != ogp::OperationTree::zero)
+              {
+                // if the ft term has a lead, than we need to
+                // introduce an auxiliary variable z_t, define it
+                // as E_t[ft] and put z_{t-ll} to the
+                // equation. Otherwise, we just put leaded ft to
+                // the equation directly.
+                int ft_maxlead, ft_minlag;
+                model.termspan(ft, ft_maxlead, ft_minlag);
+                if (ft_maxlead > 0)
+                  {
+                    // make an auxiliary variable
+                    char name[100];
+                    sprintf(name, "AUX_%d_%d_%d", yi, fset[fi], -ll);
+                    model.atoms.register_uniq_endo(name);
+                    info.num_aux_variables++;
+                    int taux = model.eqs.add_nulary(name);
+                    sprintf(name, "AUX_%d_%d_%d(%d)", yi, fset[fi], -ll, -ll);
+                    int taux_leaded = model.eqs.add_nulary(name);
+                    // put aux_leaded to the equation
+                    diff_f(yi, fi, ll-minlag) = taux_leaded;
+                    // save auxiliary variable and the term
+                    aux_map.insert(Tsubstmap::value_type(model.atoms.name(taux), ft));
+                  }
+                else
+                  {
+                    // no auxiliary variable is needed and the
+                    // term ft can be leaded in place
+                    model.variable_shift_map(model.eqs.nulary_of_term(ft), -ll, subst);
+                    diff_f(yi, fi, ll-minlag)
+                      = model.eqs.add_substitution(ft, subst);
+                  }
+              }
+          }
+      }
+}
+
+void
+PlannerBuilder::beta_multiply_b()
+{
+  int beta_pow = ogp::OperationTree::one;
+  for (int ll = 0; ll >= minlag; ll--,
+         beta_pow = model.eqs.add_binary(ogp::TIMES, beta_pow, tbeta))
+    for (int yi = 0; yi < diff_b.nrows(); yi++)
+      if (diff_b(yi, ll-minlag) != ogp::OperationTree::zero)
+        diff_b(yi, ll-minlag)
+          = model.eqs.add_binary(ogp::TIMES, beta_pow, diff_b(yi, ll-minlag));
+}
+
+void
+PlannerBuilder::beta_multiply_f()
+{
+  int beta_pow = ogp::OperationTree::one;
+  for (int ll = 0; ll <= maxlead; ll++,
+         beta_pow = model.eqs.add_binary(ogp::DIVIDE, beta_pow, tbeta))
+    for (int yi = 0; yi < diff_f.dim1(); yi++)
+      for (int fi = 0; fi < diff_f.dim2(); fi++)
+        if (diff_f(yi, fi, ll-minlag) != ogp::OperationTree::zero)
+          diff_f(yi, fi, ll-minlag)
+            = model.eqs.add_binary(ogp::TIMES, beta_pow, diff_f(yi, fi, ll-minlag));
+
+  beta_pow = ogp::OperationTree::one;
+  for (int ll = 0; ll >= minlag; ll--,
+         beta_pow = model.eqs.add_binary(ogp::TIMES, beta_pow, tbeta))
+    for (int yi = 0; yi < diff_f.dim1(); yi++)
+      for (int fi = 0; fi < diff_f.dim2(); fi++)
+        if (diff_f(yi, fi, ll-minlag) != ogp::OperationTree::zero)
+          diff_f(yi, fi, ll-minlag)
+            = model.eqs.add_binary(ogp::TIMES, beta_pow, diff_f(yi, fi, ll-minlag));
+}
+
+void
+PlannerBuilder::make_static_version()
+{
+  // map holding substitutions from dynamic to static
+  ogp::StaticFineAtoms::Tintintmap tmap;
+
+  // fill static atoms with outer ordering
+  static_atoms.import_atoms(model.atoms, static_tree, tmap);
+
+  // go through diff_b and fill diff_b_static
+  for (int ll = minlag; ll <= 0; ll++)
+    for (int yi = 0; yi < diff_b.nrows(); yi++)
+      diff_b_static(yi, ll-minlag)
+        = static_tree.add_substitution(diff_b(yi, ll-minlag),
+                                       tmap,  model.eqs.getTree());
+
+  // go through diff_f and fill diff_f_static
+  for (int ll = minlag; ll <= maxlead; ll++)
+    for (int yi = 0; yi < diff_f.dim1(); yi++)
+      for (int fi = 0; fi < diff_f.dim2(); fi++)
+        diff_f_static(yi, fi, ll-minlag)
+          = static_tree.add_substitution(diff_f(yi, fi, ll-minlag),
+                                         tmap, model.eqs.getTree());
+
+  // go through aux_map and fill static_aux_map
+  for (Tsubstmap::const_iterator it = aux_map.begin();
+       it != aux_map.end(); ++it)
+    {
+      int tstatic = static_tree.add_substitution((*it).second, tmap, model.eqs.getTree());
+      const char *name = static_atoms.get_name_storage().query((*it).first);
+      static_aux_map.insert(Tsubstmap::value_type(name, tstatic));
+    }
+}
+
+void
+PlannerBuilder::lagrange_mult_f()
+{
+  // register multipliers
+  char mult_name[100];
+  for (int fi = 0; fi < diff_f.dim2(); fi++)
+    {
+      sprintf(mult_name, "MULT%d", fset[fi]);
+      model.atoms.register_uniq_endo(mult_name);
+      info.num_lagrange_mults++;
+    }
+  // multiply with the multipliers
+  for (int yi = 0; yi < diff_f.dim1(); yi++)
+    for (int fi = 0; fi < diff_f.dim2(); fi++)
+      for (int ll = minlag; ll <= maxlead; ll++)
+        if (diff_f(yi, fi, ll-minlag) != ogp::OperationTree::zero)
+          {
+            sprintf(mult_name, "MULT%d(%d)", fset[fi], -ll);
+            int tm = model.eqs.add_nulary(mult_name);
+            diff_f(yi, fi, ll-minlag)
+              = model.eqs.add_binary(ogp::TIMES, tm, diff_f(yi, fi, ll-minlag));
+          }
+}
+
+void
+PlannerBuilder::form_equations()
+{
+  // add planner's FOCs
+  for (int yi = 0; yi < diff_f.dim1(); yi++)
+    {
+      int eq = ogp::OperationTree::zero;
+      for (int ll = minlag; ll <= 0; ll++)
+        eq = model.eqs.add_binary(ogp::PLUS, eq, diff_b(yi, ll-minlag));
+      for (int fi = 0; fi < diff_f.dim2(); fi++)
+        for (int ll = minlag; ll <= maxlead; ll++)
+          eq = model.eqs.add_binary(ogp::PLUS, eq, diff_f(yi, fi, ll-minlag));
+      model.eqs.add_formula(eq);
+    }
+
+  // add equations for auxiliary variables
+  for (Tsubstmap::const_iterator it = aux_map.begin();
+       it != aux_map.end(); ++it)
+    {
+      int t = model.atoms.index((*it).first, 0);
+      model.eqs.add_formula(model.eqs.add_binary(ogp::MINUS, t, (*it).second));
+    }
+}
+
+void
+PlannerBuilder::fill_yset(const ogp::NameStorage &ns,
+                          const PlannerBuilder::Tvarset &yyset)
+{
+  for (Tvarset::const_iterator it = yyset.begin(); it != yyset.end(); ++it)
+    yset.insert(ns.query(*it));
+}
+
+void
+PlannerBuilder::fill_aux_map(const ogp::NameStorage &ns, const Tsubstmap &aaux_map,
+                             const Tsubstmap &astatic_aux_map)
+{
+  // fill aux_map
+  for (Tsubstmap::const_iterator it = aaux_map.begin();
+       it != aaux_map.end(); ++it)
+    aux_map.insert(Tsubstmap::value_type(ns.query((*it).first), (*it).second));
+
+  // fill static_aux_map
+  for (Tsubstmap::const_iterator it = astatic_aux_map.begin();
+       it != astatic_aux_map.end(); ++it)
+    static_aux_map.insert(Tsubstmap::value_type(static_atoms.get_name_storage().query((*it).first),
+                                                (*it).second));
+}
+
+MultInitSS::MultInitSS(const PlannerBuilder &pb, const Vector &pvals, Vector &yy)
+  : builder(pb), b(builder.diff_b_static.nrows()),
+    F(builder.diff_f_static.dim1(), builder.diff_f_static.dim2())
+{
+  b.zeros();
+  F.zeros();
+
+  // first evaluate substitutions (auxiliary variables) from the builder
+  ogdyn::DynareStaticSteadySubstitutions dss(builder.model.atoms, builder.static_atoms,
+                                             builder.static_tree,
+                                             builder.static_aux_map, pvals, yy);
+
+  // gather all the terms from builder.diff_b_static and
+  // builder.diff_f_static to the vector, the ordering is important,
+  // since the index of this vector will have to be decoded to the
+  // position in b and F.
+  vector<int> terms;
+  for (int yi = 0; yi < builder.diff_b_static.nrows(); yi++)
+    for (int l = 0; l < builder.diff_b_static.ncols(); l++)
+      terms.push_back(builder.diff_b_static(yi, l));
+  for (int yi = 0; yi < builder.diff_f_static.dim1(); yi++)
+    for (int fi = 0; fi < builder.diff_f_static.dim2(); fi++)
+      for (int l = 0; l < builder.diff_f_static.dim3(); l++)
+        terms.push_back(builder.diff_f_static(yi, fi, l));
+
+  // evaluate the terms, it will call a series of load(i,res), which
+  // sum the results through lags/leads to b and F
+  DynareStaticSteadyAtomValues dssav(builder.model.atoms, builder.static_atoms, pvals, yy);
+  ogp::FormulaCustomEvaluator fe(builder.static_tree, terms);
+  fe.eval(dssav, *this);
+
+  // solve overdetermined system b+F*lambda=0 using SVD decomposition
+  SVDDecomp decomp(F);
+  Vector lambda(builder.diff_f_static.dim2());
+  decomp.solve(b, lambda);
+  lambda.mult(-1);
+
+  // take values of lambda and put it to yy
+  for (int fi = 0; fi < builder.diff_f_static.dim2(); fi++)
+    {
+      char mult_name[100];
+      sprintf(mult_name, "MULT%d", builder.fset[fi]);
+      int iouter = builder.model.atoms.name2outer_endo(mult_name);
+      int iy = builder.model.atoms.outer2y_endo()[iouter];
+      if (!std::isfinite(yy[iy]))
+        yy[iy] = lambda[fi];
+
+      // go through all substitutions of the multiplier and set them
+      // as well
+      if (builder.model.atom_substs)
+        {
+          const ogp::AtomSubstitutions::Toldnamemap &old2new
+            = builder.model.atom_substs->get_old2new();
+          const ogp::AtomSubstitutions::Toldnamemap::const_iterator it
+            = old2new.find(mult_name);
+          if (it != old2new.end())
+            {
+              const ogp::AtomSubstitutions::Tshiftnameset &sset = (*it).second;
+              for (ogp::AtomSubstitutions::Tshiftnameset::const_iterator itt = sset.begin();
+                   itt != sset.end(); ++itt)
+                {
+                  const char *newname = (*itt).first;
+                  int iouter = builder.model.atoms.name2outer_endo(newname);
+                  int iy = builder.model.atoms.outer2y_endo()[iouter];
+                  if (!std::isfinite(yy[iy]))
+                    yy[iy] = lambda[fi];
+                }
+            }
+        }
+    }
+}
+
+void
+MultInitSS::load(int i, double res)
+{
+  // we can afford it, since the evaluator sets res to exact zero if
+  // the term is zero
+  if (res == 0)
+    return;
+  // decode i and add to either b or F
+  if (i < builder.diff_b_static.nrows()*builder.diff_b_static.ncols())
+    {
+      // add to b
+      b[i / builder.diff_b_static.ncols()] += res;
+    }
+  else
+    {
+      // add to F
+      i -= builder.diff_b_static.nrows()*builder.diff_b_static.ncols();
+      int yifi = i / builder.diff_f_static.dim3();
+      int yi = yifi / builder.diff_f_static.dim2();
+      int fi = yifi % builder.diff_f_static.dim2();
+      F.get(yi, fi) += res;
+    }
+}
diff --git a/dynare++/src/planner_builder.cpp b/dynare++/src/planner_builder.cpp
deleted file mode 100644
index 6958a8ab62d3f46b3e3733ff065f16ba09402519..0000000000000000000000000000000000000000
--- a/dynare++/src/planner_builder.cpp
+++ /dev/null
@@ -1,385 +0,0 @@
-// Copyright (C) 2006, Ondra Kamenik
-
-// $Id$
-
-#include "planner_builder.h"
-#include "dynare_exception.h"
-
-#include <cmath>
-
-using namespace ogdyn;
-
-const IntegerMatrix& IntegerMatrix::operator=(const IntegerMatrix& im)
-{
-	if (nr != im.nr || nc != im.nc)
-		throw DynareException(__FILE__,__LINE__,
-							  "Matrices have different dimensions in IntegerMatrix::operator=");
-	memcpy(data, im.data, nr*nc*sizeof(int));
-	return *this;
-}
-
-const IntegerArray3& IntegerArray3::operator=(const IntegerArray3& ia3)
-{
-	if (n1 != ia3.n1 || n2 != ia3.n2 || n3 != ia3.n3)
-		throw DynareException(__FILE__,__LINE__,
-							  "Arrays have different dimensions in IntegerArray3::operator=");
-	memcpy(data, ia3.data, n1*n2*n3*sizeof(int));
-	return *this;
-}
-
-
-PlannerBuilder::PlannerBuilder(DynareModel& m, const Tvarset& yyset,
-							   const Teqset& ffset)
-	: yset(), fset(ffset), model(m),
-	  tb(model.t_plobjective), tbeta(model.t_pldiscount),
-	  maxlead(model.atoms.get_maxlead()),
-	  minlag(model.atoms.get_minlag()),
-	  diff_b(yyset.size(), 1-minlag),
-	  diff_f(yyset.size(), fset.size(), 1+maxlead-minlag),
-	  static_atoms(),
-	  static_tree(),
-	  diff_b_static(yyset.size(), 1-minlag),
-	  diff_f_static(yyset.size(), fset.size(), 1+maxlead-minlag)
-{
-	info.num_new_terms -= model.getParser().getTree().get_num_op();
-
-	fill_yset(m.atoms.get_name_storage(), yyset);
-
-	add_derivatives_of_b();
-	add_derivatives_of_f();
-	shift_derivatives_of_b();
-	shift_derivatives_of_f();
-	beta_multiply_b();
-	beta_multiply_f();
-	make_static_version();
-	lagrange_mult_f();
-	form_equations();
-
-	info.num_new_terms += model.getParser().getTree().get_num_op();
-}
-
-PlannerBuilder::PlannerBuilder(const PlannerBuilder& pb, ogdyn::DynareModel& m)
-	: yset(), fset(pb.fset), model(m),
-	  tb(pb.tb), tbeta(pb.tbeta),
-	  maxlead(pb.maxlead), minlag(pb.minlag),
-	  diff_b(pb.diff_b), diff_f(pb.diff_f),
-	  static_atoms(pb.static_atoms),
-	  static_tree(pb.static_tree),
-	  diff_b_static(pb.diff_b_static),
-	  diff_f_static(pb.diff_f_static),
-	  aux_map(), static_aux_map()
-	
-{
-	fill_yset(m.atoms.get_name_storage(), pb.yset);
-	fill_aux_map(m.atoms.get_name_storage(), pb.aux_map, pb.static_aux_map);
-}
-
-void PlannerBuilder::add_derivatives_of_b()
-{
-	int yi = 0;
-	for (Tvarset::const_iterator yname = yset.begin();
-		 yname != yset.end(); ++yname, yi++)
-		for (int ll = minlag; ll <= 0; ll++) {
-			int yt = model.atoms.index(*yname, ll);
-			if (yt != -1)
-				diff_b(yi, ll-minlag) = model.eqs.add_derivative(tb, yt);
-			else
-				diff_b(yi, ll-minlag) = ogp::OperationTree::zero;
-		}
-}
-
-void PlannerBuilder::add_derivatives_of_f()
-{
-	int yi = 0;
-	for (Tvarset::const_iterator yname = yset.begin();
-		 yname != yset.end(); ++yname, yi++)
-		for (unsigned int fi = 0; fi < fset.size(); fi++)
-			for (int ll = minlag; ll <= maxlead; ll++) {
-				int yt = model.atoms.index(*yname, ll);
-				if (yt != -1)
-					diff_f(yi, fi, ll-minlag) =
-						model.eqs.add_derivative(model.eqs.formula(fset[fi]), yt);
-				else
-					diff_f(yi, fi, ll-minlag) = ogp::OperationTree::zero;
-			}
-}
-
-void PlannerBuilder::shift_derivatives_of_b()
-{
-	map<int,int> subst;
-	for (int yi = 0; yi < diff_b.nrows(); yi++)
-		for (int ll = minlag; ll < 0; ll++)
-			if (diff_b(yi, ll-minlag) != ogp::OperationTree::zero) {
-				model.variable_shift_map(model.eqs.nulary_of_term(diff_b(yi, ll-minlag)),
-										 -ll, subst);
-				diff_b(yi, ll-minlag) = model.eqs.add_substitution(diff_b(yi, ll-minlag), subst);
-			}
-}
-
-void PlannerBuilder::shift_derivatives_of_f()
-{
-	map<int,int> subst;
-	for (int yi = 0; yi < diff_f.dim1(); yi++)
-		for (int fi = 0; fi < diff_f.dim2(); fi++) {
-			// first do it leads which are put under expectation before t: no problem
-			for (int ll = 0; ll <= maxlead; ll++)
-				if (diff_f(yi, fi, ll-minlag) != ogp::OperationTree::zero) {
-					model.variable_shift_map(model.eqs.nulary_of_term(diff_f(yi, fi, ll-minlag)),
-											 -ll, subst);
-					diff_f(yi, fi, ll-minlag) =
-						model.eqs.add_substitution(diff_f(yi, fi, ll-minlag), subst);
-				}
-			// now do it for lags, these are put as leads under
-			// expectations after time t, so we have to introduce
-			// auxiliary variables at time t, and make leads of them here
-			for (int ll = minlag; ll < 0; ll++) {
-				int ft = diff_f(yi, fi, ll-minlag);
-				if (ft != ogp::OperationTree::zero) {
-					// if the ft term has a lead, than we need to
-					// introduce an auxiliary variable z_t, define it
-					// as E_t[ft] and put z_{t-ll} to the
-					// equation. Otherwise, we just put leaded ft to
-					// the equation directly.
-					int ft_maxlead, ft_minlag;
-					model.termspan(ft, ft_maxlead, ft_minlag);
-					if (ft_maxlead > 0) {
-						// make an auxiliary variable
-						char name[100];
-						sprintf(name, "AUX_%d_%d_%d", yi, fset[fi], -ll);
-						model.atoms.register_uniq_endo(name);
-						info.num_aux_variables++;
-						int taux = model.eqs.add_nulary(name);
-						sprintf(name, "AUX_%d_%d_%d(%d)", yi, fset[fi], -ll, -ll);
-						int taux_leaded = model.eqs.add_nulary(name);
-						// put aux_leaded to the equation
-						diff_f(yi, fi, ll-minlag) = taux_leaded;
-						// save auxiliary variable and the term
-						aux_map.insert(Tsubstmap::value_type(model.atoms.name(taux), ft));
-					} else {
-						// no auxiliary variable is needed and the
-						// term ft can be leaded in place
-						model.variable_shift_map(model.eqs.nulary_of_term(ft), -ll, subst);
-						diff_f(yi, fi, ll-minlag) =
-							model.eqs.add_substitution(ft, subst);
-					}
-				}
-			}
-		}
-}
-
-void PlannerBuilder::beta_multiply_b()
-{
-	int beta_pow = ogp::OperationTree::one;
-	for (int ll = 0; ll >= minlag; ll--,
-			 beta_pow = model.eqs.add_binary(ogp::TIMES, beta_pow, tbeta))
-		for (int yi = 0; yi < diff_b.nrows(); yi++)
-			if (diff_b(yi, ll-minlag) != ogp::OperationTree::zero)
-				diff_b(yi, ll-minlag) =
-					model.eqs.add_binary(ogp::TIMES, beta_pow, diff_b(yi, ll-minlag));
-}
-
-void PlannerBuilder::beta_multiply_f()
-{
-	int beta_pow = ogp::OperationTree::one;
-	for (int ll = 0; ll <= maxlead; ll++,
-			 beta_pow = model.eqs.add_binary(ogp::DIVIDE, beta_pow, tbeta))
-		for (int yi = 0; yi < diff_f.dim1(); yi++)
-			for (int fi = 0; fi < diff_f.dim2(); fi++)
-				if (diff_f(yi, fi, ll-minlag) != ogp::OperationTree::zero)
-					diff_f(yi, fi, ll-minlag) =
-						model.eqs.add_binary(ogp::TIMES, beta_pow, diff_f(yi, fi, ll-minlag));
-
-	beta_pow = ogp::OperationTree::one;
-	for (int ll = 0; ll >= minlag; ll--,
-			 beta_pow = model.eqs.add_binary(ogp::TIMES, beta_pow, tbeta))
-		for (int yi = 0; yi < diff_f.dim1(); yi++)
-			for (int fi = 0; fi < diff_f.dim2(); fi++)
-				if (diff_f(yi, fi, ll-minlag) != ogp::OperationTree::zero)
-					diff_f(yi, fi, ll-minlag) =
-						model.eqs.add_binary(ogp::TIMES, beta_pow, diff_f(yi, fi, ll-minlag));
-}
-
-void PlannerBuilder::make_static_version()
-{
-	// map holding substitutions from dynamic to static
-	ogp::StaticFineAtoms::Tintintmap tmap;
-
-	// fill static atoms with outer ordering
-	static_atoms.import_atoms(model.atoms, static_tree, tmap);
-
-	// go through diff_b and fill diff_b_static
-	for (int ll = minlag; ll <= 0; ll++)
-		for (int yi = 0; yi < diff_b.nrows(); yi++)
-			diff_b_static(yi, ll-minlag) =
-				static_tree.add_substitution(diff_b(yi, ll-minlag),
-											 tmap,  model.eqs.getTree());
-
-	// go through diff_f and fill diff_f_static
-	for (int ll = minlag; ll <= maxlead; ll++)
-		for (int yi = 0; yi < diff_f.dim1(); yi++)
-			for (int fi = 0; fi < diff_f.dim2(); fi++)
-				diff_f_static(yi, fi, ll-minlag) =
-					static_tree.add_substitution(diff_f(yi, fi, ll-minlag),
-												 tmap, model.eqs.getTree());
-
-	// go through aux_map and fill static_aux_map
-	for (Tsubstmap::const_iterator it = aux_map.begin();
-		 it != aux_map.end(); ++it) {
-		int tstatic = static_tree.add_substitution((*it).second, tmap, model.eqs.getTree());
-		const char* name = static_atoms.get_name_storage().query((*it).first);
-		static_aux_map.insert(Tsubstmap::value_type(name, tstatic));
-	}
-}
-
-
-void PlannerBuilder::lagrange_mult_f()
-{
-	// register multipliers
-	char mult_name[100];
-	for (int fi = 0; fi < diff_f.dim2(); fi++) {	
-		sprintf(mult_name, "MULT%d", fset[fi]);
-		model.atoms.register_uniq_endo(mult_name);
-		info.num_lagrange_mults++;
-	}
-	// multiply with the multipliers
-	for (int yi = 0; yi < diff_f.dim1(); yi++)
-		for (int fi = 0; fi < diff_f.dim2(); fi++)
-			for (int ll = minlag; ll <= maxlead; ll++)
-				if (diff_f(yi, fi, ll-minlag) != ogp::OperationTree::zero) {
-					sprintf(mult_name, "MULT%d(%d)", fset[fi], -ll);
-					int tm = model.eqs.add_nulary(mult_name);
-					diff_f(yi, fi, ll-minlag) =
-						model.eqs.add_binary(ogp::TIMES, tm, diff_f(yi, fi, ll-minlag));
-				}
-}
-
-void PlannerBuilder::form_equations()
-{
-	// add planner's FOCs
-	for (int yi = 0; yi < diff_f.dim1(); yi++) {
-		int eq = ogp::OperationTree::zero;
-		for (int ll = minlag; ll <= 0; ll++)
-			eq = model.eqs.add_binary(ogp::PLUS, eq, diff_b(yi, ll-minlag));
-		for (int fi = 0; fi < diff_f.dim2(); fi++)
-			for (int ll = minlag; ll <= maxlead; ll++)
-				eq = model.eqs.add_binary(ogp::PLUS, eq, diff_f(yi, fi, ll-minlag));
-		model.eqs.add_formula(eq);
-	}
-
-	// add equations for auxiliary variables
-	for (Tsubstmap::const_iterator it = aux_map.begin();
-		 it != aux_map.end(); ++it) {
-		int t = model.atoms.index((*it).first, 0);
-		model.eqs.add_formula(model.eqs.add_binary(ogp::MINUS, t, (*it).second));
-	}
-}
-
-void PlannerBuilder::fill_yset(const ogp::NameStorage& ns,
-							   const PlannerBuilder::Tvarset& yyset)
-{
-	for (Tvarset::const_iterator it = yyset.begin(); it != yyset.end(); ++it)
-		yset.insert(ns.query(*it));
-}
-
-void PlannerBuilder::fill_aux_map(const ogp::NameStorage& ns, const Tsubstmap& aaux_map,
-								  const Tsubstmap& astatic_aux_map)
-{
-	// fill aux_map
-	for (Tsubstmap::const_iterator it = aaux_map.begin();
-		 it != aaux_map.end(); ++it)
-		aux_map.insert(Tsubstmap::value_type(ns.query((*it).first), (*it).second));
-
-	// fill static_aux_map
-	for (Tsubstmap::const_iterator it = astatic_aux_map.begin();
-		 it != astatic_aux_map.end(); ++it)
-		static_aux_map.insert(Tsubstmap::value_type(static_atoms.get_name_storage().query((*it).first),
-													(*it).second));
-}
-
-MultInitSS::MultInitSS(const PlannerBuilder& pb, const Vector& pvals, Vector& yy)
-	: builder(pb), b(builder.diff_b_static.nrows()),
-	  F(builder.diff_f_static.dim1(), builder.diff_f_static.dim2())
-{
-	b.zeros();
-	F.zeros();
-
-	// first evaluate substitutions (auxiliary variables) from the builder
-	ogdyn::DynareStaticSteadySubstitutions dss(builder.model.atoms, builder.static_atoms,
-											   builder.static_tree,
-											   builder.static_aux_map, pvals, yy);
-
-	// gather all the terms from builder.diff_b_static and
-	// builder.diff_f_static to the vector, the ordering is important,
-	// since the index of this vector will have to be decoded to the
-	// position in b and F.
-	vector<int> terms;
-	for (int yi = 0; yi < builder.diff_b_static.nrows(); yi++)
-		for (int l = 0; l < builder.diff_b_static.ncols(); l++)
-			terms.push_back(builder.diff_b_static(yi, l));
-	for (int yi = 0; yi < builder.diff_f_static.dim1(); yi++)
-		for (int fi = 0; fi < builder.diff_f_static.dim2(); fi++)
-			for (int l = 0; l < builder.diff_f_static.dim3(); l++)
-				terms.push_back(builder.diff_f_static(yi, fi, l));
-
-	// evaluate the terms, it will call a series of load(i,res), which
-	// sum the results through lags/leads to b and F
-	DynareStaticSteadyAtomValues dssav(builder.model.atoms, builder.static_atoms, pvals, yy);
-	ogp::FormulaCustomEvaluator fe(builder.static_tree, terms);
-	fe.eval(dssav, *this);
-
-	// solve overdetermined system b+F*lambda=0 using SVD decomposition
-    SVDDecomp decomp(F);
-    Vector lambda(builder.diff_f_static.dim2());
-    decomp.solve(b, lambda);
-    lambda.mult(-1);
-
-	// take values of lambda and put it to yy
-	for (int fi = 0; fi < builder.diff_f_static.dim2(); fi++) {
-		char mult_name[100];
-		sprintf(mult_name, "MULT%d", builder.fset[fi]);
-		int iouter = builder.model.atoms.name2outer_endo(mult_name);
-		int iy = builder.model.atoms.outer2y_endo()[iouter];
-		if (! std::isfinite(yy[iy]))
-			yy[iy] = lambda[fi];
-
-		// go through all substitutions of the multiplier and set them
-		// as well
-		if (builder.model.atom_substs) {
-			const ogp::AtomSubstitutions::Toldnamemap& old2new =
-				builder.model.atom_substs->get_old2new();
-			const ogp::AtomSubstitutions::Toldnamemap::const_iterator it =
-				old2new.find(mult_name);
-			if (it != old2new.end()) {
-				const ogp::AtomSubstitutions::Tshiftnameset& sset = (*it).second;
-				for (ogp::AtomSubstitutions::Tshiftnameset::const_iterator itt = sset.begin();
-					 itt != sset.end(); ++itt) {
-					const char* newname = (*itt).first;
-					int iouter = builder.model.atoms.name2outer_endo(newname);
-					int iy = builder.model.atoms.outer2y_endo()[iouter];
-					if (! std::isfinite(yy[iy]))
-						yy[iy] = lambda[fi];
-				}
-			}
-		}
-	}
-}
-
-void MultInitSS::load(int i, double res)
-{
-	// we can afford it, since the evaluator sets res to exact zero if
-	// the term is zero
-	if (res == 0)
-		return;
-	// decode i and add to either b or F 
-	if (i < builder.diff_b_static.nrows()*builder.diff_b_static.ncols()) {
-		// add to b
-		b[i / builder.diff_b_static.ncols()] += res;
-	} else {
-		// add to F
-		i -= builder.diff_b_static.nrows()*builder.diff_b_static.ncols();
-		int yifi = i / builder.diff_f_static.dim3();
-		int yi = yifi / builder.diff_f_static.dim2();
-		int fi = yifi % builder.diff_f_static.dim2();
-		F.get(yi, fi) += res;
-	}
-}
diff --git a/dynare++/src/planner_builder.h b/dynare++/src/planner_builder.hh
similarity index 99%
rename from dynare++/src/planner_builder.h
rename to dynare++/src/planner_builder.hh
index 4d888d9051c300706761f879890de059d623ed14..b62b76a1eb55313893e1adae50ad979408d0450d 100644
--- a/dynare++/src/planner_builder.h
+++ b/dynare++/src/planner_builder.hh
@@ -3,7 +3,7 @@
 #ifndef PLANNER_BUILDER_H
 #define PLANNER_BUILDER_H
 
-#include "dynare_model.h"
+#include "dynare_model.hh"
 
 namespace ogdyn
 {
diff --git a/dynare++/sylv/cc/BlockDiagonal.cc b/dynare++/sylv/cc/BlockDiagonal.cc
new file mode 100644
index 0000000000000000000000000000000000000000..daf7a38302e49df06280aa60646e4088bcd44ab8
--- /dev/null
+++ b/dynare++/sylv/cc/BlockDiagonal.cc
@@ -0,0 +1,355 @@
+/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/BlockDiagonal.cpp,v 1.1.1.1 2004/06/04 13:00:20 kamenik Exp $ */
+
+/* Tag $Name:  $ */
+
+#include "BlockDiagonal.hh"
+
+#include <cstdio>
+#include <cstring>
+
+BlockDiagonal::BlockDiagonal(const double *d, int d_size)
+  : QuasiTriangular(d, d_size),
+    row_len(new int[d_size]), col_len(new int[d_size])
+{
+  for (int i = 0; i < d_size; i++)
+    {
+      row_len[i] = d_size;
+      col_len[i] = 0;
+    }
+}
+
+BlockDiagonal::BlockDiagonal(const QuasiTriangular &t)
+  : QuasiTriangular(t),
+    row_len(new int[t.numRows()]), col_len(new int[t.numRows()])
+{
+  for (int i = 0; i < t.numRows(); i++)
+    {
+      row_len[i] = t.numRows();
+      col_len[i] = 0;
+    }
+}
+
+BlockDiagonal::BlockDiagonal(int p, const BlockDiagonal &b)
+  : QuasiTriangular(p, b),
+    row_len(new int[b.numRows()]), col_len(new int[b.numRows()])
+{
+  memcpy(row_len, b.row_len, b.numRows()*sizeof(int));
+  memcpy(col_len, b.col_len, b.numRows()*sizeof(int));
+}
+
+BlockDiagonal::BlockDiagonal(const BlockDiagonal &b)
+  : QuasiTriangular(b),
+    row_len(new int[b.numRows()]), col_len(new int[b.numRows()])
+{
+  memcpy(row_len, b.row_len, b.numRows()*sizeof(int));
+  memcpy(col_len, b.col_len, b.numRows()*sizeof(int));
+}
+
+/* put zeroes to right upper submatrix whose first column is defined
+ * by 'edge' */
+void
+BlockDiagonal::setZerosToRU(diag_iter edge)
+{
+  int iedge = (*edge).getIndex();
+  for (int i = 0; i < iedge; i++)
+    for (int j = iedge; j < numCols(); j++)
+      get(i, j) = 0.0;
+}
+
+/* Updates row_len and col_len so that there are zeroes in upper right part, this
+ * |T1 0 |
+ * |0  T2|. The first column of T2 is given by diagonal iterator 'edge'.
+
+ * Note the semantics of row_len and col_len. row_len[i] is distance
+ * of the right-most non-zero element of i-th row from the left, and
+ * col_len[j] is distance of top-most non-zero element of j-th column
+ * to the top. (First element has distance 1).
+ */
+void
+BlockDiagonal::setZeroBlockEdge(diag_iter edge)
+{
+  setZerosToRU(edge);
+
+  int iedge = (*edge).getIndex();
+  for (diag_iter run = diag_begin(); run != edge; ++run)
+    {
+      int ind = (*run).getIndex();
+      if (row_len[ind] > iedge)
+        {
+          row_len[ind] = iedge;
+          if (!(*run).isReal())
+            row_len[ind+1] = iedge;
+        }
+    }
+  for (diag_iter run = edge; run != diag_end(); ++run)
+    {
+      int ind = (*run).getIndex();
+      if (col_len[ind] < iedge)
+        {
+          col_len[ind] = iedge;
+          if (!(*run).isReal())
+            col_len[ind+1] = iedge;
+        }
+    }
+}
+
+BlockDiagonal::const_col_iter
+BlockDiagonal::col_begin(const DiagonalBlock &b) const
+{
+  int jbar = b.getIndex();
+  int d_size = diagonal.getSize();
+  return const_col_iter(&getData()[jbar*d_size + col_len[jbar]], d_size,
+                        b.isReal(), col_len[jbar]);
+}
+
+BlockDiagonal::col_iter
+BlockDiagonal::col_begin(const DiagonalBlock &b)
+{
+  int jbar = b.getIndex();
+  int d_size = diagonal.getSize();
+  return col_iter(&getData()[jbar*d_size + col_len[jbar]], d_size,
+                  b.isReal(), col_len[jbar]);
+}
+
+BlockDiagonal::const_row_iter
+BlockDiagonal::row_end(const DiagonalBlock &b) const
+{
+  int jbar = b.getIndex();
+  int d_size = diagonal.getSize();
+  return const_row_iter(&getData()[d_size*row_len[jbar]+jbar], d_size,
+                        b.isReal(), row_len[jbar]);
+}
+
+BlockDiagonal::row_iter
+BlockDiagonal::row_end(const DiagonalBlock &b)
+{
+  int jbar = b.getIndex();
+  int d_size = diagonal.getSize();
+  return row_iter(&getData()[d_size*row_len[jbar]+jbar], d_size,
+                  b.isReal(), row_len[jbar]);
+}
+
+int
+BlockDiagonal::getNumZeros() const
+{
+  int sum = 0;
+  for (int i = 0; i < diagonal.getSize(); i++)
+    {
+      sum += diagonal.getSize() - row_len[i];
+    }
+  return sum;
+}
+
+QuasiTriangular::const_diag_iter
+BlockDiagonal::findBlockStart(const_diag_iter from) const
+{
+  if (from != diag_end())
+    {
+      ++from;
+      while (from != diag_end()
+             && col_len[(*from).getIndex()] != (*from).getIndex())
+        ++from;
+    }
+  return from;
+}
+
+int
+BlockDiagonal::getLargestBlock() const
+{
+  int largest = 0;
+  const_diag_iter start = diag_begin();
+  const_diag_iter end = findBlockStart(start);
+  while (start != diag_end())
+    {
+      int si = (*start).getIndex();
+      int ei = diagonal.getSize();
+      if (end != diag_end())
+        ei = (*end).getIndex();
+      if (largest < ei-si)
+        largest = ei-si;
+      start = end;
+      end = findBlockStart(start);
+    }
+  return largest;
+}
+
+void
+BlockDiagonal::savePartOfX(int si, int ei, const KronVector &x, Vector &work)
+{
+  for (int i = si; i < ei; i++)
+    {
+      ConstKronVector xi(x, i);
+      Vector target(work, (i-si)*xi.length(), xi.length());
+      target = xi;
+    }
+}
+
+void
+BlockDiagonal::multKronBlock(const_diag_iter start, const_diag_iter end,
+                             KronVector &x, Vector &work) const
+{
+  int si = (*start).getIndex();
+  int ei = diagonal.getSize();
+  if (end != diag_end())
+    ei = (*end).getIndex();
+  savePartOfX(si, ei, x, work);
+
+  for (const_diag_iter di = start; di != end; ++di)
+    {
+      int jbar = (*di).getIndex();
+      if ((*di).isReal())
+        {
+          KronVector xi(x, jbar);
+          xi.zeros();
+          Vector wi(work, (jbar-si)*xi.length(), xi.length());
+          xi.add(*((*di).getAlpha()), wi);
+          for (const_row_iter ri = row_begin(*di); ri != row_end(*di); ++ri)
+            {
+              int col = ri.getCol();
+              Vector wj(work, (col-si)*xi.length(), xi.length());
+              xi.add(*ri, wj);
+            }
+        }
+      else
+        {
+          KronVector xi(x, jbar);
+          KronVector xii(x, jbar+1);
+          xi.zeros();
+          xii.zeros();
+          Vector wi(work, (jbar-si)*xi.length(), xi.length());
+          Vector wii(work, (jbar+1-si)*xi.length(), xi.length());
+          xi.add(*((*di).getAlpha()), wi);
+          xi.add((*di).getBeta1(), wii);
+          xii.add((*di).getBeta2(), wi);
+          xii.add(*((*di).getAlpha()), wii);
+          for (const_row_iter ri = row_begin(*di); ri != row_end(*di); ++ri)
+            {
+              int col = ri.getCol();
+              Vector wj(work, (col-si)*xi.length(), xi.length());
+              xi.add(ri.a(), wj);
+              xii.add(ri.b(), wj);
+            }
+        }
+    }
+}
+
+void
+BlockDiagonal::multKronBlockTrans(const_diag_iter start, const_diag_iter end,
+                                  KronVector &x, Vector &work) const
+{
+  int si = (*start).getIndex();
+  int ei = diagonal.getSize();
+  if (end != diag_end())
+    ei = (*end).getIndex();
+  savePartOfX(si, ei, x, work);
+
+  for (const_diag_iter di = start; di != end; ++di)
+    {
+      int jbar = (*di).getIndex();
+      if ((*di).isReal())
+        {
+          KronVector xi(x, jbar);
+          xi.zeros();
+          Vector wi(work, (jbar-si)*xi.length(), xi.length());
+          xi.add(*((*di).getAlpha()), wi);
+          for (const_col_iter ci = col_begin(*di); ci != col_end(*di); ++ci)
+            {
+              int row = ci.getRow();
+              Vector wj(work, (row-si)*xi.length(), xi.length());
+              xi.add(*ci, wj);
+            }
+        }
+      else
+        {
+          KronVector xi(x, jbar);
+          KronVector xii(x, jbar+1);
+          xi.zeros();
+          xii.zeros();
+          Vector wi(work, (jbar-si)*xi.length(), xi.length());
+          Vector wii(work, (jbar+1-si)*xi.length(), xi.length());
+          xi.add(*((*di).getAlpha()), wi);
+          xi.add((*di).getBeta2(), wii);
+          xii.add((*di).getBeta1(), wi);
+          xii.add(*((*di).getAlpha()), wii);
+          for (const_col_iter ci = col_begin(*di); ci != col_end(*di); ++ci)
+            {
+              int row = ci.getRow();
+              Vector wj(work, (row-si)*xi.length(), xi.length());
+              xi.add(ci.a(), wj);
+              xii.add(ci.b(), wj);
+            }
+        }
+    }
+}
+
+void
+BlockDiagonal::multKron(KronVector &x) const
+{
+  int largest = getLargestBlock();
+  Vector work(largest *x.getN()*power(x.getM(), x.getDepth()-1));
+  const_diag_iter start = diag_begin();
+  const_diag_iter end = findBlockStart(start);
+  while (start != diag_end())
+    {
+      multKronBlock(start, end, x, work);
+      start = end;
+      end = findBlockStart(start);
+    }
+}
+
+void
+BlockDiagonal::multKronTrans(KronVector &x) const
+{
+  int largest = getLargestBlock();
+  Vector work(largest *x.getN()*power(x.getM(), x.getDepth()-1));
+  const_diag_iter start = diag_begin();
+  const_diag_iter end = findBlockStart(start);
+  while (start != diag_end())
+    {
+      multKronBlockTrans(start, end, x, work);
+      start = end;
+      end = findBlockStart(start);
+    }
+}
+
+void
+BlockDiagonal::printInfo() const
+{
+  printf("Block sizes:");
+  int num_blocks = 0;
+  const_diag_iter start = diag_begin();
+  const_diag_iter end = findBlockStart(start);
+  while (start != diag_end())
+    {
+      int si = (*start).getIndex();
+      int ei = diagonal.getSize();
+      if (end != diag_end())
+        ei = (*end).getIndex();
+      printf(" %d", ei-si);
+      num_blocks++;
+      start = end;
+      end = findBlockStart(start);
+    }
+  printf("\nNum blocks: %d\n", num_blocks);
+  printf("There are %d zeros out of %d\n",
+         getNumZeros(), getNumOffdiagonal());
+}
+
+int
+BlockDiagonal::getNumBlocks() const
+{
+  int num_blocks = 0;
+  const_diag_iter start = diag_begin();
+  const_diag_iter end = findBlockStart(start);
+  while (start != diag_end())
+    {
+      num_blocks++;
+      start = end;
+      end = findBlockStart(start);
+    }
+  return num_blocks;
+}
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/dynare++/sylv/cc/BlockDiagonal.cpp b/dynare++/sylv/cc/BlockDiagonal.cpp
deleted file mode 100644
index ea461dc4a15276c1ae6d2b893ed1317e0a3d2b37..0000000000000000000000000000000000000000
--- a/dynare++/sylv/cc/BlockDiagonal.cpp
+++ /dev/null
@@ -1,321 +0,0 @@
-/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/BlockDiagonal.cpp,v 1.1.1.1 2004/06/04 13:00:20 kamenik Exp $ */
-
-/* Tag $Name:  $ */
-
-#include "BlockDiagonal.h"
-
-#include <cstdio>
-#include <cstring>
-
-BlockDiagonal::BlockDiagonal(const double* d, int d_size)
-	: QuasiTriangular(d, d_size),
-	  row_len(new int[d_size]), col_len(new int[d_size])
-{
-	for (int i = 0; i < d_size; i++) {
-		row_len[i] = d_size;
-		col_len[i] = 0;
-	}
-}
-
-BlockDiagonal::BlockDiagonal(const QuasiTriangular& t)
-	: QuasiTriangular(t),
-	  row_len(new int[t.numRows()]), col_len(new int[t.numRows()])
-{
-	for (int i = 0; i < t.numRows(); i++) {
-		row_len[i] = t.numRows();
-		col_len[i] = 0;
-	}
-}
-
-BlockDiagonal::BlockDiagonal(int p, const BlockDiagonal& b)
-	: QuasiTriangular(p, b),
-	  row_len(new int[b.numRows()]), col_len(new int[b.numRows()])
-{
-	memcpy(row_len, b.row_len, b.numRows()*sizeof(int));
-	memcpy(col_len, b.col_len, b.numRows()*sizeof(int));
-}
-
-BlockDiagonal::BlockDiagonal(const BlockDiagonal& b)
-	: QuasiTriangular(b),
-	  row_len(new int[b.numRows()]), col_len(new int[b.numRows()])
-{
-	memcpy(row_len, b.row_len, b.numRows()*sizeof(int));
-	memcpy(col_len, b.col_len, b.numRows()*sizeof(int));
-}
-
-/* put zeroes to right upper submatrix whose first column is defined
- * by 'edge' */
-void BlockDiagonal::setZerosToRU(diag_iter edge)
-{
-	int iedge = (*edge).getIndex();
-	for (int i = 0; i < iedge; i++)
-		for (int j = iedge; j < numCols(); j++)
-			get(i,j) = 0.0;
-}
-
-/* Updates row_len and col_len so that there are zeroes in upper right part, this
- * |T1 0 |
- * |0  T2|. The first column of T2 is given by diagonal iterator 'edge'.
-
- * Note the semantics of row_len and col_len. row_len[i] is distance
- * of the right-most non-zero element of i-th row from the left, and
- * col_len[j] is distance of top-most non-zero element of j-th column
- * to the top. (First element has distance 1).
- */
-void BlockDiagonal::setZeroBlockEdge(diag_iter edge)
-{
-	setZerosToRU(edge);
-
-	int iedge = (*edge).getIndex();
-	for (diag_iter run = diag_begin(); run != edge; ++run) {
-		int ind = (*run).getIndex();
-		if (row_len[ind] > iedge) {
-			row_len[ind] = iedge;
-			if (!(*run).isReal())
-				row_len[ind+1] = iedge;
-		} 
-	}
-	for (diag_iter run = edge; run != diag_end(); ++run) {
-		int ind = (*run).getIndex();
-		if (col_len[ind] < iedge) {
-			col_len[ind] = iedge;
-			if (!(*run).isReal())
-				col_len[ind+1] = iedge;
-		}
-	}
-}
-
-BlockDiagonal::const_col_iter
-BlockDiagonal::col_begin(const DiagonalBlock& b) const
-{
-	int jbar = b.getIndex();
-	int d_size = diagonal.getSize();
-	return const_col_iter(&getData()[jbar*d_size + col_len[jbar]], d_size,
-						  b.isReal(), col_len[jbar]);
-}
-
-BlockDiagonal::col_iter
-BlockDiagonal::col_begin(const DiagonalBlock& b)
-{
-	int jbar = b.getIndex();
-	int d_size = diagonal.getSize();
-	return col_iter(&getData()[jbar*d_size + col_len[jbar]], d_size,
-					b.isReal(), col_len[jbar]);
-}
-
-
-BlockDiagonal::const_row_iter
-BlockDiagonal::row_end(const DiagonalBlock& b) const
-{
-	int jbar = b.getIndex();
-	int d_size = diagonal.getSize();
-	return const_row_iter(&getData()[d_size*row_len[jbar]+jbar], d_size,
-						  b.isReal(), row_len[jbar]);
-}
-
-BlockDiagonal::row_iter
-BlockDiagonal::row_end(const DiagonalBlock& b)
-{
-	int jbar = b.getIndex();
-	int d_size = diagonal.getSize();
-	return row_iter(&getData()[d_size*row_len[jbar]+jbar], d_size,
-					b.isReal(), row_len[jbar]);
-}
-
-int BlockDiagonal::getNumZeros() const
-{
-	int sum = 0;
-	for (int i = 0; i < diagonal.getSize(); i++) {
-		sum += diagonal.getSize() - row_len[i];
-	}
-	return sum;
-}
-
-QuasiTriangular::const_diag_iter
-BlockDiagonal::findBlockStart(const_diag_iter from) const
-{
-	if (from != diag_end()) {
-		++from;
-		while (from != diag_end() &&
-			   col_len[(*from).getIndex()] != (*from).getIndex())
-			++from;
-	}
-	return from;
-}
-
-int BlockDiagonal::getLargestBlock() const
-{
-	int largest = 0;
-	const_diag_iter start = diag_begin();
-	const_diag_iter end = findBlockStart(start);
-	while (start != diag_end()) {
-		int si = (*start).getIndex();
-		int ei = diagonal.getSize();
-		if (end != diag_end())
-			ei = (*end).getIndex();
-		if (largest < ei-si)
-			largest = ei-si;
-		start = end;
-		end = findBlockStart(start);
-	}
-	return largest;
-}
-
-
-void BlockDiagonal::savePartOfX(int si, int ei, const KronVector& x, Vector& work)
-{
-	for (int i = si; i < ei; i++) {
-		ConstKronVector xi(x, i);
-		Vector target(work, (i-si)*xi.length(), xi.length());
-		target = xi;
-	}
-}
-
-void BlockDiagonal::multKronBlock(const_diag_iter start, const_diag_iter end,
-								  KronVector& x, Vector& work) const
-{
-	int si = (*start).getIndex();
-	int ei = diagonal.getSize();
-	if (end != diag_end())
-		ei = (*end).getIndex();
-	savePartOfX(si, ei, x, work);
-
-	for (const_diag_iter di = start; di != end; ++di) {
-		int jbar = (*di).getIndex();
-		if ((*di).isReal()) {
-			KronVector xi(x, jbar);
-			xi.zeros();
-			Vector wi(work, (jbar-si)*xi.length(), xi.length());
-			xi.add(*((*di).getAlpha()), wi);
-			for (const_row_iter ri = row_begin(*di); ri != row_end(*di); ++ri) {
-				int col = ri.getCol();
-				Vector wj(work, (col-si)*xi.length(), xi.length());
-				xi.add(*ri, wj);
-			}
-		} else {
-			KronVector xi(x, jbar);
-			KronVector xii(x, jbar+1);
-			xi.zeros();
-			xii.zeros();
-			Vector wi(work, (jbar-si)*xi.length(), xi.length());
-			Vector wii(work, (jbar+1-si)*xi.length(), xi.length());
-			xi.add(*((*di).getAlpha()), wi);
-			xi.add((*di).getBeta1(), wii);
-			xii.add((*di).getBeta2(), wi);
-			xii.add(*((*di).getAlpha()), wii);
-			for (const_row_iter ri = row_begin(*di); ri != row_end(*di); ++ri) {
-				int col = ri.getCol();
-				Vector wj(work, (col-si)*xi.length(), xi.length());
-				xi.add(ri.a(), wj);
-				xii.add(ri.b(), wj);
-			}
-		}
-	}
-}
-
-void BlockDiagonal::multKronBlockTrans(const_diag_iter start, const_diag_iter end,
-									   KronVector& x, Vector& work) const
-{
-	int si = (*start).getIndex();
-	int ei = diagonal.getSize();
-	if (end != diag_end())
-		ei = (*end).getIndex();
-	savePartOfX(si, ei, x, work);
-
-	for (const_diag_iter di = start; di != end; ++di) {
-		int jbar = (*di).getIndex();
-		if ((*di).isReal()) {
-			KronVector xi(x, jbar);
-			xi.zeros();
-			Vector wi(work, (jbar-si)*xi.length(), xi.length());
-			xi.add(*((*di).getAlpha()), wi);
-			for (const_col_iter ci = col_begin(*di); ci != col_end(*di); ++ci) {
-				int row = ci.getRow();
-				Vector wj(work, (row-si)*xi.length(), xi.length());
-				xi.add(*ci, wj);
-			}
-		} else {
-			KronVector xi(x, jbar);
-			KronVector xii(x, jbar+1);
-			xi.zeros();
-			xii.zeros();
-			Vector wi(work, (jbar-si)*xi.length(), xi.length());
-			Vector wii(work, (jbar+1-si)*xi.length(), xi.length());
-			xi.add(*((*di).getAlpha()), wi);
-			xi.add((*di).getBeta2(), wii);
-			xii.add((*di).getBeta1(), wi);
-			xii.add(*((*di).getAlpha()), wii);
-			for (const_col_iter ci = col_begin(*di); ci != col_end(*di); ++ci) {
-				int row = ci.getRow();
-				Vector wj(work, (row-si)*xi.length(), xi.length());
-				xi.add(ci.a(), wj);
-				xii.add(ci.b(), wj);
-			}
-		}
-	}
-}
-
-void BlockDiagonal::multKron(KronVector& x) const
-{
-	int largest = getLargestBlock();
-	Vector work(largest*x.getN()*power(x.getM(),x.getDepth()-1));
-	const_diag_iter start = diag_begin();
-	const_diag_iter end = findBlockStart(start);
-	while (start != diag_end()) {
-		multKronBlock(start, end, x, work);
-		start = end;
-		end = findBlockStart(start);
-	}
-}
-
-
-void BlockDiagonal::multKronTrans(KronVector& x) const
-{
-	int largest = getLargestBlock();
-	Vector work(largest*x.getN()*power(x.getM(),x.getDepth()-1));
-	const_diag_iter start = diag_begin();
-	const_diag_iter end = findBlockStart(start);
-	while (start != diag_end()) {
-		multKronBlockTrans(start, end, x, work);
-		start = end;
-		end = findBlockStart(start);
-	}
-}
-
-void BlockDiagonal::printInfo() const
-{
-	printf("Block sizes:");
-	int num_blocks = 0;
-	const_diag_iter start = diag_begin();
-	const_diag_iter end = findBlockStart(start);
-	while (start != diag_end()) {
-		int si = (*start).getIndex();
-		int ei = diagonal.getSize();
-		if (end != diag_end())
-			ei = (*end).getIndex();
-		printf(" %d", ei-si);
-		num_blocks++;
-		start = end;
-		end = findBlockStart(start);
-	}
-	printf("\nNum blocks: %d\n", num_blocks);
-	printf("There are %d zeros out of %d\n",
-		   getNumZeros(), getNumOffdiagonal());
-}
-
-int BlockDiagonal::getNumBlocks() const
-{
-	int num_blocks = 0;
-	const_diag_iter start = diag_begin();
-	const_diag_iter end = findBlockStart(start);
-	while (start != diag_end()) {
-		num_blocks++;
-		start = end;
-		end = findBlockStart(start);
-	}
-	return num_blocks;
-}
-
-// Local Variables:
-// mode:C++
-// End:
diff --git a/dynare++/sylv/cc/BlockDiagonal.h b/dynare++/sylv/cc/BlockDiagonal.hh
similarity index 98%
rename from dynare++/sylv/cc/BlockDiagonal.h
rename to dynare++/sylv/cc/BlockDiagonal.hh
index f449653385da4d385d4b7af825d4411784523944..d1acc1ae65263e892d8d1d594e60c17ca5ab8d70 100644
--- a/dynare++/sylv/cc/BlockDiagonal.h
+++ b/dynare++/sylv/cc/BlockDiagonal.hh
@@ -5,7 +5,7 @@
 #ifndef BLOCK_DIAGONAL_H
 #define BLOCK_DIAGONAL_H
 
-#include "QuasiTriangular.h"
+#include "QuasiTriangular.hh"
 
 class BlockDiagonal : public QuasiTriangular
 {
diff --git a/dynare++/sylv/cc/GeneralMatrix.cc b/dynare++/sylv/cc/GeneralMatrix.cc
new file mode 100644
index 0000000000000000000000000000000000000000..c035248b9a3b104b52f9ce1cea2e5d6424bb8d4d
--- /dev/null
+++ b/dynare++/sylv/cc/GeneralMatrix.cc
@@ -0,0 +1,613 @@
+/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/GeneralMatrix.cpp,v 1.4 2004/11/24 20:41:59 kamenik Exp $ */
+
+/* Tag $Name:  $ */
+
+#include "SylvException.hh"
+#include "GeneralMatrix.hh"
+
+#include <dynblas.h>
+#include <dynlapack.h>
+
+#include <cstdio>
+#include <cstring>
+#include <cstdlib>
+#include <cmath>
+#include <limits>
+
+int GeneralMatrix::md_length = 32;
+
+GeneralMatrix::GeneralMatrix(const GeneralMatrix &m)
+  : data(m.rows*m.cols), rows(m.rows), cols(m.cols), ld(m.rows)
+{
+  copy(m);
+}
+
+GeneralMatrix::GeneralMatrix(const ConstGeneralMatrix &m)
+  : data(m.rows*m.cols), rows(m.rows), cols(m.cols), ld(m.rows)
+{
+  copy(m);
+}
+
+GeneralMatrix::GeneralMatrix(const GeneralMatrix &m, const char *dummy)
+  : data(m.rows*m.cols), rows(m.cols), cols(m.rows), ld(m.cols)
+{
+  for (int i = 0; i < m.rows; i++)
+    for (int j = 0; j < m.cols; j++)
+      get(j, i) = m.get(i, j);
+}
+
+GeneralMatrix::GeneralMatrix(const ConstGeneralMatrix &m, const char *dummy)
+  : data(m.rows*m.cols), rows(m.cols), cols(m.rows), ld(m.cols)
+{
+  for (int i = 0; i < m.rows; i++)
+    for (int j = 0; j < m.cols; j++)
+      get(j, i) = m.get(i, j);
+}
+
+GeneralMatrix::GeneralMatrix(const GeneralMatrix &m, int i, int j, int nrows, int ncols)
+  : data(nrows*ncols), rows(nrows), cols(ncols), ld(nrows)
+{
+  copy(m, i, j);
+}
+
+GeneralMatrix::GeneralMatrix(GeneralMatrix &m, int i, int j, int nrows, int ncols)
+  : data(m.base()+m.ld*j+i, m.ld*(ncols-1)+nrows), rows(nrows), cols(ncols), ld(m.ld)
+{
+}
+
+GeneralMatrix::GeneralMatrix(const GeneralMatrix &a, const GeneralMatrix &b)
+  : data(a.rows*b.cols), rows(a.rows), cols(b.cols), ld(a.rows)
+{
+  gemm("N", a, "N", b, 1.0, 0.0);
+}
+
+GeneralMatrix::GeneralMatrix(const GeneralMatrix &a, const GeneralMatrix &b, const char *dum)
+  : data(a.rows*b.rows), rows(a.rows), cols(b.rows), ld(a.rows)
+{
+  gemm("N", a, "T", b, 1.0, 0.0);
+}
+
+GeneralMatrix::GeneralMatrix(const GeneralMatrix &a, const char *dum, const GeneralMatrix &b)
+  : data(a.cols*b.cols), rows(a.cols), cols(b.cols), ld(a.cols)
+{
+  gemm("T", a, "N", b, 1.0, 0.0);
+}
+
+GeneralMatrix::GeneralMatrix(const GeneralMatrix &a, const char *dum1,
+                             const GeneralMatrix &b, const char *dum2)
+  : data(a.cols*b.rows), rows(a.cols), cols(b.rows), ld(a.cols)
+{
+  gemm("T", a, "T", b, 1.0, 0.0);
+}
+
+GeneralMatrix::~GeneralMatrix()
+{
+}
+
+void
+GeneralMatrix::place(const ConstGeneralMatrix &m, int i, int j)
+{
+  if (i + m.numRows() > numRows()
+      || j + m.numCols() > numCols())
+    throw SYLV_MES_EXCEPTION("Bad submatrix placement, matrix dimensions exceeded.");
+
+  GeneralMatrix tmpsub(*this, i, j, m.numRows(), m.numCols());
+  tmpsub.copy(m);
+}
+
+void
+GeneralMatrix::mult(const ConstGeneralMatrix &a, const ConstGeneralMatrix &b)
+{
+  gemm("N", a, "N", b, 1.0, 0.0);
+}
+
+void
+GeneralMatrix::multAndAdd(const ConstGeneralMatrix &a, const ConstGeneralMatrix &b,
+                          double mult)
+{
+  gemm("N", a, "N", b, mult, 1.0);
+}
+
+void
+GeneralMatrix::multAndAdd(const ConstGeneralMatrix &a, const ConstGeneralMatrix &b,
+                          const char *dum, double mult)
+{
+  gemm("N", a, "T", b, mult, 1.0);
+}
+
+void
+GeneralMatrix::multAndAdd(const ConstGeneralMatrix &a, const char *dum,
+                          const ConstGeneralMatrix &b, double mult)
+{
+  gemm("T", a, "N", b, mult, 1.0);
+}
+
+void
+GeneralMatrix::multAndAdd(const ConstGeneralMatrix &a, const char *dum1,
+                          const ConstGeneralMatrix &b, const char *dum2, double mult)
+{
+  gemm("T", a, "T", b, mult, 1.0);
+}
+
+void
+GeneralMatrix::addOuter(const ConstVector &a, double mult)
+{
+  if (numRows() != numCols())
+    throw SYLV_MES_EXCEPTION("Matrix is not square in GeneralMatrix::addOuter.");
+  if (numRows() != a.length())
+    throw SYLV_MES_EXCEPTION("Wrong length of a vector in GeneralMatrix::addOuter.");
+
+  // since BLAS dsyr (symmetric rank 1 update) assumes symmetricity, we do this manually
+  for (int i = 0; i < numRows(); i++)
+    for (int j = i; j < numRows(); j++)
+      {
+        double s = mult*a[i]*a[j];
+        get(i, j) = get(i, j) + s;
+        if (i != j)
+          get(j, i) = get(j, i) + s;
+      }
+}
+
+void
+GeneralMatrix::multRight(const ConstGeneralMatrix &m)
+{
+  gemm_partial_right("N", m, 1.0, 0.0);
+}
+
+void
+GeneralMatrix::multLeft(const ConstGeneralMatrix &m)
+{
+  gemm_partial_left("N", m, 1.0, 0.0);
+}
+
+void
+GeneralMatrix::multRightTrans(const ConstGeneralMatrix &m)
+{
+  gemm_partial_right("T", m, 1.0, 0.0);
+}
+
+void
+GeneralMatrix::multLeftTrans(const ConstGeneralMatrix &m)
+{
+  gemm_partial_left("T", m, 1.0, 0.0);
+}
+
+// here we must be careful for ld
+void
+GeneralMatrix::zeros()
+{
+  if (ld == rows)
+    data.zeros();
+  else
+    {
+      for (int i = 0; i < rows; i++)
+        for (int j = 0; j < cols; j++)
+          get(i, j) = 0;
+    }
+}
+
+void
+GeneralMatrix::unit()
+{
+  for (int i = 0; i < rows; i++)
+    for (int j = 0; j < cols; j++)
+      if (i == j)
+        get(i, j) = 1.0;
+      else
+        get(i, j) = 0.0;
+}
+
+void
+GeneralMatrix::nans()
+{
+  for (int i = 0; i < rows; i++)
+    for (int j = 0; j < cols; j++)
+      get(i, j) = std::numeric_limits<double>::quiet_NaN();
+}
+
+void
+GeneralMatrix::infs()
+{
+  for (int i = 0; i < rows; i++)
+    for (int j = 0; j < cols; j++)
+      get(i, j) = std::numeric_limits<double>::infinity();
+}
+
+// here we must be careful for ld
+void
+GeneralMatrix::mult(double a)
+{
+  if (ld == rows)
+    data.mult(a);
+  else
+    {
+      for (int i = 0; i < rows; i++)
+        for (int j = 0; j < cols; j++)
+          get(i, j) *= a;
+    }
+}
+
+// here we must be careful for ld
+void
+GeneralMatrix::add(double a, const ConstGeneralMatrix &m)
+{
+  if (m.numRows() != rows || m.numCols() != cols)
+    throw SYLV_MES_EXCEPTION("Matrix has different size in GeneralMatrix::add.");
+
+  if (ld == rows && m.ld == m.rows)
+    data.add(a, m.data);
+  else
+    {
+      for (int i = 0; i < rows; i++)
+        for (int j = 0; j < cols; j++)
+          get(i, j) += a*m.get(i, j);
+    }
+}
+
+void
+GeneralMatrix::add(double a, const ConstGeneralMatrix &m, const char *dum)
+{
+  if (m.numRows() != cols || m.numCols() != rows)
+    throw SYLV_MES_EXCEPTION("Matrix has different size in GeneralMatrix::add.");
+
+  for (int i = 0; i < rows; i++)
+    for (int j = 0; j < cols; j++)
+      get(i, j) += a*m.get(j, i);
+}
+
+void
+GeneralMatrix::copy(const ConstGeneralMatrix &m, int ioff, int joff)
+{
+  for (int i = 0; i < rows; i++)
+    for (int j = 0; j < cols; j++)
+      get(i, j) = m.get(i+ioff, j+joff);
+}
+
+void
+GeneralMatrix::gemm(const char *transa, const ConstGeneralMatrix &a,
+                    const char *transb, const ConstGeneralMatrix &b,
+                    double alpha, double beta)
+{
+  int opa_rows = a.numRows();
+  int opa_cols = a.numCols();
+  if (!strcmp(transa, "T"))
+    {
+      opa_rows = a.numCols();
+      opa_cols = a.numRows();
+    }
+  int opb_rows = b.numRows();
+  int opb_cols = b.numCols();
+  if (!strcmp(transb, "T"))
+    {
+      opb_rows = b.numCols();
+      opb_cols = b.numRows();
+    }
+
+  if (opa_rows != numRows()
+      || opb_cols != numCols()
+      || opa_cols != opb_rows)
+    {
+      throw SYLV_MES_EXCEPTION("Wrong dimensions for matrix multiplication.");
+    }
+
+  blas_int m = opa_rows;
+  blas_int n = opb_cols;
+  blas_int k = opa_cols;
+  blas_int lda = a.ld;
+  blas_int ldb = b.ld;
+  blas_int ldc = ld;
+  if (lda > 0 && ldb > 0 && ldc > 0)
+    {
+      dgemm(transa, transb, &m, &n, &k, &alpha, a.data.base(), &lda,
+            b.data.base(), &ldb, &beta, data.base(), &ldc);
+    }
+  else if (numRows()*numCols() > 0)
+    {
+      if (beta == 0.0)
+        zeros();
+      else
+        mult(beta);
+    }
+}
+
+void
+GeneralMatrix::gemm_partial_left(const char *trans, const ConstGeneralMatrix &m,
+                                 double alpha, double beta)
+{
+  int icol;
+  for (icol = 0; icol + md_length < cols; icol += md_length)
+    {
+      GeneralMatrix incopy((const GeneralMatrix &)*this, 0, icol, rows, md_length);
+      GeneralMatrix inplace((GeneralMatrix&)*this, 0, icol, rows, md_length);
+      inplace.gemm(trans, m, "N", ConstGeneralMatrix(incopy), alpha, beta);
+    }
+  if (cols > icol)
+    {
+      GeneralMatrix incopy((const GeneralMatrix &)*this, 0, icol, rows, cols - icol);
+      GeneralMatrix inplace((GeneralMatrix&)*this, 0, icol, rows, cols - icol);
+      inplace.gemm(trans, m, "N", ConstGeneralMatrix(incopy), alpha, beta);
+    }
+}
+
+void
+GeneralMatrix::gemm_partial_right(const char *trans, const ConstGeneralMatrix &m,
+                                  double alpha, double beta)
+{
+  int irow;
+  for (irow = 0; irow + md_length < rows; irow += md_length)
+    {
+      GeneralMatrix incopy((const GeneralMatrix &)*this, irow, 0, md_length, cols);
+      GeneralMatrix inplace((GeneralMatrix&)*this, irow, 0, md_length, cols);
+      inplace.gemm("N", ConstGeneralMatrix(incopy), trans, m, alpha, beta);
+    }
+  if (rows > irow)
+    {
+      GeneralMatrix incopy((const GeneralMatrix &)*this, irow, 0, rows - irow, cols);
+      GeneralMatrix inplace((GeneralMatrix&)*this, irow, 0, rows - irow, cols);
+      inplace.gemm("N", ConstGeneralMatrix(incopy), trans, m, alpha, beta);
+    }
+}
+
+ConstGeneralMatrix::ConstGeneralMatrix(const GeneralMatrix &m, int i, int j, int nrows, int ncols)
+  : data(m.getData(), j*m.getLD()+i, (ncols-1)*m.getLD()+nrows), rows(nrows), cols(ncols), ld(m.getLD())
+{
+  // can check that the submatirx is fully in the matrix
+}
+
+ConstGeneralMatrix::ConstGeneralMatrix(const ConstGeneralMatrix &m, int i, int j, int nrows, int ncols)
+  : data(m.getData(), j*m.getLD()+i, (ncols-1)*m.getLD()+nrows), rows(nrows), cols(ncols), ld(m.getLD())
+{
+  // can check that the submatirx is fully in the matrix
+}
+
+ConstGeneralMatrix::ConstGeneralMatrix(const GeneralMatrix &m)
+  : data(m.data), rows(m.rows), cols(m.cols), ld(m.ld)
+{
+}
+
+double
+ConstGeneralMatrix::getNormInf() const
+{
+  double norm = 0.0;
+  for (int i = 0; i < numRows(); i++)
+    {
+      ConstVector rowi(data.base()+i, ld, cols);
+      double normi = rowi.getNorm1();
+      if (norm < normi)
+        norm = normi;
+    }
+  return norm;
+}
+
+double
+ConstGeneralMatrix::getNorm1() const
+{
+  double norm = 0.0;
+  for (int j = 0; j < numCols(); j++)
+    {
+      ConstVector colj(data.base()+ld *j, 1, rows);
+      double normj = colj.getNorm1();
+      if (norm < normj)
+        norm = normj;
+    }
+  return norm;
+}
+
+void
+ConstGeneralMatrix::multVec(double a, Vector &x, double b, const ConstVector &d) const
+{
+  if (x.length() != rows || cols != d.length())
+    {
+      throw SYLV_MES_EXCEPTION("Wrong dimensions for vector multiply.");
+    }
+  if (rows > 0)
+    {
+      blas_int mm = rows;
+      blas_int nn = cols;
+      double alpha = b;
+      blas_int lda = ld;
+      blas_int incx = d.skip();
+      double beta = a;
+      blas_int incy = x.skip();
+      dgemv("N", &mm, &nn, &alpha, data.base(), &lda, d.base(), &incx,
+            &beta, x.base(), &incy);
+    }
+
+}
+
+void
+ConstGeneralMatrix::multVecTrans(double a, Vector &x, double b,
+                                 const ConstVector &d) const
+{
+  if (x.length() != cols || rows != d.length())
+    {
+      throw SYLV_MES_EXCEPTION("Wrong dimensions for vector multiply.");
+    }
+  if (rows > 0)
+    {
+      blas_int mm = rows;
+      blas_int nn = cols;
+      double alpha = b;
+      blas_int lda = rows;
+      blas_int incx = d.skip();
+      double beta = a;
+      blas_int incy = x.skip();
+      dgemv("T", &mm, &nn, &alpha, data.base(), &lda, d.base(), &incx,
+            &beta, x.base(), &incy);
+    }
+}
+
+/* m = inv(this)*m */
+void
+ConstGeneralMatrix::multInvLeft(const char *trans, int mrows, int mcols, int mld, double *d) const
+{
+  if (rows != cols)
+    {
+      throw SYLV_MES_EXCEPTION("The matrix is not square for inversion.");
+    }
+  if (cols != mrows)
+    {
+      throw SYLV_MES_EXCEPTION("Wrong dimensions for matrix inverse mutliply.");
+    }
+
+  if (rows > 0)
+    {
+      GeneralMatrix inv(*this);
+      lapack_int *ipiv = new lapack_int[rows];
+      lapack_int info;
+      lapack_int rows2 = rows, mcols2 = mcols, mld2 = mld;
+      dgetrf(&rows2, &rows2, inv.getData().base(), &rows2, ipiv, &info);
+      dgetrs(trans, &rows2, &mcols2, inv.base(), &rows2, ipiv, d,
+             &mld2, &info);
+      delete [] ipiv;
+    }
+}
+
+/* m = inv(this)*m */
+void
+ConstGeneralMatrix::multInvLeft(GeneralMatrix &m) const
+{
+  multInvLeft("N", m.numRows(), m.numCols(), m.getLD(), m.getData().base());
+}
+
+/* m = inv(this')*m */
+void
+ConstGeneralMatrix::multInvLeftTrans(GeneralMatrix &m) const
+{
+  multInvLeft("T", m.numRows(), m.numCols(), m.getLD(), m.getData().base());
+}
+
+/* d = inv(this)*d */
+void
+ConstGeneralMatrix::multInvLeft(Vector &d) const
+{
+  if (d.skip() != 1)
+    {
+      throw SYLV_MES_EXCEPTION("Skip!=1 not implemented in ConstGeneralMatrix::multInvLeft(Vector&)");
+    }
+
+  multInvLeft("N", d.length(), 1, d.length(), d.base());
+}
+
+/* d = inv(this')*d */
+void
+ConstGeneralMatrix::multInvLeftTrans(Vector &d) const
+{
+  if (d.skip() != 1)
+    {
+      throw SYLV_MES_EXCEPTION("Skip!=1 not implemented in ConstGeneralMatrix::multInvLeft(Vector&)");
+    }
+
+  multInvLeft("T", d.length(), 1, d.length(), d.base());
+}
+
+bool
+ConstGeneralMatrix::isFinite() const
+{
+  for (int i = 0; i < numRows(); i++)
+    for (int j = 0; j < numCols(); j++)
+      if (!std::isfinite(get(i, j)))
+        return false;
+  return true;
+}
+
+bool
+ConstGeneralMatrix::isZero() const
+{
+  for (int i = 0; i < numRows(); i++)
+    for (int j = 0; j < numCols(); j++)
+      if (get(i, j) != 0.0)
+        return false;
+  return true;
+}
+
+void
+ConstGeneralMatrix::print() const
+{
+  printf("rows=%d, cols=%d\n", rows, cols);
+  for (int i = 0; i < rows; i++)
+    {
+      printf("row %d:\n", i);
+      for (int j = 0; j < cols; j++)
+        {
+          printf("%6.3g ", get(i, j));
+        }
+      printf("\n");
+    }
+}
+
+void
+SVDDecomp::construct(const GeneralMatrix &A)
+{
+  // quick exit if empty matrix
+  if (minmn == 0)
+    {
+      U.unit();
+      VT.unit();
+      conv = true;
+      return;
+    }
+
+  // make copy of the matrix
+  GeneralMatrix AA(A);
+
+  lapack_int m = AA.numRows();
+  lapack_int n = AA.numCols();
+  double *a = AA.base();
+  lapack_int lda = AA.getLD();
+  double *s = sigma.base();
+  double *u = U.base();
+  lapack_int ldu = U.getLD();
+  double *vt = VT.base();
+  lapack_int ldvt = VT.getLD();
+  double tmpwork;
+  lapack_int lwork = -1;
+  lapack_int info;
+
+  lapack_int *iwork = new lapack_int[8*minmn];
+  // query for optimal lwork
+  dgesdd("A", &m, &n, a, &lda, s, u, &ldu, vt, &ldvt, &tmpwork,
+         &lwork, iwork, &info);
+  lwork = (lapack_int) tmpwork;
+  Vector work(lwork);
+  // do the decomposition
+  dgesdd("A", &m, &n, a, &lda, s, u, &ldu, vt, &ldvt, work.base(),
+         &lwork, iwork, &info);
+  delete [] iwork;
+  if (info < 0)
+    throw SYLV_MES_EXCEPTION("Internal error in SVDDecomp constructor");
+  if (info == 0)
+    conv = true;
+}
+
+void
+SVDDecomp::solve(const GeneralMatrix &B, GeneralMatrix &X) const
+{
+  if (B.numRows() != U.numRows())
+    throw SYLV_MES_EXCEPTION("Incompatible number of rows ");
+
+  // reciprocal condition number for determination of zeros in the
+  // end of sigma
+  double rcond = 1e-13;
+
+  // solve U: B = U^T*B
+  GeneralMatrix UTB(U, "trans", B);
+  // determine nz=number of zeros in the end of sigma
+  int nz = 0;
+  while (nz < minmn && sigma[minmn-1-nz] < rcond*sigma[0])
+    nz++;
+  // take relevant B for sigma inversion
+  int m = U.numRows();
+  int n = VT.numCols();
+  GeneralMatrix Bprime(UTB, m-minmn, 0, minmn-nz, B.numCols());
+  // solve sigma
+  for (int i = 0; i < minmn-nz; i++)
+    Vector(i, Bprime).mult(1.0/sigma[i]);
+  // solve VT
+  X.zeros();
+  //- copy Bprime to right place of X
+  for (int i = 0; i < minmn-nz; i++)
+    Vector(n-minmn+i, X) = ConstVector(i, Bprime);
+  //- multiply with VT
+  X.multLeftTrans(VT);
+}
diff --git a/dynare++/sylv/cc/GeneralMatrix.cpp b/dynare++/sylv/cc/GeneralMatrix.cpp
deleted file mode 100644
index 75834f522e4eb367ee6876475b9d0db6aef138fe..0000000000000000000000000000000000000000
--- a/dynare++/sylv/cc/GeneralMatrix.cpp
+++ /dev/null
@@ -1,556 +0,0 @@
-/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/GeneralMatrix.cpp,v 1.4 2004/11/24 20:41:59 kamenik Exp $ */
-
-/* Tag $Name:  $ */
-
-
-#include "SylvException.h"
-#include "GeneralMatrix.h"
-
-#include <dynblas.h>
-#include <dynlapack.h>
-
-#include <cstdio>
-#include <cstring>
-#include <cstdlib>
-#include <cmath>
-#include <limits>
-
-int GeneralMatrix::md_length = 32;
-
-GeneralMatrix::GeneralMatrix(const GeneralMatrix& m)
-	: data(m.rows*m.cols), rows(m.rows), cols(m.cols), ld(m.rows)
-{
-	copy(m);
-}
-
-GeneralMatrix::GeneralMatrix(const ConstGeneralMatrix& m)
-	: data(m.rows*m.cols), rows(m.rows), cols(m.cols), ld(m.rows)
-{
-	copy(m);
-}
-
-GeneralMatrix::GeneralMatrix(const GeneralMatrix& m, const char* dummy)
-	: data(m.rows*m.cols), rows(m.cols), cols(m.rows), ld(m.cols)
-{
-	for (int i = 0; i < m.rows; i++)
-		for (int j = 0; j < m.cols; j++)
-			get(j,i) = m.get(i,j);
-}
-
-GeneralMatrix::GeneralMatrix(const ConstGeneralMatrix& m, const char* dummy)
-	: data(m.rows*m.cols), rows(m.cols), cols(m.rows), ld(m.cols)
-{
-	for (int i = 0; i < m.rows; i++)
-		for (int j = 0; j < m.cols; j++)
-			get(j,i) = m.get(i,j);
-}
-
-
-GeneralMatrix::GeneralMatrix(const GeneralMatrix& m, int i, int j, int nrows, int ncols)
-	: data(nrows*ncols), rows(nrows), cols(ncols), ld(nrows)
-{
-	copy(m, i, j);
-}
-
-GeneralMatrix::GeneralMatrix(GeneralMatrix& m, int i, int j, int nrows, int ncols)
-	: data(m.base()+m.ld*j+i, m.ld*(ncols-1)+nrows), rows(nrows), cols(ncols), ld(m.ld)
-{}
-
-GeneralMatrix::GeneralMatrix(const GeneralMatrix& a, const GeneralMatrix& b)
-	: data(a.rows*b.cols), rows(a.rows), cols(b.cols), ld(a.rows)
-{
-	gemm("N", a, "N", b, 1.0, 0.0);
-}
-
-GeneralMatrix::GeneralMatrix(const GeneralMatrix& a, const GeneralMatrix& b, const char* dum)
-	: data(a.rows*b.rows), rows(a.rows), cols(b.rows), ld(a.rows)
-{
-	gemm("N", a, "T", b, 1.0, 0.0);
-}
-
-GeneralMatrix::GeneralMatrix(const GeneralMatrix& a, const char* dum, const GeneralMatrix& b)
-	: data(a.cols*b.cols), rows(a.cols), cols(b.cols), ld(a.cols)
-{
-	gemm("T", a, "N", b, 1.0, 0.0);
-}
-
-GeneralMatrix::GeneralMatrix(const GeneralMatrix& a, const char* dum1,
-							 const GeneralMatrix& b, const char* dum2)
-	: data(a.cols*b.rows), rows(a.cols), cols(b.rows), ld(a.cols)
-{
-	gemm("T", a, "T", b, 1.0, 0.0);
-}
-
-
-
-GeneralMatrix::~GeneralMatrix()
-{
-}
-
-
-
-void GeneralMatrix::place(const ConstGeneralMatrix& m, int i, int j)
-{
-	if (i + m.numRows() > numRows() ||
-		j + m.numCols() > numCols())
-		throw SYLV_MES_EXCEPTION("Bad submatrix placement, matrix dimensions exceeded.");
-
-	GeneralMatrix tmpsub(*this, i, j, m.numRows(), m.numCols());
-	tmpsub.copy(m);
-}
-
-void GeneralMatrix::mult(const ConstGeneralMatrix& a, const ConstGeneralMatrix& b)
-{
-	gemm("N", a, "N", b, 1.0, 0.0);
-}
-
-void GeneralMatrix::multAndAdd(const ConstGeneralMatrix& a, const ConstGeneralMatrix& b,
-							   double mult)
-{
-	gemm("N", a, "N", b, mult, 1.0);
-}
-
-void GeneralMatrix::multAndAdd(const ConstGeneralMatrix& a, const ConstGeneralMatrix& b,
-							   const char* dum, double mult)
-{
-	gemm("N", a, "T", b, mult, 1.0);
-}
-
-void GeneralMatrix::multAndAdd(const ConstGeneralMatrix& a, const char* dum,
-							   const ConstGeneralMatrix& b, double mult)
-{
-	gemm("T", a, "N", b, mult, 1.0);
-}
-
-void GeneralMatrix::multAndAdd(const ConstGeneralMatrix& a, const char* dum1,
-							   const ConstGeneralMatrix& b, const char* dum2, double mult)
-{
-	gemm("T", a, "T", b, mult, 1.0);
-}
-
-void GeneralMatrix::addOuter(const ConstVector& a, double mult)
-{
-	if (numRows() != numCols())
-		throw SYLV_MES_EXCEPTION("Matrix is not square in GeneralMatrix::addOuter.");
-	if (numRows() != a.length())
-		throw SYLV_MES_EXCEPTION("Wrong length of a vector in GeneralMatrix::addOuter.");
-
-	// since BLAS dsyr (symmetric rank 1 update) assumes symmetricity, we do this manually
-	for (int i = 0; i < numRows(); i++)
-		for (int j = i; j < numRows(); j++) {
-			double s = mult*a[i]*a[j];
-			get(i,j) = get(i,j) + s;
-			if (i != j)
-				get(j,i) = get(j,i) + s;
-		}
-}
-
-
-void GeneralMatrix::multRight(const ConstGeneralMatrix& m)
-{
-	gemm_partial_right("N", m, 1.0, 0.0);
-}
-
-void GeneralMatrix::multLeft(const ConstGeneralMatrix& m)
-{
-	gemm_partial_left("N", m, 1.0, 0.0);
-}
-
-void GeneralMatrix::multRightTrans(const ConstGeneralMatrix& m)
-{
-	gemm_partial_right("T", m, 1.0, 0.0);
-}
-
-void GeneralMatrix::multLeftTrans(const ConstGeneralMatrix& m)
-{
-	gemm_partial_left("T", m, 1.0, 0.0);
-}
-
-// here we must be careful for ld
-void GeneralMatrix::zeros()
-{
-	if (ld == rows)
-		data.zeros();
-	else {
-		for (int i = 0; i < rows; i++) 
-			for (int j = 0; j < cols; j++)
-				get(i,j) = 0;
-	}
-}
-
-void GeneralMatrix::unit()
-{
-	for (int i = 0; i < rows; i++)
-		for (int j = 0; j < cols; j++)
-			if (i == j)
-				get(i,j) = 1.0;
-			else
-				get(i,j) = 0.0;
-}
-
-void GeneralMatrix::nans()
-{
-	for (int i = 0; i < rows; i++) 
-		for (int j = 0; j < cols; j++)
-			get(i,j) = std::numeric_limits<double>::quiet_NaN();
-}
-
-void GeneralMatrix::infs()
-{
-	for (int i = 0; i < rows; i++) 
-		for (int j = 0; j < cols; j++)
-			get(i,j) = std::numeric_limits<double>::infinity();
-}
-
-
-// here we must be careful for ld
-void GeneralMatrix::mult(double a)
-{
-	if (ld == rows)
-		data.mult(a);
-	else {
-		for (int i = 0; i < rows; i++) 
-			for (int j = 0; j < cols; j++)
-				get(i,j) *= a;
-	}
-}
-
-// here we must be careful for ld
-void GeneralMatrix::add(double a, const ConstGeneralMatrix& m)
-{
-	if (m.numRows() != rows || m.numCols() != cols)
-		throw SYLV_MES_EXCEPTION("Matrix has different size in GeneralMatrix::add.");
-
-	if (ld == rows && m.ld == m.rows)
-		data.add(a, m.data);
-	else {
-		for (int i = 0; i < rows; i++) 
-			for (int j = 0; j < cols; j++)
-				get(i,j) += a*m.get(i,j);
-	}
-}
-
-void GeneralMatrix::add(double a, const ConstGeneralMatrix& m, const char* dum)
-{
-	if (m.numRows() != cols || m.numCols() != rows)
-		throw SYLV_MES_EXCEPTION("Matrix has different size in GeneralMatrix::add.");
-
-	for (int i = 0; i < rows; i++) 
-		for (int j = 0; j < cols; j++)
-			get(i,j) += a*m.get(j,i);
-}
-
-void GeneralMatrix::copy(const ConstGeneralMatrix& m, int ioff, int joff)
-{
-	for (int i = 0; i < rows; i++)
-		for (int j = 0; j < cols; j++)
-			get(i,j) = m.get(i+ioff,j+joff);
-}
-
-void GeneralMatrix::gemm(const char* transa, const ConstGeneralMatrix& a,
-						 const char* transb, const ConstGeneralMatrix& b,
-						 double alpha, double beta)
-{
-	int opa_rows = a.numRows();
-	int opa_cols = a.numCols();
-	if (!strcmp(transa, "T")) {
-		opa_rows = a.numCols();
-		opa_cols = a.numRows();
-	}
-	int opb_rows = b.numRows();
-	int opb_cols = b.numCols();
-	if (!strcmp(transb, "T")) {
-		opb_rows = b.numCols();
-		opb_cols = b.numRows();
-	}
-
-	if (opa_rows != numRows() ||
-		opb_cols != numCols() ||
-		opa_cols != opb_rows) {
-		throw SYLV_MES_EXCEPTION("Wrong dimensions for matrix multiplication.");
-	}
-
-	blas_int m = opa_rows;
-	blas_int n = opb_cols;
-	blas_int k = opa_cols;
-	blas_int lda = a.ld;
-	blas_int ldb = b.ld;
-	blas_int ldc = ld;
-	if (lda > 0 && ldb > 0 && ldc > 0) {
-		dgemm(transa, transb, &m, &n, &k, &alpha, a.data.base(), &lda,
-				   b.data.base(), &ldb, &beta, data.base(), &ldc); 
-	} else if (numRows()*numCols() > 0) {
-		if (beta == 0.0)
-			zeros();
-		else
-			mult(beta);
-	}
-}
-
-void GeneralMatrix::gemm_partial_left(const char* trans, const ConstGeneralMatrix& m,
-									  double alpha, double beta)
-{
-	int icol;
-	for (icol = 0; icol + md_length < cols; icol += md_length) {
-		GeneralMatrix incopy((const GeneralMatrix&)*this, 0, icol, rows, md_length);
-		GeneralMatrix inplace((GeneralMatrix&)*this, 0, icol, rows, md_length);
-		inplace.gemm(trans, m, "N", ConstGeneralMatrix(incopy), alpha, beta);
-	}
-	if (cols > icol) {
-		GeneralMatrix incopy((const GeneralMatrix&)*this, 0, icol, rows, cols - icol);
-		GeneralMatrix inplace((GeneralMatrix&)*this, 0, icol, rows, cols - icol);
-		inplace.gemm(trans, m, "N", ConstGeneralMatrix(incopy), alpha, beta);
-	}
-}
-
-void GeneralMatrix::gemm_partial_right(const char* trans, const ConstGeneralMatrix& m,
-									   double alpha, double beta)
-{
-	int irow;
-	for (irow = 0; irow + md_length < rows; irow += md_length) {
-		GeneralMatrix incopy((const GeneralMatrix&)*this, irow, 0, md_length, cols);
-		GeneralMatrix inplace((GeneralMatrix&)*this, irow, 0, md_length, cols);
-		inplace.gemm("N", ConstGeneralMatrix(incopy), trans, m, alpha, beta);
-	}
-	if (rows > irow) {
-		GeneralMatrix incopy((const GeneralMatrix&)*this, irow, 0, rows - irow, cols);
-		GeneralMatrix inplace((GeneralMatrix&)*this, irow, 0, rows - irow, cols);
-		inplace.gemm("N", ConstGeneralMatrix(incopy), trans, m, alpha, beta);
-	}
-}
-
-ConstGeneralMatrix::ConstGeneralMatrix(const GeneralMatrix& m, int i, int j, int nrows, int ncols)
-	: data(m.getData(), j*m.getLD()+i, (ncols-1)*m.getLD()+nrows), rows(nrows), cols(ncols), ld(m.getLD())
-{
-	// can check that the submatirx is fully in the matrix
-}
-
-ConstGeneralMatrix::ConstGeneralMatrix(const ConstGeneralMatrix& m, int i, int j, int nrows, int ncols)
-	: data(m.getData(), j*m.getLD()+i, (ncols-1)*m.getLD()+nrows), rows(nrows), cols(ncols), ld(m.getLD())
-{
-	// can check that the submatirx is fully in the matrix
-}
-
-
-ConstGeneralMatrix::ConstGeneralMatrix(const GeneralMatrix& m)
-		: data(m.data), rows(m.rows), cols(m.cols), ld(m.ld) {}
-
-double ConstGeneralMatrix::getNormInf() const
-{
-	double norm = 0.0;
-	for (int i = 0; i < numRows(); i++) {
-		ConstVector rowi(data.base()+i, ld, cols);
-		double normi = rowi.getNorm1();
-		if (norm < normi)
-			norm = normi;
-	}
-	return norm;
-}
-
-double ConstGeneralMatrix::getNorm1() const
-{
-	double norm = 0.0;
-	for (int j = 0; j < numCols(); j++) {
-		ConstVector colj(data.base()+ld*j, 1, rows);
-		double normj = colj.getNorm1();
-		if (norm < normj)
-			norm = normj;
-	}
-	return norm;
-}
-
-void ConstGeneralMatrix::multVec(double a, Vector& x, double b, const ConstVector& d) const
-{
-	if (x.length() != rows || cols != d.length()) {
-		throw SYLV_MES_EXCEPTION("Wrong dimensions for vector multiply.");
-	}
-	if (rows > 0) {
-		blas_int mm = rows;
-		blas_int nn = cols;
-		double alpha = b;
-		blas_int lda = ld;
-		blas_int incx = d.skip();
-		double beta = a;
-		blas_int incy = x.skip();
-		dgemv("N", &mm, &nn, &alpha, data.base(), &lda, d.base(), &incx,
-				   &beta, x.base(), &incy);
-	}
-	
-}
-
-void ConstGeneralMatrix::multVecTrans(double a, Vector& x, double b,
-									  const ConstVector& d) const
-{
-	if (x.length() != cols || rows != d.length()) {
-		throw SYLV_MES_EXCEPTION("Wrong dimensions for vector multiply.");
-	}
-	if (rows > 0) {
-		blas_int mm = rows;
-		blas_int nn = cols;
-		double alpha = b;
-		blas_int lda = rows;
-		blas_int incx = d.skip();
-		double beta = a;
-		blas_int incy = x.skip();
-		dgemv("T", &mm, &nn, &alpha, data.base(), &lda, d.base(), &incx,
-				   &beta, x.base(), &incy);
-	}
-}
-
-/* m = inv(this)*m */
-void ConstGeneralMatrix::multInvLeft(const char* trans, int mrows, int mcols, int mld, double* d) const
-{
-	if (rows != cols) {
-		throw SYLV_MES_EXCEPTION("The matrix is not square for inversion.");
-	}
-	if (cols != mrows) {
-		throw SYLV_MES_EXCEPTION("Wrong dimensions for matrix inverse mutliply.");
-	}
-
-	if (rows > 0) {
-		GeneralMatrix inv(*this);
-		lapack_int* ipiv = new lapack_int[rows];
-		lapack_int info;
-		lapack_int rows2 = rows, mcols2 = mcols, mld2 = mld;
-		dgetrf(&rows2, &rows2, inv.getData().base(), &rows2, ipiv, &info);
-		dgetrs(trans, &rows2, &mcols2, inv.base(), &rows2, ipiv, d,
-					  &mld2, &info);
-		delete [] ipiv;
-	}
-}
-
-/* m = inv(this)*m */
-void ConstGeneralMatrix::multInvLeft(GeneralMatrix& m) const
-{
-	multInvLeft("N", m.numRows(), m.numCols(), m.getLD(), m.getData().base());
-}
-
-/* m = inv(this')*m */
-void ConstGeneralMatrix::multInvLeftTrans(GeneralMatrix& m) const
-{
-	multInvLeft("T", m.numRows(), m.numCols(), m.getLD(), m.getData().base());
-}
-
-/* d = inv(this)*d */
-void ConstGeneralMatrix::multInvLeft(Vector& d) const
-{
-	if (d.skip() != 1) {
-		throw SYLV_MES_EXCEPTION("Skip!=1 not implemented in ConstGeneralMatrix::multInvLeft(Vector&)");
-	}
-
-	multInvLeft("N", d.length(), 1, d.length(), d.base());
-}
-
-/* d = inv(this')*d */
-void ConstGeneralMatrix::multInvLeftTrans(Vector& d) const
-{
-	if (d.skip() != 1) {
-		throw SYLV_MES_EXCEPTION("Skip!=1 not implemented in ConstGeneralMatrix::multInvLeft(Vector&)");
-	}
-
-	multInvLeft("T", d.length(), 1, d.length(), d.base());
-}
-
-
-bool ConstGeneralMatrix::isFinite() const
-{
-	for (int i = 0; i < numRows(); i++)
-		for (int j = 0; j < numCols(); j++)
-			if (! std::isfinite(get(i,j)))
-				return false;
-	return true;
-}
-
-bool ConstGeneralMatrix::isZero() const
-{
-	for (int i = 0; i < numRows(); i++)
-		for (int j = 0; j < numCols(); j++)
-			if (get(i,j) != 0.0)
-				return false;
-	return true;
-}
-
-void ConstGeneralMatrix::print() const
-{
-	printf("rows=%d, cols=%d\n",rows, cols);
-	for (int i = 0; i < rows; i++) {
-		printf("row %d:\n",i);
-		for (int j = 0; j < cols; j++) {
-			printf("%6.3g ",get(i,j));
-		}
-		printf("\n");
-	}
-}
-
-void SVDDecomp::construct(const GeneralMatrix& A)
-{
-    // quick exit if empty matrix
-    if (minmn == 0) {
-        U.unit();
-        VT.unit();
-        conv = true;
-        return;
-    }
-
-    // make copy of the matrix
-    GeneralMatrix AA(A);
-
-    lapack_int m = AA.numRows();
-    lapack_int n = AA.numCols();
-    double* a = AA.base();
-    lapack_int lda = AA.getLD();
-    double* s = sigma.base();
-    double* u = U.base();
-    lapack_int ldu = U.getLD();
-    double* vt = VT.base();
-    lapack_int ldvt = VT.getLD();
-    double tmpwork;
-    lapack_int lwork = -1;
-    lapack_int info;
-
-    lapack_int* iwork = new lapack_int[8*minmn];
-    // query for optimal lwork
-    dgesdd("A", &m, &n, a, &lda, s, u, &ldu, vt, &ldvt, &tmpwork,
-                  &lwork, iwork, &info);
-    lwork = (lapack_int)tmpwork;
-    Vector work(lwork);
-    // do the decomposition
-    dgesdd("A", &m, &n, a, &lda, s, u, &ldu, vt, &ldvt, work.base(),
-                  &lwork, iwork, &info);
-    delete [] iwork;
-    if (info < 0)
-        throw SYLV_MES_EXCEPTION("Internal error in SVDDecomp constructor");
-    if (info == 0)
-        conv = true;
-}
-
-void SVDDecomp::solve(const GeneralMatrix& B, GeneralMatrix& X) const
-{
-    if (B.numRows() != U.numRows())
-        throw SYLV_MES_EXCEPTION("Incompatible number of rows ");
-
-    // reciprocal condition number for determination of zeros in the
-    // end of sigma
-    double rcond = 1e-13;
-
-    // solve U: B = U^T*B
-    GeneralMatrix UTB(U, "trans", B);
-    // determine nz=number of zeros in the end of sigma
-    int nz = 0;
-    while (nz < minmn && sigma[minmn-1-nz] < rcond*sigma[0])
-        nz++;
-    // take relevant B for sigma inversion
-    int m = U.numRows();
-    int n = VT.numCols();
-    GeneralMatrix Bprime(UTB, m-minmn, 0, minmn-nz, B.numCols());
-    // solve sigma
-    for (int i = 0; i < minmn-nz; i++)
-        Vector(i, Bprime).mult(1.0/sigma[i]);
-    // solve VT
-    X.zeros();
-    //- copy Bprime to right place of X
-    for (int i = 0; i < minmn-nz; i++)
-        Vector(n-minmn+i, X) = ConstVector(i, Bprime);
-    //- multiply with VT
-    X.multLeftTrans(VT);
-}
diff --git a/dynare++/sylv/cc/GeneralMatrix.h b/dynare++/sylv/cc/GeneralMatrix.hh
similarity index 99%
rename from dynare++/sylv/cc/GeneralMatrix.h
rename to dynare++/sylv/cc/GeneralMatrix.hh
index 494dcf40677956d9df97d4eada2e5a84b6efc373..b85dbb4da9e169442756d04addc1ce8d5600296a 100644
--- a/dynare++/sylv/cc/GeneralMatrix.h
+++ b/dynare++/sylv/cc/GeneralMatrix.hh
@@ -5,7 +5,7 @@
 #ifndef GENERAL_MATRIX_H
 #define GENERAL_MATRIX_H
 
-#include "Vector.h"
+#include "Vector.hh"
 
 #include <algorithm>
 
diff --git a/dynare++/sylv/cc/GeneralSylvester.cc b/dynare++/sylv/cc/GeneralSylvester.cc
new file mode 100644
index 0000000000000000000000000000000000000000..930b6adb786e3b54cf0bc32b6e7cdbab6fc431f9
--- /dev/null
+++ b/dynare++/sylv/cc/GeneralSylvester.cc
@@ -0,0 +1,141 @@
+/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/GeneralSylvester.cpp,v 1.1.1.1 2004/06/04 13:00:20 kamenik Exp $ */
+
+/* Tag $Name:  $ */
+
+#include "GeneralSylvester.hh"
+#include "SchurDecomp.hh"
+#include "SylvException.hh"
+#include "TriangularSylvester.hh"
+#include "IterativeSylvester.hh"
+
+#include <ctime>
+
+GeneralSylvester::GeneralSylvester(int ord, int n, int m, int zero_cols,
+                                   const double *da, const double *db,
+                                   const double *dc, const double *dd,
+                                   const SylvParams &ps)
+  : pars(ps),
+    mem_driver(pars, 1, m, n, ord), order(ord), a(da, n),
+    b(db, n, n-zero_cols), c(dc, m), d(dd, n, power(m, order)),
+    solved(false)
+{
+  init();
+}
+
+GeneralSylvester::GeneralSylvester(int ord, int n, int m, int zero_cols,
+                                   const double *da, const double *db,
+                                   const double *dc, double *dd,
+                                   const SylvParams &ps)
+  : pars(ps),
+    mem_driver(pars, 0, m, n, ord), order(ord), a(da, n),
+    b(db, n, n-zero_cols), c(dc, m), d(dd, n, power(m, order)),
+    solved(false)
+{
+  init();
+}
+
+GeneralSylvester::GeneralSylvester(int ord, int n, int m, int zero_cols,
+                                   const double *da, const double *db,
+                                   const double *dc, const double *dd,
+                                   bool alloc_for_check)
+  : pars(alloc_for_check),
+    mem_driver(pars, 1, m, n, ord), order(ord), a(da, n),
+    b(db, n, n-zero_cols), c(dc, m), d(dd, n, power(m, order)),
+    solved(false)
+{
+  init();
+}
+
+GeneralSylvester::GeneralSylvester(int ord, int n, int m, int zero_cols,
+                                   const double *da, const double *db,
+                                   const double *dc, double *dd,
+                                   bool alloc_for_check)
+  : pars(alloc_for_check),
+    mem_driver(pars, 0, m, n, ord), order(ord), a(da, n),
+    b(db, n, n-zero_cols), c(dc, m), d(dd, n, power(m, order)),
+    solved(false)
+{
+  init();
+}
+
+void
+GeneralSylvester::init()
+{
+  GeneralMatrix ainvb(b);
+  double rcond1;
+  double rcondinf;
+  a.multInvLeft2(ainvb, d, rcond1, rcondinf);
+  pars.rcondA1 = rcond1;
+  pars.rcondAI = rcondinf;
+  bdecomp = new SchurDecompZero(ainvb);
+  cdecomp = new SimilarityDecomp(c.getData().base(), c.numRows(), *(pars.bs_norm));
+  cdecomp->check(pars, c);
+  cdecomp->infoToPars(pars);
+  if (*(pars.method) == SylvParams::recurse)
+    sylv = new TriangularSylvester(*bdecomp, *cdecomp);
+  else
+    sylv = new IterativeSylvester(*bdecomp, *cdecomp);
+}
+
+void
+GeneralSylvester::solve()
+{
+  if (solved)
+    throw SYLV_MES_EXCEPTION("Attempt to run solve() more than once.");
+
+  mem_driver.setStackMode(true);
+
+  clock_t start = clock();
+  // multiply d
+  d.multLeftITrans(bdecomp->getQ());
+  d.multRightKron(cdecomp->getQ(), order);
+  // convert to KronVector
+  KronVector dkron(d.getData(), getM(), getN(), order);
+  // solve
+  sylv->solve(pars, dkron);
+  // multiply d back
+  d.multLeftI(bdecomp->getQ());
+  d.multRightKron(cdecomp->getInvQ(), order);
+  clock_t end = clock();
+  pars.cpu_time = ((double) (end-start))/CLOCKS_PER_SEC;
+
+  mem_driver.setStackMode(false);
+
+  solved = true;
+}
+
+void
+GeneralSylvester::check(const double *ds)
+{
+  if (!solved)
+    throw SYLV_MES_EXCEPTION("Cannot run check on system, which is not solved yet.");
+
+  mem_driver.setStackMode(true);
+
+  // calculate xcheck = AX+BXC^i-D
+  SylvMatrix dcheck(d.numRows(), d.numCols());
+  dcheck.multLeft(b.numRows()-b.numCols(), b, d);
+  dcheck.multRightKron(c, order);
+  dcheck.multAndAdd(a, d);
+  ConstVector dv(ds, d.numRows()*d.numCols());
+  dcheck.getData().add(-1.0, dv);
+  // calculate relative norms
+  pars.mat_err1 = dcheck.getNorm1()/d.getNorm1();
+  pars.mat_errI = dcheck.getNormInf()/d.getNormInf();
+  pars.mat_errF = dcheck.getData().getNorm()/d.getData().getNorm();
+  pars.vec_err1 = dcheck.getData().getNorm1()/d.getData().getNorm1();
+  pars.vec_errI = dcheck.getData().getMax()/d.getData().getMax();
+
+  mem_driver.setStackMode(false);
+}
+
+GeneralSylvester::~GeneralSylvester()
+{
+  delete bdecomp;
+  delete cdecomp;
+  delete sylv;
+}
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/dynare++/sylv/cc/GeneralSylvester.cpp b/dynare++/sylv/cc/GeneralSylvester.cpp
deleted file mode 100644
index 81453a91a8431d91a4389872161388b113472bae..0000000000000000000000000000000000000000
--- a/dynare++/sylv/cc/GeneralSylvester.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/GeneralSylvester.cpp,v 1.1.1.1 2004/06/04 13:00:20 kamenik Exp $ */
-
-/* Tag $Name:  $ */
-
-#include "GeneralSylvester.h"
-#include "SchurDecomp.h"
-#include "SylvException.h"
-#include "TriangularSylvester.h"
-#include "IterativeSylvester.h"
-
-#include <ctime>
-
-GeneralSylvester::GeneralSylvester(int ord, int n, int m, int zero_cols,
-								   const double* da, const double* db,
-								   const double* dc, const double* dd,
-								   const SylvParams& ps)
-	: pars(ps), 
-	  mem_driver(pars, 1, m, n, ord), order(ord), a(da, n),
-	  b(db, n, n-zero_cols), c(dc, m), d(dd, n, power(m, order)),
-	  solved(false)
-{
-	init();
-}
-
-GeneralSylvester::GeneralSylvester(int ord, int n, int m, int zero_cols,
-								   const double* da, const double* db,
-								   const double* dc, double* dd,
-								   const SylvParams& ps)
-	: pars(ps),
-	  mem_driver(pars, 0, m, n, ord), order(ord), a(da, n),
-	  b(db, n, n-zero_cols), c(dc, m), d(dd, n, power(m, order)),
-	  solved(false)
-{
-	init();
-}
-
-GeneralSylvester::GeneralSylvester(int ord, int n, int m, int zero_cols,
-								   const double* da, const double* db,
-								   const double* dc, const double* dd,
-								   bool alloc_for_check)
-	: pars(alloc_for_check), 
-	  mem_driver(pars, 1, m, n, ord), order(ord), a(da, n),
-	  b(db, n, n-zero_cols), c(dc, m), d(dd, n, power(m, order)),
-	  solved(false)
-{
-	init();
-}
-
-GeneralSylvester::GeneralSylvester(int ord, int n, int m, int zero_cols,
-								   const double* da, const double* db,
-								   const double* dc, double* dd,
-								   bool alloc_for_check)
-	: pars(alloc_for_check),
-	  mem_driver(pars, 0, m, n, ord), order(ord), a(da, n),
-	  b(db, n, n-zero_cols), c(dc, m), d(dd, n, power(m, order)),
-	  solved(false)
-{
-	init();
-}
-
-void GeneralSylvester::init()
-{
-	GeneralMatrix ainvb(b);
-	double rcond1;
-	double rcondinf;
-	a.multInvLeft2(ainvb, d, rcond1, rcondinf);
-	pars.rcondA1 = rcond1;
-	pars.rcondAI = rcondinf;
-	bdecomp = new SchurDecompZero(ainvb);
-	cdecomp = new SimilarityDecomp(c.getData().base(), c.numRows(), *(pars.bs_norm));
-	cdecomp->check(pars, c);
-	cdecomp->infoToPars(pars);
-	if (*(pars.method) == SylvParams::recurse)
-		sylv = new TriangularSylvester(*bdecomp, *cdecomp);
-	else
-		sylv = new IterativeSylvester(*bdecomp, *cdecomp);
-}
-
-void GeneralSylvester::solve()
-{
-	if (solved)
-		throw SYLV_MES_EXCEPTION("Attempt to run solve() more than once.");
-
-	mem_driver.setStackMode(true);
-
-	clock_t start = clock();
-	// multiply d
-	d.multLeftITrans(bdecomp->getQ());
-	d.multRightKron(cdecomp->getQ(), order);
-	// convert to KronVector
-	KronVector dkron(d.getData(), getM(), getN(), order);
-	// solve
-	sylv->solve(pars, dkron);
-	// multiply d back
-	d.multLeftI(bdecomp->getQ());
-	d.multRightKron(cdecomp->getInvQ(), order);
-	clock_t end = clock();
-	pars.cpu_time = ((double)(end-start))/CLOCKS_PER_SEC;
-
-	mem_driver.setStackMode(false);
-
-	solved = true;
-}
-
-void GeneralSylvester::check(const double* ds)
-{
-	if (!solved)
-		throw SYLV_MES_EXCEPTION("Cannot run check on system, which is not solved yet.");
-
-	mem_driver.setStackMode(true);
-
-	// calculate xcheck = AX+BXC^i-D
-	SylvMatrix dcheck(d.numRows(), d.numCols());
-	dcheck.multLeft(b.numRows()-b.numCols(), b, d);
-	dcheck.multRightKron(c, order);
-	dcheck.multAndAdd(a,d);
-	ConstVector dv(ds, d.numRows()*d.numCols());
-	dcheck.getData().add(-1.0, dv);
-	// calculate relative norms
-	pars.mat_err1 = dcheck.getNorm1()/d.getNorm1();
-	pars.mat_errI = dcheck.getNormInf()/d.getNormInf();
-	pars.mat_errF = dcheck.getData().getNorm()/d.getData().getNorm();
-	pars.vec_err1 = dcheck.getData().getNorm1()/d.getData().getNorm1();
-	pars.vec_errI = dcheck.getData().getMax()/d.getData().getMax();
-
-	mem_driver.setStackMode(false);
-}
-
-GeneralSylvester::~GeneralSylvester()
-{
-	delete bdecomp;
-	delete cdecomp;
-	delete sylv;
-}
-
-// Local Variables:
-// mode:C++
-// End:
diff --git a/dynare++/sylv/cc/GeneralSylvester.h b/dynare++/sylv/cc/GeneralSylvester.hh
similarity index 94%
rename from dynare++/sylv/cc/GeneralSylvester.h
rename to dynare++/sylv/cc/GeneralSylvester.hh
index 9e2603f48ce1580861d224b14738c7ca6cb6223a..c1a596f158b1007d827839a90d6368cdc84e1fc0 100644
--- a/dynare++/sylv/cc/GeneralSylvester.h
+++ b/dynare++/sylv/cc/GeneralSylvester.hh
@@ -5,10 +5,10 @@
 #ifndef GENERAL_SYLVESTER_H
 #define GENERAL_SYLVESTER_H
 
-#include "SylvMatrix.h"
-#include "SylvMemory.h"
-#include "SimilarityDecomp.h"
-#include "SylvesterSolver.h"
+#include "SylvMatrix.hh"
+#include "SylvMemory.hh"
+#include "SimilarityDecomp.hh"
+#include "SylvesterSolver.hh"
 
 class GeneralSylvester
 {
diff --git a/dynare++/sylv/cc/IterativeSylvester.cc b/dynare++/sylv/cc/IterativeSylvester.cc
new file mode 100644
index 0000000000000000000000000000000000000000..92fe05ab4885174dd6facecb354b46afd1f21fc5
--- /dev/null
+++ b/dynare++/sylv/cc/IterativeSylvester.cc
@@ -0,0 +1,57 @@
+/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/IterativeSylvester.cpp,v 1.1.1.1 2004/06/04 13:00:20 kamenik Exp $ */
+
+/* Tag $Name:  $ */
+
+#include "IterativeSylvester.hh"
+#include "KronUtils.hh"
+
+void
+IterativeSylvester::solve(SylvParams &pars, KronVector &x) const
+{
+  int max_steps = *(pars.max_num_iter);
+  int steps = 1;
+  double max_norm = *(pars.convergence_tol);
+  double norm = performFirstStep(x);
+
+  QuasiTriangular *kpow = matrixK->clone();
+  QuasiTriangular *fpow = matrixF->clone();
+  while (steps < max_steps &&norm > max_norm)
+    {
+      kpow->multRight(SqSylvMatrix(*kpow)); // be careful to make copy
+      fpow->multRight(SqSylvMatrix(*fpow)); // also here
+      norm = performStep(*kpow, *fpow, x);
+      steps++;
+    }
+
+  delete fpow;
+  delete kpow;
+
+  pars.converged = (norm <= max_norm);
+  pars.iter_last_norm = norm;
+  pars.num_iter = steps;
+}
+
+double
+IterativeSylvester::performFirstStep(KronVector &x) const
+{
+  KronVector xtmp((const KronVector &)x);
+  KronUtils::multKron(*matrixF, *matrixK, xtmp);
+  x.add(-1., xtmp);
+  double norm = xtmp.getMax();
+  return norm;
+}
+
+double
+IterativeSylvester::performStep(const QuasiTriangular &k, const QuasiTriangular &f,
+                                KronVector &x)
+{
+  KronVector xtmp((const KronVector &)x);
+  KronUtils::multKron(f, k, xtmp);
+  x.add(1.0, xtmp);
+  double norm = xtmp.getMax();
+  return norm;
+}
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/dynare++/sylv/cc/IterativeSylvester.cpp b/dynare++/sylv/cc/IterativeSylvester.cpp
deleted file mode 100644
index e585f655af909abb7df393dc0b6e98106b572067..0000000000000000000000000000000000000000
--- a/dynare++/sylv/cc/IterativeSylvester.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/IterativeSylvester.cpp,v 1.1.1.1 2004/06/04 13:00:20 kamenik Exp $ */
-
-/* Tag $Name:  $ */
-
-#include "IterativeSylvester.h"
-#include "KronUtils.h"
-
-void IterativeSylvester::solve(SylvParams& pars, KronVector& x) const
-{
-	int max_steps = *(pars.max_num_iter);
-	int steps = 1;
-	double max_norm = *(pars.convergence_tol);
-	double norm = performFirstStep(x);
-
-	QuasiTriangular* kpow = matrixK->clone();
-	QuasiTriangular* fpow = matrixF->clone();
-	while (steps < max_steps && norm > max_norm) {
-		kpow->multRight(SqSylvMatrix(*kpow)); // be careful to make copy
-		fpow->multRight(SqSylvMatrix(*fpow)); // also here
-		norm = performStep(*kpow, *fpow, x);
-		steps++;
-	}
-
-	delete fpow;
-	delete kpow;
-
-	pars.converged = (norm <= max_norm);
-	pars.iter_last_norm = norm;
-	pars.num_iter = steps;
-}
-
-double IterativeSylvester::performFirstStep(KronVector& x) const
-{
-	KronVector xtmp((const KronVector&)x);
-	KronUtils::multKron(*matrixF, *matrixK, xtmp);
-	x.add(-1., xtmp);
-	double norm = xtmp.getMax();
-	return norm;
-}
-
-double IterativeSylvester::performStep(const QuasiTriangular& k, const QuasiTriangular& f,
-									   KronVector& x)
-{
-	KronVector xtmp((const KronVector&)x);
-	KronUtils::multKron(f, k, xtmp);
-	x.add(1.0, xtmp);
-	double norm = xtmp.getMax();
-	return norm;
-}
-
-// Local Variables:
-// mode:C++
-// End:
diff --git a/dynare++/sylv/cc/IterativeSylvester.h b/dynare++/sylv/cc/IterativeSylvester.hh
similarity index 89%
rename from dynare++/sylv/cc/IterativeSylvester.h
rename to dynare++/sylv/cc/IterativeSylvester.hh
index 6e30d75d0939c1054176e9f1efcb81136f9ea3eb..3163f8fbb42d123d2424d18c12317eb1803c25fb 100644
--- a/dynare++/sylv/cc/IterativeSylvester.h
+++ b/dynare++/sylv/cc/IterativeSylvester.hh
@@ -5,10 +5,10 @@
 #ifndef ITERATIVE_SYLVESTER_H
 #define ITERATIVE_SYLVESTER_H
 
-#include "SylvesterSolver.h"
-#include "KronVector.h"
-#include "QuasiTriangular.h"
-#include "SimilarityDecomp.h"
+#include "SylvesterSolver.hh"
+#include "KronVector.hh"
+#include "QuasiTriangular.hh"
+#include "SimilarityDecomp.hh"
 
 class IterativeSylvester : public SylvesterSolver
 {
diff --git a/dynare++/sylv/cc/KronUtils.cc b/dynare++/sylv/cc/KronUtils.cc
new file mode 100644
index 0000000000000000000000000000000000000000..b3b9740bc9de6f12020d2ebf9ad6c05e034bb7e6
--- /dev/null
+++ b/dynare++/sylv/cc/KronUtils.cc
@@ -0,0 +1,73 @@
+/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/KronUtils.cpp,v 1.1.1.1 2004/06/04 13:00:31 kamenik Exp $ */
+
+/* Tag $Name:  $ */
+
+#include "KronUtils.hh"
+
+void
+KronUtils::multAtLevel(int level, const QuasiTriangular &t,
+                       KronVector &x)
+{
+  if (0 < level && level < x.getDepth())
+    {
+      for (int i = 0; i < x.getM(); i++)
+        {
+          KronVector xi(x, i);
+          multAtLevel(level, t, xi);
+        }
+    }
+  else if (0 == level && 0 < x.getDepth())
+    {
+      GeneralMatrix tmp(x.base(), x.getN(), power(x.getM(), x.getDepth()));
+      t.multLeftOther(tmp);
+    }
+  else if (0 == level && 0 == x.getDepth())
+    {
+      Vector b((const Vector &)x);
+      t.multVec(x, b);
+    }
+  else // 0 < level == depth
+    {
+      t.multKron(x);
+    }
+}
+
+void
+KronUtils::multAtLevelTrans(int level, const QuasiTriangular &t,
+                            KronVector &x)
+{
+  if (0 < level && level < x.getDepth())
+    {
+      for (int i = 0; i < x.getM(); i++)
+        {
+          KronVector xi(x, i);
+          multAtLevelTrans(level, t, xi);
+        }
+    }
+  else if (0 == level && 0 < x.getDepth())
+    {
+      GeneralMatrix tmp(x.base(), x.getN(), power(x.getM(), x.getDepth()));
+      t.multLeftOtherTrans(tmp);
+    }
+  else if (level == 0 && 0 == x.getDepth())
+    {
+      Vector b((const Vector &)x);
+      t.multVecTrans(x, b);
+    }
+  else // 0 < level == depth
+    {
+      t.multKronTrans(x);
+    }
+}
+
+void
+KronUtils::multKron(const QuasiTriangular &f, const QuasiTriangular &k,
+                    KronVector &x)
+{
+  multAtLevel(0, k, x);
+  if (x.getDepth() > 0)
+    {
+      for (int level = 1; level <= x.getDepth(); level++)
+        multAtLevelTrans(level, f, x);
+    }
+}
diff --git a/dynare++/sylv/cc/KronUtils.cpp b/dynare++/sylv/cc/KronUtils.cpp
deleted file mode 100644
index 013d16520537eba421a47a4edf6e9d592f6d723b..0000000000000000000000000000000000000000
--- a/dynare++/sylv/cc/KronUtils.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/KronUtils.cpp,v 1.1.1.1 2004/06/04 13:00:31 kamenik Exp $ */
-
-/* Tag $Name:  $ */
-
-#include "KronUtils.h"
-
-void KronUtils::multAtLevel(int level, const QuasiTriangular& t,
-							KronVector& x)
-{
-	if (0 < level && level < x.getDepth()) {
-		for (int i = 0; i < x.getM(); i++) {
-			KronVector xi(x, i);
-			multAtLevel(level, t, xi);
-		}
-	} else if (0 == level && 0 < x.getDepth()) {
-		GeneralMatrix tmp(x.base(), x.getN(), power(x.getM(),x.getDepth()));
-		t.multLeftOther(tmp);
-	} else if (0 == level && 0 == x.getDepth()) {
-		Vector b((const Vector&)x);
-		t.multVec(x,b);
-	} else { // 0 < level == depth
-		t.multKron(x);
-	}
-}
-
-void KronUtils::multAtLevelTrans(int level, const QuasiTriangular& t,
-								 KronVector& x)
-{
-	if (0 < level && level < x.getDepth()) {
-		for (int i = 0; i < x.getM(); i++) {
-			KronVector xi(x, i);
-			multAtLevelTrans(level, t, xi);
-		}
-	} else if (0 == level && 0 < x.getDepth()) {
-		GeneralMatrix tmp(x.base(), x.getN(), power(x.getM(),x.getDepth()));
-		t.multLeftOtherTrans(tmp);
-	} else if (level == 0 && 0 == x.getDepth()) {
-		Vector b((const Vector&)x);
-		t.multVecTrans(x,b);
-	} else { // 0 < level == depth
-		t.multKronTrans(x);
-	}
-}
-
-void KronUtils::multKron(const QuasiTriangular& f, const QuasiTriangular& k,
-						 KronVector& x)
-{
-	multAtLevel(0, k, x);
-	if (x.getDepth() > 0) {
-		for (int level = 1; level <= x.getDepth(); level++)
-			multAtLevelTrans(level, f, x);
-	}
-}
diff --git a/dynare++/sylv/cc/KronUtils.h b/dynare++/sylv/cc/KronUtils.hh
similarity index 94%
rename from dynare++/sylv/cc/KronUtils.h
rename to dynare++/sylv/cc/KronUtils.hh
index a0d2339f065bb9fe59a6c6b007cc05387549a0a4..0f4c11f2b8f1bd899228a03963b9c6b4c8e7c95d 100644
--- a/dynare++/sylv/cc/KronUtils.h
+++ b/dynare++/sylv/cc/KronUtils.hh
@@ -5,8 +5,8 @@
 #ifndef KRON_UTILS_H
 #define KRON_UTILS_H
 
-#include "KronVector.h"
-#include "QuasiTriangular.h"
+#include "KronVector.hh"
+#include "QuasiTriangular.hh"
 
 class KronUtils
 {
diff --git a/dynare++/sylv/cc/KronVector.cc b/dynare++/sylv/cc/KronVector.cc
new file mode 100644
index 0000000000000000000000000000000000000000..7897d571e8883a028ddef7f5660a99b310fc3bd7
--- /dev/null
+++ b/dynare++/sylv/cc/KronVector.cc
@@ -0,0 +1,121 @@
+/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/KronVector.cpp,v 1.1.1.1 2004/06/04 13:00:31 kamenik Exp $ */
+
+/* Tag $Name:  $ */
+
+#include "KronVector.hh"
+#include "SylvException.hh"
+
+int
+power(int m, int depth)
+{
+  int p = 1;
+  for (int i = 0; i < depth; i++)
+    {
+      p *= m;
+    }
+  return p;
+}
+
+KronVector::KronVector(int mm, int nn, int dp)
+  : Vector(power(mm, dp)*nn), m(mm), n(nn), depth(dp)
+{
+}
+
+KronVector::KronVector(Vector &v, int mm, int nn, int dp)
+  : Vector(v), m(mm), n(nn), depth(dp)
+{
+  len = power(m, depth)*n;
+  if (v.length() != length())
+    {
+      throw SYLV_MES_EXCEPTION("Bad conversion KronVector from Vector.");
+    }
+}
+
+KronVector::KronVector(KronVector &v, int i)
+  : Vector(v, i*power(v.m, v.depth-1)*v.n, power(v.m, v.depth-1)*v.n), m(v.m), n(v.n),
+    depth(v.depth-1)
+{
+  if (depth < 0)
+    {
+      throw SYLV_MES_EXCEPTION("Bad KronVector pick, depth < 0.");
+    }
+}
+
+KronVector::KronVector(const ConstKronVector &v)
+  : Vector(v.length()), m(v.getM()), n(v.getN()), depth(v.getDepth())
+{
+  Vector::operator=(v);
+}
+
+const KronVector &
+KronVector::operator=(const ConstKronVector &v)
+{
+  Vector::operator=(v);
+  m = v.getM();
+  n = v.getN();
+  depth = v.getDepth();
+  return *this;
+}
+
+const KronVector &
+KronVector::operator=(const Vector &v)
+{
+  if (length() != v.length())
+    {
+      throw SYLV_MES_EXCEPTION("Wrong lengths for vector operator =.");
+    }
+  Vector::operator=(v);
+  return *this;
+}
+
+ConstKronVector::ConstKronVector(const KronVector &v)
+  : ConstVector(v), m(v.getM()), n(v.getN()), depth(v.getDepth())
+{
+}
+
+ConstKronVector::ConstKronVector(const ConstKronVector &v)
+  : ConstVector(power(v.getM(), v.getDepth())*v.getN()), m(v.getM()), n(v.getN()),
+    depth(v.getDepth())
+{
+}
+
+ConstKronVector::ConstKronVector(const Vector &v, int mm, int nn, int dp)
+  : ConstVector(v), m(mm), n(nn), depth(dp)
+{
+  len = power(m, depth)*n;
+  if (v.length() != length())
+    {
+      throw SYLV_MES_EXCEPTION("Bad conversion KronVector from Vector.");
+    }
+}
+
+ConstKronVector::ConstKronVector(const ConstVector &v, int mm, int nn, int dp)
+  : ConstVector(v), m(mm), n(nn), depth(dp)
+{
+  len = power(m, depth)*n;
+  if (v.length() != length())
+    {
+      throw SYLV_MES_EXCEPTION("Bad conversion KronVector from Vector.");
+    }
+}
+
+ConstKronVector::ConstKronVector(const KronVector &v, int i)
+  : ConstVector(v, i*power(v.getM(), v.getDepth()-1)*v.getN(),
+                power(v.getM(), v.getDepth()-1)*v.getN()),
+    m(v.getM()), n(v.getN()), depth(v.getDepth()-1)
+{
+  if (depth < 0)
+    {
+      throw SYLV_MES_EXCEPTION("Bad KronVector pick, depth < 0.");
+    }
+}
+
+ConstKronVector::ConstKronVector(const ConstKronVector &v, int i)
+  : ConstVector(v, i*power(v.m, v.depth-1)*v.n, power(v.m, v.depth-1)*v.n),
+    m(v.getM()), n(v.getN()), depth(v.getDepth()-1)
+{
+  if (depth < 0)
+    {
+      throw SYLV_MES_EXCEPTION("Bad KronVector pick, depth < 0.");
+    }
+}
diff --git a/dynare++/sylv/cc/KronVector.cpp b/dynare++/sylv/cc/KronVector.cpp
deleted file mode 100644
index 71da28f7b6150b00167f83eb96ef0f17ee50e75a..0000000000000000000000000000000000000000
--- a/dynare++/sylv/cc/KronVector.cpp
+++ /dev/null
@@ -1,109 +0,0 @@
-/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/KronVector.cpp,v 1.1.1.1 2004/06/04 13:00:31 kamenik Exp $ */
-
-/* Tag $Name:  $ */
-
-#include "KronVector.h"
-#include "SylvException.h"
-
-int power(int m, int depth)
-{
-	int p = 1;
-	for (int i = 0; i < depth; i++) {
-		p *= m;
-	}
-	return p;
-}
-
-KronVector::KronVector(int mm, int nn, int dp)
-	: Vector(power(mm,dp)*nn), m(mm), n(nn), depth(dp)
-{}
-
-KronVector::KronVector(Vector& v, int mm, int nn, int dp)
-	: Vector(v), m(mm), n(nn), depth(dp)
-{
-	len = power(m,depth)*n;
-	if (v.length() != length()) {
-		throw SYLV_MES_EXCEPTION("Bad conversion KronVector from Vector.");
-	}
-}
-
-KronVector::KronVector(KronVector& v, int i)
-	: Vector(v, i*power(v.m,v.depth-1)*v.n, power(v.m, v.depth-1)*v.n), m(v.m), n(v.n),
-	  depth(v.depth-1)
-{
-	if (depth < 0) {
-		throw SYLV_MES_EXCEPTION("Bad KronVector pick, depth < 0.");
-	}
-}
-
-KronVector::KronVector(const ConstKronVector& v)
-	: Vector(v.length()), m(v.getM()), n(v.getN()), depth(v.getDepth())
-{
-	Vector::operator=(v);
-}
-
-const KronVector& KronVector::operator=(const ConstKronVector& v)
-{
-	Vector::operator=(v);
-	m=v.getM();
-	n=v.getN();
-	depth = v.getDepth();
-	return *this;
-}
-
-const KronVector& KronVector::operator=(const Vector& v)
-{
-	if (length() != v.length()) {
-		throw SYLV_MES_EXCEPTION("Wrong lengths for vector operator =.");
-	}
-	Vector::operator=(v);
-	return *this;
-}
-
-
-
-ConstKronVector::ConstKronVector(const KronVector& v)
-	: ConstVector(v), m(v.getM()), n(v.getN()), depth(v.getDepth())
-{}
-
-ConstKronVector::ConstKronVector(const ConstKronVector& v)
-	: ConstVector(power(v.getM(),v.getDepth())*v.getN()), m(v.getM()), n(v.getN()),
-	  depth(v.getDepth())	  
-{}
-
-ConstKronVector::ConstKronVector(const Vector& v, int mm, int nn, int dp)
-	: ConstVector(v), m(mm), n(nn), depth(dp)
-{
-	len = power(m,depth)*n;
-	if (v.length() != length()) {
-		throw SYLV_MES_EXCEPTION("Bad conversion KronVector from Vector.");
-	}
-}
-
-ConstKronVector::ConstKronVector(const ConstVector& v, int mm, int nn, int dp)
-	: ConstVector(v), m(mm), n(nn), depth(dp)
-{
-	len = power(m,depth)*n;
-	if (v.length() != length()) {
-		throw SYLV_MES_EXCEPTION("Bad conversion KronVector from Vector.");
-	}
-}
-
-ConstKronVector::ConstKronVector(const KronVector& v, int i)
-	: ConstVector(v, i*power(v.getM(),v.getDepth()-1)*v.getN(),
-				  power(v.getM(),v.getDepth()-1)*v.getN()),
-	  m(v.getM()), n(v.getN()), depth(v.getDepth()-1)
-{
-	if (depth < 0) {
-		throw SYLV_MES_EXCEPTION("Bad KronVector pick, depth < 0.");
-	}
-}
-
-ConstKronVector::ConstKronVector(const ConstKronVector& v, int i)
-	: ConstVector(v, i*power(v.m,v.depth-1)*v.n, power(v.m,v.depth-1)*v.n),
-	  m(v.getM()), n(v.getN()), depth(v.getDepth()-1)
-{
-	if (depth < 0) {
-		throw SYLV_MES_EXCEPTION("Bad KronVector pick, depth < 0.");
-	}
-}
diff --git a/dynare++/sylv/cc/KronVector.h b/dynare++/sylv/cc/KronVector.hh
similarity index 98%
rename from dynare++/sylv/cc/KronVector.h
rename to dynare++/sylv/cc/KronVector.hh
index dc8b6fb919e4f8fe598935d0d3cae29d53a1879d..b381288368849b5d79e02322983e52ea58139ca9 100644
--- a/dynare++/sylv/cc/KronVector.h
+++ b/dynare++/sylv/cc/KronVector.hh
@@ -5,7 +5,7 @@
 #ifndef KRON_VECTOR_H
 #define KRON_VECTOR_H
 
-#include "Vector.h"
+#include "Vector.hh"
 
 class ConstKronVector;
 
diff --git a/dynare++/sylv/cc/Makefile.am b/dynare++/sylv/cc/Makefile.am
index d84d3922e3c8bbed474cc5a10bc5229c2c0fe8ae..175e7f92ffb4fcdb3b86f7d3cb09a82bfb50440d 100644
--- a/dynare++/sylv/cc/Makefile.am
+++ b/dynare++/sylv/cc/Makefile.am
@@ -4,40 +4,40 @@ noinst_LIBRARIES = libsylv.a
 libsylv_a_CPPFLAGS = -I$(top_srcdir)/mex/sources
 
 libsylv_a_SOURCES = \
-	IterativeSylvester.cpp \
-	SylvMatrix.h \
-	QuasiTriangular.cpp \
-	QuasiTriangularZero.cpp \
-	TriangularSylvester.h \
-	GeneralMatrix.cpp \
-	SylvMemory.h \
-	SylvException.h \
-	GeneralSylvester.cpp \
-	GeneralMatrix.h \
-	Vector.h \
-	SchurDecompEig.h \
-	QuasiTriangularZero.h \
-	SimilarityDecomp.cpp \
-	BlockDiagonal.h \
-	SylvesterSolver.h \
-	SylvException.cpp \
-	SimilarityDecomp.h \
-	IterativeSylvester.h \
-	SchurDecompEig.cpp \
-	KronUtils.h \
-	Vector.cpp \
-	TriangularSylvester.cpp \
-	GeneralSylvester.h \
-	SylvParams.cpp \
-	SchurDecomp.h \
-	SymSchurDecomp.h \
-	BlockDiagonal.cpp \
-	SylvParams.h \
-	KronVector.cpp \
-	SylvMemory.cpp \
-	SymSchurDecomp.cpp \
-	SylvMatrix.cpp \
-	QuasiTriangular.h \
-	SchurDecomp.cpp \
-	KronVector.h \
-	KronUtils.cpp
+	BlockDiagonal.cc \
+	BlockDiagonal.hh \
+	GeneralMatrix.cc \
+	GeneralMatrix.hh \
+	GeneralSylvester.cc \
+	GeneralSylvester.hh \
+	IterativeSylvester.cc \
+	IterativeSylvester.hh \
+	KronUtils.cc \
+	KronUtils.hh \
+	KronVector.cc \
+	KronVector.hh \
+	QuasiTriangular.cc \
+	QuasiTriangular.hh \
+	QuasiTriangularZero.cc \
+	QuasiTriangularZero.hh \
+	SchurDecomp.cc \
+	SchurDecomp.hh \
+	SchurDecompEig.cc \
+	SchurDecompEig.hh \
+	SimilarityDecomp.cc \
+	SimilarityDecomp.hh \
+	SylvException.cc \
+	SylvException.hh \
+	SylvMatrix.cc \
+	SylvMatrix.hh \
+	SylvMemory.cc \
+	SylvMemory.hh \
+	SylvParams.cc \
+	SylvParams.hh \
+	SylvesterSolver.hh \
+	SymSchurDecomp.cc \
+	SymSchurDecomp.hh \
+	TriangularSylvester.cc \
+	TriangularSylvester.hh \
+	Vector.cc \
+	Vector.hh
diff --git a/dynare++/sylv/cc/QuasiTriangular.cc b/dynare++/sylv/cc/QuasiTriangular.cc
new file mode 100644
index 0000000000000000000000000000000000000000..ef502b50ad2a9814cdcdb92be87956f8789c7196
--- /dev/null
+++ b/dynare++/sylv/cc/QuasiTriangular.cc
@@ -0,0 +1,773 @@
+/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/QuasiTriangular.cpp,v 1.1.1.1 2004/06/04 13:00:31 kamenik Exp $ */
+
+/* Tag $Name:  $ */
+
+#include "QuasiTriangular.hh"
+#include "SylvException.hh"
+#include "SchurDecomp.hh"
+
+#include <dynblas.h>
+
+#include <cstdio>
+#include <cmath>
+
+using namespace std;
+
+double
+DiagonalBlock::getDeterminant() const
+{
+  return (*alpha)*(*alpha) + getSBeta();
+}
+
+double
+DiagonalBlock::getSBeta() const
+{
+  return -(*beta1)*(*beta2);
+}
+
+double
+DiagonalBlock::getSize() const
+{
+  if (real)
+    return abs(*alpha);
+  else
+    return sqrt(getDeterminant());
+}
+
+// this function makes Diagonal inconsistent, it should only be used
+// on temorary matrices, which will not be used any more, e.g. in
+// QuasiTriangular::solve (we need fast performance)
+void
+DiagonalBlock::setReal()
+{
+  *beta1 = 0;
+  *beta2 = 0;
+  real = true;
+}
+
+void
+DiagonalBlock::checkBlock(const double *d, int d_size)
+{
+  const double *a1 = d + jbar*d_size+jbar;
+  const double *b1 = a1 + d_size;
+  const double *b2 = a1 + 1;
+  const double *a2 = b1 + 1;
+  if (a1 != alpha.a1)
+    throw SYLV_MES_EXCEPTION("Bad alpha1.");
+  if (!real && b1 != beta1)
+    throw SYLV_MES_EXCEPTION("Bad beta1.");
+  if (!real && b2 != beta2)
+    throw SYLV_MES_EXCEPTION("Bad beta2.");
+  if (!real && a2 != alpha.a2)
+    throw SYLV_MES_EXCEPTION("Bad alpha2.");
+}
+
+Diagonal::Diagonal(double *data, int d_size)
+{
+  int nc = getNumComplex(data, d_size); // return nc <= d_size/2
+  num_all = d_size - nc;
+  num_real = d_size - 2*nc;
+
+  int jbar = 0;
+  int j = 0;
+  while (j < num_all)
+    {
+      int id = jbar*d_size + jbar; // index of diagonal block in data
+      int ill = id + 1; // index of element below the diagonal
+      int iur = id + d_size; // index of element right to diagonal
+      int idd = id + d_size + 1; // index of element next on diagonal
+      if ((jbar < d_size-1) && !isZero(data[ill]))
+        {
+          // it is not last column and we have nonzero below diagonal
+          DiagonalBlock b(jbar, false, &data[id], &data[idd],
+                          &data[iur], &data[ill]);
+          blocks.push_back(b);
+          jbar++;
+        }
+      else
+        {
+          // it is last column or we have zero below diagonal
+          DiagonalBlock b(jbar, true, &data[id], &data[id], NULL, NULL);
+          blocks.push_back(b);
+        }
+      jbar++;
+      j++;
+    }
+}
+
+Diagonal::Diagonal(double *data, const Diagonal &d)
+{
+  num_all = d.num_all;
+  num_real = d.num_real;
+  int d_size = d.getSize();
+  for (const_diag_iter it = d.begin(); it != d.end(); ++it)
+    {
+      const DiagonalBlock &dit = *it;
+      double *beta1 = NULL;
+      double *beta2 = NULL;
+      int id = dit.getIndex()*(d_size+1);
+      int idd = id;
+      if (!dit.isReal())
+        {
+          beta1 = &data[id+d_size];
+          beta2 = &data[id+1];
+          idd = id + d_size + 1;
+        }
+      DiagonalBlock b(dit.getIndex(), dit.isReal(),
+                      &data[id], &data[idd], beta1, beta2);
+      blocks.push_back(b);
+    }
+}
+
+void
+Diagonal::copy(const Diagonal &d)
+{
+  num_all = d.num_all;
+  num_real = d.num_real;
+  blocks = d.blocks;
+}
+
+int
+Diagonal::getNumComplex(const double *data, int d_size)
+{
+  int num_complex = 0;
+  int in = 1;
+  for (int i = 0; i < d_size-1; i++, in = in + d_size + 1)
+    {
+      if (!isZero(data[in]))
+        {
+          num_complex++;
+          if (in < d_size - 2 && !isZero(data[in + d_size +1]))
+            {
+              throw SYLV_MES_EXCEPTION("Matrix is not quasi-triangular");
+            }
+        }
+    }
+  return num_complex;
+}
+
+void
+Diagonal::changeBase(double *p)
+{
+  int d_size = getSize();
+  for (diag_iter it = begin(); it != end(); ++it)
+    {
+      const DiagonalBlock &b = *it;
+      int jbar = b.getIndex();
+      int base = d_size*jbar + jbar;
+      if (b.isReal())
+        {
+          DiagonalBlock bnew(jbar, true, &p[base], &p[base],
+                             NULL, NULL);
+          *it = bnew;
+        }
+      else
+        {
+          DiagonalBlock bnew(jbar, false, &p[base], &p[base+d_size+1],
+                             &p[base+d_size], &p[base+1]);
+          *it = bnew;
+        }
+    }
+}
+
+void
+Diagonal::getEigenValues(Vector &eig) const
+{
+  int d_size = getSize();
+  if (eig.length() != 2*d_size)
+    {
+      char mes[500];
+      sprintf(mes, "Wrong length of vector for eigenvalues len=%d, should be=%d.\n",
+              eig.length(), 2*d_size);
+      throw SYLV_MES_EXCEPTION(mes);
+    }
+  for (const_diag_iter it = begin(); it != end(); ++it)
+    {
+      const DiagonalBlock &b = *it;
+      int ind = b.getIndex();
+      eig[2*ind] = *(b.getAlpha());
+      if (b.isReal())
+        {
+          eig[2*ind+1] = 0.0;
+        }
+      else
+        {
+          double beta = sqrt(b.getSBeta());
+          eig[2*ind+1] = beta;
+          eig[2*ind+2] = eig[2*ind];
+          eig[2*ind+3] = -beta;
+        }
+    }
+}
+
+/* swaps logically blocks 'it', and '++it'. remember to move also
+ * addresses, alpha, beta1, beta2. This is a dirty (but most
+ * effective) way how to do it. */
+void
+Diagonal::swapLogically(diag_iter it)
+{
+  diag_iter itp = it;
+  ++itp;
+
+  if ((*it).isReal() && !(*itp).isReal())
+    {
+      // first is real, second is complex
+      double *d1 = (*it).alpha.a1;
+      double *d2 = (*itp).alpha.a1;
+      double *d3 = (*itp).alpha.a2;
+      // swap
+      DiagonalBlock new_it((*it).jbar, d1, d2);
+      *it = new_it;
+      DiagonalBlock new_itp((*itp).jbar+1, d3);
+      *itp = new_itp;
+    }
+  else if (!(*it).isReal() && (*itp).isReal())
+    {
+      // first is complex, second is real
+      double *d1 = (*it).alpha.a1;
+      double *d2 = (*it).alpha.a2;
+      double *d3 = (*itp).alpha.a1;
+      // swap
+      DiagonalBlock new_it((*it).jbar, d1);
+      *it = new_it;
+      DiagonalBlock new_itp((*itp).jbar-1, d2, d3);
+      *itp = new_itp;
+    }
+}
+
+void
+Diagonal::checkConsistency(diag_iter it)
+{
+  if (!(*it).isReal() && isZero((*it).getBeta2()))
+    {
+      (*it).getBeta2() = 0.0; // put exact zero
+      int jbar = (*it).getIndex();
+      double *d2 = (*it).alpha.a2;
+      (*it).alpha.a2 = (*it).alpha.a1;
+      (*it).real = true;
+      (*it).beta1 = 0;
+      (*it).beta2 = 0;
+      DiagonalBlock b(jbar+1, d2);
+      blocks.insert((++it).iter(), b);
+      num_real += 2;
+      num_all++;
+    }
+}
+
+double
+Diagonal::getAverageSize(diag_iter start, diag_iter end)
+{
+  double res = 0;
+  int num = 0;
+  for (diag_iter run = start; run != end; ++run)
+    {
+      num++;
+      res += (*run).getSize();
+    }
+  if (num > 0)
+    res = res/num;
+  return res;
+}
+
+Diagonal::diag_iter
+Diagonal::findClosestBlock(diag_iter start, diag_iter end, double a)
+{
+  diag_iter closest = start;
+  double minim = 1.0e100;
+  for (diag_iter run = start; run != end; ++run)
+    {
+      double dist = abs(a - (*run).getSize());
+      if (dist < minim)
+        {
+          minim = dist;
+          closest = run;
+        }
+    }
+  return closest;
+}
+
+Diagonal::diag_iter
+Diagonal::findNextLargerBlock(diag_iter start, diag_iter end, double a)
+{
+  diag_iter closest = start;
+  double minim = 1.0e100;
+  for (diag_iter run = start; run != end; ++run)
+    {
+      double dist = (*run).getSize() - a;
+      if ((0 <= dist) && (dist < minim))
+        {
+          minim = dist;
+          closest = run;
+        }
+    }
+  return closest;
+}
+
+void
+Diagonal::print() const
+{
+  printf("Num real: %d, num complex: %d\n", getNumReal(), getNumComplex());
+  for (const_diag_iter it = begin(); it != end(); ++it)
+    {
+      if ((*it).isReal())
+        {
+          printf("real: jbar=%d, alpha=%f\n", (*it).getIndex(), *((*it).getAlpha()));
+        }
+      else
+        {
+          printf("complex: jbar=%d, alpha=%f, beta1=%f, beta2=%f\n",
+                 (*it).getIndex(), *((*it).getAlpha()), (*it).getBeta1(), (*it).getBeta2());
+        }
+    }
+}
+
+double Diagonal::EPS = 1.0e-300;
+
+bool
+Diagonal::isZero(double p)
+{
+  return (abs(p) < EPS);
+}
+
+QuasiTriangular::const_col_iter
+QuasiTriangular::col_begin(const DiagonalBlock &b) const
+{
+  int jbar = b.getIndex();
+  int d_size = diagonal.getSize();
+  return const_col_iter(&getData()[jbar*d_size], d_size, b.isReal(), 0);
+}
+
+QuasiTriangular::col_iter
+QuasiTriangular::col_begin(const DiagonalBlock &b)
+{
+  int jbar = b.getIndex();
+  int d_size = diagonal.getSize();
+  return col_iter(&getData()[jbar*d_size], d_size, b.isReal(), 0);
+}
+
+QuasiTriangular::const_row_iter
+QuasiTriangular::row_begin(const DiagonalBlock &b) const
+{
+  int jbar = b.getIndex();
+  int d_size = diagonal.getSize();
+  int off = jbar*d_size+jbar+d_size;
+  int col = jbar+1;
+  if (!b.isReal())
+    {
+      off = off + d_size;
+      col++;
+    }
+  return const_row_iter(&getData()[off], d_size, b.isReal(), col);
+}
+
+QuasiTriangular::row_iter
+QuasiTriangular::row_begin(const DiagonalBlock &b)
+{
+  int jbar = b.getIndex();
+  int d_size = diagonal.getSize();
+  int off = jbar*d_size+jbar+d_size;
+  int col = jbar+1;
+  if (!b.isReal())
+    {
+      off = off + d_size;
+      col++;
+    }
+  return row_iter(&getData()[off], d_size, b.isReal(), col);
+}
+
+QuasiTriangular::const_col_iter
+QuasiTriangular::col_end(const DiagonalBlock &b) const
+{
+  int jbar = b.getIndex();
+  int d_size = diagonal.getSize();
+  return const_col_iter(getData().base()+jbar*d_size+jbar, d_size, b.isReal(),
+                        jbar);
+}
+
+QuasiTriangular::col_iter
+QuasiTriangular::col_end(const DiagonalBlock &b)
+{
+  int jbar = b.getIndex();
+  int d_size = diagonal.getSize();
+  return col_iter(&getData()[jbar*d_size+jbar], d_size, b.isReal(), jbar);
+}
+
+QuasiTriangular::const_row_iter
+QuasiTriangular::row_end(const DiagonalBlock &b) const
+{
+  int jbar = b.getIndex();
+  int d_size = diagonal.getSize();
+  return const_row_iter(&getData()[d_size*d_size+jbar], d_size, b.isReal(),
+                        d_size);
+}
+
+QuasiTriangular::row_iter
+QuasiTriangular::row_end(const DiagonalBlock &b)
+{
+  int jbar = b.getIndex();
+  int d_size = diagonal.getSize();
+  return row_iter(&getData()[d_size*d_size+jbar], d_size, b.isReal(), d_size);
+}
+
+QuasiTriangular::QuasiTriangular(double r, const QuasiTriangular &t)
+  : SqSylvMatrix(t.numRows()), diagonal(getData().base(), t.diagonal)
+{
+  setMatrix(r, t);
+}
+
+QuasiTriangular::QuasiTriangular(double r, const QuasiTriangular &t,
+                                 double rr, const QuasiTriangular &tt)
+  : SqSylvMatrix(t.numRows()), diagonal(getData().base(), t.diagonal)
+{
+  setMatrix(r, t);
+  addMatrix(rr, tt);
+}
+
+QuasiTriangular::QuasiTriangular(const QuasiTriangular &t)
+  : SqSylvMatrix(t), diagonal(getData().base(), t.diagonal)
+{
+}
+
+QuasiTriangular::QuasiTriangular(const double *d, int d_size)
+  : SqSylvMatrix(d, d_size), diagonal(getData().base(), d_size)
+{
+}
+
+QuasiTriangular::~QuasiTriangular()
+{
+}
+
+QuasiTriangular::QuasiTriangular(int p, const QuasiTriangular &t)
+  : SqSylvMatrix(t.numRows()), diagonal(getData().base(), t.diagonal)
+{
+  Vector aux(t.getData());
+  blas_int d_size = diagonal.getSize();
+  double alpha = 1.0;
+  double beta = 0.0;
+  dgemm("N", "N", &d_size, &d_size, &d_size, &alpha, aux.base(),
+        &d_size, t.getData().base(), &d_size, &beta, getData().base(), &d_size);
+}
+
+QuasiTriangular::QuasiTriangular(const SchurDecomp &decomp)
+  : SqSylvMatrix(decomp.getT()),
+    diagonal(getData().base(), decomp.getDim())
+{
+}
+
+/* this pads matrix with intial columns with zeros */
+QuasiTriangular::QuasiTriangular(const SchurDecompZero &decomp)
+  : SqSylvMatrix(decomp.getDim())
+{
+  // nullify first decomp.getZeroCols() columns
+  int zeros = decomp.getZeroCols()*decomp.getDim();
+  Vector zv(getData(), 0, zeros);
+  zv.zeros();
+  // fill right upper part with decomp.getRU()
+  for (int i = 0; i < decomp.getRU().numRows(); i++)
+    {
+      for (int j = 0; j < decomp.getRU().numCols(); j++)
+        {
+          getData()[(j+decomp.getZeroCols())*decomp.getDim()+i] = decomp.getRU().get(i, j);
+        }
+    }
+  // fill right lower part with decomp.getT()
+  for (int i = 0; i < decomp.getT().numRows(); i++)
+    {
+      for (int j = 0; j < decomp.getT().numCols(); j++)
+        {
+          getData()[(j+decomp.getZeroCols())*decomp.getDim()+decomp.getZeroCols()+i]
+            = decomp.getT().get(i, j);
+        }
+    }
+  // construct diagonal
+  Diagonal *const d = new Diagonal(getData().base(), decomp.getDim());
+  diagonal = *d;
+  delete d;
+}
+
+void
+QuasiTriangular::setMatrix(double r, const QuasiTriangular &t)
+{
+  getData().zeros();
+  getData().add(r, t.getData());
+}
+
+void
+QuasiTriangular::setMatrixViaIter(double r, const QuasiTriangular &t)
+{
+  register double rr = r;
+  diag_iter dil = diag_begin();
+  const_diag_iter dir = t.diag_begin();
+  for (; dil != diag_end(); ++dil, ++dir)
+    {
+      (*dil).getAlpha() = rr*(*(*dir).getAlpha());
+      if (!(*dil).isReal())
+        {
+          (*dil).getBeta1() = rr*(*dir).getBeta1();
+          (*dil).getBeta2() = rr*(*dir).getBeta2();
+        }
+      col_iter cil = col_begin(*dil);
+      const_col_iter cir = t.col_begin(*dir);
+      for (; cil != col_end(*dil); ++cil, ++cir)
+        {
+          if ((*dil).isReal())
+            {
+              *cil = rr*(*cir);
+            }
+          else
+            {
+              cil.a() = rr*cir.a();
+              cil.b() = rr*cir.b();
+            }
+        }
+    }
+}
+
+void
+QuasiTriangular::addMatrix(double r, const QuasiTriangular &t)
+{
+  getData().add(r, t.getData());
+}
+
+void
+QuasiTriangular::addMatrixViaIter(double r, const QuasiTriangular &t)
+{
+  register double rr = r;
+  diag_iter dil = diag_begin();
+  const_diag_iter dir = t.diag_begin();
+  for (; dil != diag_end(); ++dil, ++dir)
+    {
+      (*dil).getAlpha() = (*(*dil).getAlpha()) + rr*(*(*dir).getAlpha());
+      if (!(*dil).isReal())
+        {
+          (*dil).getBeta1() += rr*(*dir).getBeta1();
+          (*dil).getBeta2() += rr*(*dir).getBeta2();
+        }
+      col_iter cil = col_begin(*dil);
+      const_col_iter cir = t.col_begin(*dir);
+      for (; cil != col_end(*dil); ++cil, ++cir)
+        {
+          if ((*dil).isReal())
+            {
+              *cil += rr*(*cir);
+            }
+          else
+            {
+              cil.a() += rr*cir.a();
+              cil.b() += rr*cir.b();
+            }
+        }
+    }
+}
+
+void
+QuasiTriangular::addUnit()
+{
+  for (diag_iter di = diag_begin(); di != diag_end(); ++di)
+    {
+      (*di).getAlpha() = *((*di).getAlpha()) + 1.0;
+    }
+}
+
+void
+QuasiTriangular::solve(Vector &x, const ConstVector &b, double &eig_min)
+{
+  x = b;
+  solvePre(x, eig_min);
+}
+
+void
+QuasiTriangular::solveTrans(Vector &x, const ConstVector &b, double &eig_min)
+{
+  x = b;
+  solvePreTrans(x, eig_min);
+}
+
+void
+QuasiTriangular::solvePre(Vector &x, double &eig_min)
+{
+  addUnit();
+  for (diag_iter di = diag_begin(); di != diag_end(); ++di)
+    {
+      double eig_size;
+      if (!(*di).isReal())
+        {
+          eig_size = (*di).getDeterminant();
+          eliminateLeft((*di).getIndex()+1, (*di).getIndex(), x);
+        }
+      else
+        {
+          eig_size = *(*di).getAlpha()*(*(*di).getAlpha());
+        }
+      if (eig_size < eig_min)
+        eig_min = eig_size;
+    }
+
+  blas_int nn = diagonal.getSize();
+  blas_int lda = diagonal.getSize();
+  blas_int incx = x.skip();
+  dtrsv("U", "N", "N", &nn, getData().base(), &lda, x.base(), &incx);
+}
+
+void
+QuasiTriangular::solvePreTrans(Vector &x, double &eig_min)
+{
+  addUnit();
+  for (diag_iter di = diag_begin(); di != diag_end(); ++di)
+    {
+      double eig_size;
+      if (!(*di).isReal())
+        {
+          eig_size = (*di).getDeterminant();
+          eliminateRight((*di).getIndex()+1, (*di).getIndex(), x);
+        }
+      else
+        {
+          eig_size = *(*di).getAlpha()*(*(*di).getAlpha());
+        }
+      if (eig_size < eig_min)
+        eig_min = eig_size;
+    }
+
+  blas_int nn = diagonal.getSize();
+  blas_int lda = diagonal.getSize();
+  blas_int incx = x.skip();
+  dtrsv("U", "T", "N", &nn, getData().base(), &lda, x.base(), &incx);
+}
+
+/* calculates x = Tb */
+void
+QuasiTriangular::multVec(Vector &x, const ConstVector &b) const
+{
+  x = b;
+  blas_int nn = diagonal.getSize();
+  blas_int lda = diagonal.getSize();
+  blas_int incx = x.skip();
+  dtrmv("U", "N", "N", &nn, getData().base(), &lda, x.base(), &incx);
+  for (const_diag_iter di = diag_begin(); di != diag_end(); ++di)
+    {
+      if (!(*di).isReal())
+        {
+          int jbar = (*di).getIndex();
+          x[jbar+1] += (*di).getBeta2()*(b[jbar]);
+        }
+    }
+}
+
+void
+QuasiTriangular::multVecTrans(Vector &x, const ConstVector &b) const
+{
+  x = b;
+  blas_int nn = diagonal.getSize();
+  blas_int lda = diagonal.getSize();
+  blas_int incx = x.skip();
+  dtrmv("U", "T", "N", &nn, getData().base(), &lda, x.base(), &incx);
+  for (const_diag_iter di = diag_begin(); di != diag_end(); ++di)
+    {
+      if (!(*di).isReal())
+        {
+          int jbar = (*di).getIndex();
+          x[jbar] += (*di).getBeta2()*b[jbar+1];
+        }
+    }
+}
+
+void
+QuasiTriangular::multaVec(Vector &x, const ConstVector &b) const
+{
+  Vector tmp((const Vector &)x); // new copy
+  multVec(x, b);
+  x.add(1.0, tmp);
+}
+
+void
+QuasiTriangular::multaVecTrans(Vector &x, const ConstVector &b) const
+{
+  Vector tmp((const Vector &)x); // new copy
+  multVecTrans(x, b);
+  x.add(1.0, tmp);
+}
+
+/* calculates x=x+(T\otimes I)b, where size of I is given by b (KronVector) */
+void
+QuasiTriangular::multaKron(KronVector &x, const ConstKronVector &b) const
+{
+  int id = b.getN()*power(b.getM(), b.getDepth()-1);
+  ConstGeneralMatrix b_resh(b.base(), id, b.getM());
+  GeneralMatrix x_resh(x.base(), id, b.getM());
+  x_resh.multAndAdd(b_resh, ConstGeneralMatrix(*this), "trans");
+}
+
+/* calculates x=x+(T'\otimes I)b, where size of I is given by b (KronVector) */
+void
+QuasiTriangular::multaKronTrans(KronVector &x, const ConstKronVector &b) const
+{
+  int id = b.getN()*power(b.getM(), b.getDepth()-1);
+  ConstGeneralMatrix b_resh(b.base(), id, b.getM());
+  GeneralMatrix x_resh(x.base(), id, b.getM());
+  x_resh.multAndAdd(b_resh, ConstGeneralMatrix(*this));
+}
+
+void
+QuasiTriangular::multKron(KronVector &x) const
+{
+  KronVector b((const KronVector &)x); // make copy
+  x.zeros();
+  multaKron(x, b);
+}
+
+void
+QuasiTriangular::multKronTrans(KronVector &x) const
+{
+  KronVector b((const KronVector &)x); // make copy
+  x.zeros();
+  multaKronTrans(x, b);
+}
+
+void
+QuasiTriangular::multLeftOther(GeneralMatrix &a) const
+{
+  a.multLeft(*this);
+}
+
+void
+QuasiTriangular::multLeftOtherTrans(GeneralMatrix &a) const
+{
+  a.multLeftTrans(*this);
+}
+
+void
+QuasiTriangular::swapDiagLogically(diag_iter it)
+{
+  diagonal.swapLogically(it);
+}
+
+void
+QuasiTriangular::checkDiagConsistency(diag_iter it)
+{
+  diagonal.checkConsistency(it);
+}
+
+double
+QuasiTriangular::getAverageDiagSize(diag_iter start, diag_iter end)
+{
+  return diagonal.getAverageSize(start, end);
+}
+
+QuasiTriangular::diag_iter
+QuasiTriangular::findClosestDiagBlock(diag_iter start, diag_iter end, double a)
+{
+  return diagonal.findClosestBlock(start, end, a);
+}
+
+QuasiTriangular::diag_iter
+QuasiTriangular::findNextLargerBlock(diag_iter start, diag_iter end, double a)
+{
+  return diagonal.findNextLargerBlock(start, end, a);
+}
+
+int
+QuasiTriangular::getNumOffdiagonal() const
+{
+  return diagonal.getSize()*(diagonal.getSize()-1)/2 - diagonal.getNumComplex();
+}
diff --git a/dynare++/sylv/cc/QuasiTriangular.cpp b/dynare++/sylv/cc/QuasiTriangular.cpp
deleted file mode 100644
index d6b742f72d17684c3b6aa35f53c679b2d3865638..0000000000000000000000000000000000000000
--- a/dynare++/sylv/cc/QuasiTriangular.cpp
+++ /dev/null
@@ -1,682 +0,0 @@
-/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/QuasiTriangular.cpp,v 1.1.1.1 2004/06/04 13:00:31 kamenik Exp $ */
-
-/* Tag $Name:  $ */
-
-#include "QuasiTriangular.h"
-#include "SylvException.h"
-#include "SchurDecomp.h"
-
-#include <dynblas.h>
-
-#include <cstdio>
-#include <cmath>
-
-using namespace std;
-
-double DiagonalBlock::getDeterminant() const
-{
-	return (*alpha)*(*alpha) + getSBeta();
-}
-
-double DiagonalBlock::getSBeta() const
-{
-	return -(*beta1)*(*beta2);
-}
-
-double DiagonalBlock::getSize() const
-{
-	if (real)
-		return abs(*alpha);
-	else
-		return sqrt(getDeterminant());
-}
-
-// this function makes Diagonal inconsistent, it should only be used
-// on temorary matrices, which will not be used any more, e.g. in
-// QuasiTriangular::solve (we need fast performance)
-void DiagonalBlock::setReal()
-{
-	*beta1 = 0;
-	*beta2 = 0;
-	real = true;
-}
-
-void DiagonalBlock::checkBlock(const double* d, int d_size)
-{
-	const double* a1 = d + jbar*d_size+jbar;
-	const double* b1 = a1 + d_size;
-	const double* b2 = a1 + 1;
-	const double* a2 = b1 + 1;
-	if (a1 != alpha.a1)
-		throw SYLV_MES_EXCEPTION("Bad alpha1.");
-	if (!real && b1 != beta1)
-		throw SYLV_MES_EXCEPTION("Bad beta1.");
-	if (!real && b2 != beta2)
-		throw SYLV_MES_EXCEPTION("Bad beta2.");
-	if (!real && a2 != alpha.a2)
-		throw SYLV_MES_EXCEPTION("Bad alpha2.");
-}
-
-Diagonal::Diagonal(double* data, int d_size)
-{
-	int nc = getNumComplex(data, d_size); // return nc <= d_size/2
-	num_all = d_size - nc;
-	num_real = d_size - 2*nc;
-
-	int jbar = 0;
-	int j = 0;
-	while (j < num_all) {		
-		int id = jbar*d_size + jbar; // index of diagonal block in data
-		int ill = id + 1; // index of element below the diagonal
-		int iur = id + d_size; // index of element right to diagonal
-		int idd = id + d_size + 1; // index of element next on diagonal
-		if ((jbar < d_size-1) && !isZero(data[ill])) {
-			// it is not last column and we have nonzero below diagonal
-			DiagonalBlock b(jbar, false, &data[id], &data[idd],
-							&data[iur], &data[ill]);
-			blocks.push_back(b);
-			jbar++;
-		} else {
-			// it is last column or we have zero below diagonal
-			DiagonalBlock b(jbar, true, &data[id], &data[id], NULL, NULL);
-			blocks.push_back(b);
-		}
-		jbar++;
-		j++;
-	}
-}
-
-
-Diagonal::Diagonal(double* data, const Diagonal& d)
-{
-	num_all = d.num_all;
-	num_real = d.num_real;
-	int d_size = d.getSize();
-	for (const_diag_iter it = d.begin(); it != d.end(); ++it) {
-		const DiagonalBlock& dit = *it;
-		double* beta1 = NULL;
-		double* beta2 = NULL;
-		int id = dit.getIndex()*(d_size+1);
-		int idd = id;
-		if (! dit.isReal()) {
-			beta1 = &data[id+d_size];
-			beta2 = &data[id+1];
-			idd = id + d_size + 1;
-		}
-		DiagonalBlock b(dit.getIndex(), dit.isReal(),
-						&data[id], &data[idd], beta1, beta2);
-		blocks.push_back(b);
-	}
-}
-
-
-void Diagonal::copy(const Diagonal& d)
-{
-	num_all = d.num_all;
-	num_real = d.num_real;
-	blocks = d.blocks;
-}
-
-int Diagonal::getNumComplex(const double* data, int d_size)
-{
-	int num_complex = 0;
-	int in = 1;
-	for (int i = 0; i < d_size-1; i++, in = in + d_size + 1) {
-		if (! isZero(data[in])) {
-			num_complex++;
-			if (in < d_size - 2 && ! isZero(data[in + d_size +1])) {
-				throw SYLV_MES_EXCEPTION("Matrix is not quasi-triangular");
-			}
-		}
-	}
-	return num_complex;
-}
-
-void Diagonal::changeBase(double* p)
-{
-	int d_size = getSize();
-	for (diag_iter it = begin(); it != end(); ++it) {
-		const DiagonalBlock& b = *it;
-		int jbar = b.getIndex();
-		int base = d_size*jbar + jbar;
-		if (b.isReal()) {
-			DiagonalBlock bnew(jbar, true, &p[base], &p[base],
-							   NULL, NULL);
-			*it = bnew;
-		} else {
-			DiagonalBlock bnew(jbar, false, &p[base], &p[base+d_size+1],
-							   &p[base+d_size], &p[base+1]);
-			*it = bnew;			
-		}
-	}
-}
-
-void Diagonal::getEigenValues(Vector& eig) const
-{
-	int d_size = getSize();
-	if (eig.length() != 2*d_size) {
-		char mes[500];
-		sprintf(mes, "Wrong length of vector for eigenvalues len=%d, should be=%d.\n",
-				eig.length(), 2*d_size);
-		throw SYLV_MES_EXCEPTION(mes);
-	}
-	for (const_diag_iter it = begin(); it != end(); ++it) {
-		const DiagonalBlock& b = *it;
-		int ind = b.getIndex();
-		eig[2*ind] = *(b.getAlpha());
-		if (b.isReal()) {
-			eig[2*ind+1] = 0.0;
-		} else {
-			double beta = sqrt(b.getSBeta());
-			eig[2*ind+1] = beta;
-			eig[2*ind+2] = eig[2*ind];
-			eig[2*ind+3] = -beta;
-		}
-	}
-}
-
-/* swaps logically blocks 'it', and '++it'. remember to move also
- * addresses, alpha, beta1, beta2. This is a dirty (but most
- * effective) way how to do it. */
-void Diagonal::swapLogically(diag_iter it)
-{
-	diag_iter itp = it;
-	++itp;
-
-	if ((*it).isReal() && !(*itp).isReal()) {
-		// first is real, second is complex
-		double* d1 = (*it).alpha.a1;
-		double* d2 = (*itp).alpha.a1;
-		double* d3 = (*itp).alpha.a2;
-		// swap
-		DiagonalBlock new_it((*it).jbar, d1, d2);
-		*it = new_it;
-		DiagonalBlock new_itp((*itp).jbar+1, d3);
-		*itp = new_itp;
-	} else if (!(*it).isReal() && (*itp).isReal()) {
-		// first is complex, second is real
-		double* d1 = (*it).alpha.a1;
-		double* d2 = (*it).alpha.a2;
-		double* d3 = (*itp).alpha.a1;
-		// swap
-		DiagonalBlock new_it((*it).jbar, d1);
-		*it = new_it;
-		DiagonalBlock new_itp((*itp).jbar-1, d2, d3);
-		*itp = new_itp;
-	}
-}
-
-void Diagonal::checkConsistency(diag_iter it)
-{
-	if (!(*it).isReal() && isZero((*it).getBeta2())) {
-		(*it).getBeta2() = 0.0; // put exact zero
-		int jbar = (*it).getIndex();
-		double* d2 = (*it).alpha.a2;
-		(*it).alpha.a2 = (*it).alpha.a1;
-		(*it).real = true;
-		(*it).beta1 = 0;
-		(*it).beta2 = 0;
-		DiagonalBlock b(jbar+1, d2);
-		blocks.insert((++it).iter(), b);
-		num_real += 2;
-		num_all++;
-	}		
-}
-
-double Diagonal::getAverageSize(diag_iter start, diag_iter end)
-{
-	double res = 0;
-	int num = 0;
-	for (diag_iter run = start; run != end; ++run) {
-		num++;
-		res += (*run).getSize();
-	}
-	if (num > 0)
-		res = res/num;
-	return res;
-}
-
-Diagonal::diag_iter Diagonal::findClosestBlock(diag_iter start, diag_iter end, double a)
-{
-	diag_iter closest = start;
-	double minim = 1.0e100;
-	for (diag_iter run = start; run != end; ++run) {
-		double dist = abs(a - (*run).getSize());
-		if (dist < minim) {
-			minim = dist;
-			closest = run;
-		}
-	}
-	return closest;
-}
-
-Diagonal::diag_iter Diagonal::findNextLargerBlock(diag_iter start, diag_iter end, double a)
-{
-	diag_iter closest = start;
-	double minim = 1.0e100;
-	for (diag_iter run = start; run != end; ++run) {
-		double dist = (*run).getSize() - a;
-		if ((0 <= dist) && (dist < minim)) {
-			minim = dist;
-			closest = run;
-		}
-	}
-	return closest;
-}	
-
-void Diagonal::print() const
-{
-	printf("Num real: %d, num complex: %d\n",getNumReal(), getNumComplex());
-	for (const_diag_iter it = begin(); it != end(); ++it) {
-		if ((*it).isReal()) {
-			printf("real: jbar=%d, alpha=%f\n", (*it).getIndex(), *((*it).getAlpha()));
-		}
-		else {
-			printf("complex: jbar=%d, alpha=%f, beta1=%f, beta2=%f\n",
-				   (*it).getIndex(), *((*it).getAlpha()), (*it).getBeta1(), (*it).getBeta2());
-		}
-	}
-}
-
-double Diagonal::EPS = 1.0e-300;
-
-bool Diagonal::isZero(double p)
-{
-	return (abs(p)<EPS);
-}
-
-
-QuasiTriangular::const_col_iter
-QuasiTriangular::col_begin(const DiagonalBlock& b) const
-{
-	int jbar = b.getIndex();
-	int d_size = diagonal.getSize();
-	return const_col_iter(&getData()[jbar*d_size], d_size, b.isReal(), 0);
-}
-
-QuasiTriangular::col_iter
-QuasiTriangular::col_begin(const DiagonalBlock& b)
-{
-	int jbar = b.getIndex();
-	int d_size = diagonal.getSize();
-	return col_iter(&getData()[jbar*d_size], d_size, b.isReal(), 0);
-}
-
-QuasiTriangular::const_row_iter
-QuasiTriangular::row_begin(const DiagonalBlock& b) const
-{
-	int jbar = b.getIndex();
-	int d_size = diagonal.getSize();
-	int off = jbar*d_size+jbar+d_size;
-	int col = jbar+1;
-	if (!b.isReal()) {
-		off = off + d_size;
-		col++;
-	}
-	return const_row_iter(&getData()[off], d_size, b.isReal(), col);
-}
-
-
-QuasiTriangular::row_iter
-QuasiTriangular::row_begin(const DiagonalBlock& b)
-{
-	int jbar = b.getIndex();
-	int d_size = diagonal.getSize();
-	int off = jbar*d_size+jbar+d_size;
-	int col = jbar+1;
-	if (!b.isReal()) {
-		off = off + d_size;
-		col++;
-	}
-	return row_iter(&getData()[off], d_size, b.isReal(), col);
-}
-
-QuasiTriangular::const_col_iter
-QuasiTriangular::col_end(const DiagonalBlock& b) const
-{
-	int jbar = b.getIndex();
-	int d_size = diagonal.getSize();
-	return const_col_iter(getData().base()+jbar*d_size+jbar, d_size, b.isReal(),
-						  jbar);
-}
-
-QuasiTriangular::col_iter
-QuasiTriangular::col_end(const DiagonalBlock& b)
-{
-	int jbar = b.getIndex();
-	int d_size = diagonal.getSize();
-	return col_iter(&getData()[jbar*d_size+jbar], d_size, b.isReal(), jbar);
-}
-
-QuasiTriangular::const_row_iter
-QuasiTriangular::row_end(const DiagonalBlock& b) const
-{
-	int jbar = b.getIndex();
-	int d_size = diagonal.getSize();
-	return const_row_iter(&getData()[d_size*d_size+jbar], d_size, b.isReal(),
-						  d_size);
-}
-
-QuasiTriangular::row_iter
-QuasiTriangular::row_end(const DiagonalBlock& b)
-{
-	int jbar = b.getIndex();
-	int d_size = diagonal.getSize();
-	return row_iter(&getData()[d_size*d_size+jbar], d_size, b.isReal(), d_size);
-}
-
-QuasiTriangular::QuasiTriangular(double r, const QuasiTriangular& t)
-	: SqSylvMatrix(t.numRows()), diagonal(getData().base(), t.diagonal)
-{
-	setMatrix(r, t);
-}
-
-QuasiTriangular::QuasiTriangular(double r, const QuasiTriangular& t,
-								 double rr, const QuasiTriangular& tt)
-	: SqSylvMatrix(t.numRows()), diagonal(getData().base(), t.diagonal)
-{
-	setMatrix(r, t);
-	addMatrix(rr, tt);
-}
-
-QuasiTriangular::QuasiTriangular(const QuasiTriangular& t)
-	: SqSylvMatrix(t), diagonal(getData().base(), t.diagonal)
-{
-}
-
-QuasiTriangular::QuasiTriangular(const double* d, int d_size)
-	: SqSylvMatrix(d, d_size), diagonal(getData().base(), d_size)
-{}
-
-QuasiTriangular::~QuasiTriangular()
-{
-}
-
-QuasiTriangular::QuasiTriangular(int p, const QuasiTriangular& t)
-	: SqSylvMatrix(t.numRows()), diagonal(getData().base(), t.diagonal)
-{
-	Vector aux(t.getData());
-	blas_int d_size = diagonal.getSize();
-	double alpha = 1.0;
-	double beta = 0.0;
-	dgemm("N", "N", &d_size, &d_size, &d_size, &alpha, aux.base(),
-			   &d_size, t.getData().base(), &d_size, &beta, getData().base(), &d_size);
-}
-
-QuasiTriangular::QuasiTriangular(const SchurDecomp& decomp)
-	: SqSylvMatrix(decomp.getT()),
-	  diagonal(getData().base(), decomp.getDim())
-{
-}
-
-/* this pads matrix with intial columns with zeros */
-QuasiTriangular::QuasiTriangular(const SchurDecompZero& decomp)
-	: SqSylvMatrix(decomp.getDim())
-{
-	// nullify first decomp.getZeroCols() columns
-	int zeros = decomp.getZeroCols()*decomp.getDim();
-	Vector zv(getData(), 0, zeros);
-	zv.zeros();
-	// fill right upper part with decomp.getRU()
-	for (int i = 0; i < decomp.getRU().numRows(); i++) {
-		for (int j = 0; j < decomp.getRU().numCols(); j++) {
-			getData()[(j+decomp.getZeroCols())*decomp.getDim()+i] = decomp.getRU().get(i,j);
-		}
-	}
-	// fill right lower part with decomp.getT()
-	for (int i = 0; i < decomp.getT().numRows(); i++) {
-		for (int j = 0; j < decomp.getT().numCols(); j++) {
-			getData()[(j+decomp.getZeroCols())*decomp.getDim()+decomp.getZeroCols()+i] = 
-				decomp.getT().get(i,j);
-		}
-	}
-	// construct diagonal
-	Diagonal* const d = new Diagonal(getData().base(), decomp.getDim());
-	diagonal = *d;
-	delete d;
-}
-
-void QuasiTriangular::setMatrix(double r, const QuasiTriangular& t)
-{
-	getData().zeros();
-	getData().add(r, t.getData());
-}
-
-void QuasiTriangular::setMatrixViaIter(double r, const QuasiTriangular& t)
-{
-	register double rr = r;
-	diag_iter dil = diag_begin();
-	const_diag_iter dir = t.diag_begin();
-	for ( ; dil != diag_end(); ++dil, ++dir) {
-		(*dil).getAlpha() = rr*(*(*dir).getAlpha());
-		if (! (*dil).isReal()) {
-			(*dil).getBeta1() = rr*(*dir).getBeta1();
-			(*dil).getBeta2() = rr*(*dir).getBeta2();
-		}
-		col_iter cil = col_begin(*dil);
-		const_col_iter cir = t.col_begin(*dir);
-		for ( ; cil != col_end(*dil); ++cil, ++cir) {
-			if ((*dil).isReal()) {
-				*cil = rr*(*cir);
-			} else {
-				cil.a() = rr*cir.a();
-				cil.b() = rr*cir.b();
-			}
-		}
-	}
-}
-
-void QuasiTriangular::addMatrix(double r, const QuasiTriangular& t)
-{
-	getData().add(r, t.getData());
-}
-
-void QuasiTriangular::addMatrixViaIter(double r, const QuasiTriangular& t)
-{
-	register double rr = r;
-	diag_iter dil = diag_begin();
-	const_diag_iter dir = t.diag_begin();
-	for ( ; dil != diag_end(); ++dil, ++dir) {
-		(*dil).getAlpha() = (*(*dil).getAlpha()) + rr*(*(*dir).getAlpha());
-		if (! (*dil).isReal()) {
-			(*dil).getBeta1() += rr*(*dir).getBeta1();
-			(*dil).getBeta2() += rr*(*dir).getBeta2();
-		}
-		col_iter cil = col_begin(*dil);
-		const_col_iter cir = t.col_begin(*dir);
-		for ( ; cil != col_end(*dil); ++cil, ++cir) {
-			if ((*dil).isReal()) {
-				*cil += rr*(*cir);
-			} else {
-				cil.a() += rr*cir.a();
-				cil.b() += rr*cir.b();
-			}
-		}
-	}
-}
-
-void QuasiTriangular::addUnit()
-{
-	for (diag_iter di = diag_begin(); di != diag_end(); ++di) {
-		(*di).getAlpha() = *((*di).getAlpha()) + 1.0;
-	}
-}
-
-void QuasiTriangular::solve(Vector& x, const ConstVector& b, double& eig_min)
-{
-	x = b;
-	solvePre(x, eig_min);
-}
-
-void QuasiTriangular::solveTrans(Vector& x, const ConstVector& b, double& eig_min)
-{
-	x = b;
-	solvePreTrans(x, eig_min);
-}
-
-void QuasiTriangular::solvePre(Vector& x, double& eig_min)
-{
-	addUnit();
-	for (diag_iter di = diag_begin(); di != diag_end(); ++di) {
-		double eig_size;
-		if (!(*di).isReal()) {
-			eig_size = (*di).getDeterminant();
-			eliminateLeft((*di).getIndex()+1, (*di).getIndex(), x);
-		} else {
-			eig_size = *(*di).getAlpha()*(*(*di).getAlpha());
-		}
-		if (eig_size < eig_min)
-			eig_min = eig_size;
-	}
-
-	blas_int nn = diagonal.getSize();
-	blas_int lda = diagonal.getSize();
-	blas_int incx = x.skip();
-	dtrsv("U", "N", "N", &nn, getData().base(), &lda, x.base(), &incx);
-}
-
-void QuasiTriangular::solvePreTrans(Vector& x, double& eig_min)
-{
-	addUnit();
-	for (diag_iter di = diag_begin(); di != diag_end(); ++di) {
-		double eig_size;
-		if (!(*di).isReal()) {
-			eig_size = (*di).getDeterminant();
-			eliminateRight((*di).getIndex()+1, (*di).getIndex(), x);
-		} else {
-			eig_size = *(*di).getAlpha()*(*(*di).getAlpha());
-		}
-		if (eig_size < eig_min)
-			eig_min = eig_size;
-	}
-	
-	blas_int nn = diagonal.getSize();
-	blas_int lda = diagonal.getSize();
-	blas_int incx = x.skip();
-	dtrsv("U", "T", "N", &nn, getData().base(), &lda, x.base(), &incx);
-}
-
-
-/* calculates x = Tb */
-void QuasiTriangular::multVec(Vector& x, const ConstVector& b) const
-{
-	x = b;
-	blas_int nn = diagonal.getSize();
-	blas_int lda = diagonal.getSize();
-	blas_int incx = x.skip();
-	dtrmv("U", "N", "N", &nn, getData().base(), &lda, x.base(), &incx);
-	for (const_diag_iter di = diag_begin(); di != diag_end(); ++di) {
-		if (!(*di).isReal()) {
-			int jbar = (*di).getIndex();
-			x[jbar+1] += (*di).getBeta2()*(b[jbar]);
-		}
-	}
-}
-
-
-void QuasiTriangular::multVecTrans(Vector& x, const ConstVector& b) const
-{
-	x = b;
-	blas_int nn = diagonal.getSize();
-	blas_int lda = diagonal.getSize();
-	blas_int incx = x.skip();
-	dtrmv("U", "T", "N", &nn, getData().base(), &lda, x.base(), &incx);
-	for (const_diag_iter di = diag_begin(); di != diag_end(); ++di) {
-		if (!(*di).isReal()) {
-			int jbar = (*di).getIndex();
-			x[jbar] += (*di).getBeta2()*b[jbar+1];
-		}
-	}	
-}
-
-void QuasiTriangular::multaVec(Vector& x, const ConstVector& b) const
-{
-	Vector tmp((const Vector&) x); // new copy
-	multVec(x, b);
-	x.add(1.0, tmp);
-}
-
-void QuasiTriangular::multaVecTrans(Vector& x, const ConstVector& b) const
-{
-	Vector tmp((const Vector&) x); // new copy
-	multVecTrans(x, b);
-	x.add(1.0, tmp);
-}
-
-/* calculates x=x+(T\otimes I)b, where size of I is given by b (KronVector) */
-void QuasiTriangular::multaKron(KronVector& x, const ConstKronVector& b) const
-{
-	int id = b.getN()*power(b.getM(), b.getDepth()-1);
-	ConstGeneralMatrix b_resh(b.base(), id, b.getM());
-	GeneralMatrix x_resh(x.base(), id, b.getM());
-	x_resh.multAndAdd(b_resh, ConstGeneralMatrix(*this), "trans");
-}
-
-
-/* calculates x=x+(T'\otimes I)b, where size of I is given by b (KronVector) */
-void
-QuasiTriangular::multaKronTrans(KronVector& x, const ConstKronVector& b) const
-{
-	int id = b.getN()*power(b.getM(), b.getDepth()-1);
-	ConstGeneralMatrix b_resh(b.base(), id, b.getM());
-	GeneralMatrix x_resh(x.base(), id, b.getM());
-	x_resh.multAndAdd(b_resh, ConstGeneralMatrix(*this));
-}
-
-
-void QuasiTriangular::multKron(KronVector& x) const
-{
-	KronVector b((const KronVector&)x); // make copy
-	x.zeros();
-	multaKron(x, b);
-}
-
-void
-QuasiTriangular::multKronTrans(KronVector& x) const
-{
-	KronVector b((const KronVector&)x); // make copy
-	x.zeros();
-	multaKronTrans(x, b);
-}
-
-void QuasiTriangular::multLeftOther(GeneralMatrix& a) const
-{
-	a.multLeft(*this);
-}
-
-void QuasiTriangular::multLeftOtherTrans(GeneralMatrix& a) const
-{
-	a.multLeftTrans(*this);
-}
-
-void QuasiTriangular::swapDiagLogically(diag_iter it)
-{
-	diagonal.swapLogically(it);
-}
-
-void QuasiTriangular::checkDiagConsistency(diag_iter it)
-{
-	diagonal.checkConsistency(it);
-}
-
-double QuasiTriangular::getAverageDiagSize(diag_iter start, diag_iter end)
-{
-	return diagonal.getAverageSize(start, end);
-}
-
-QuasiTriangular::diag_iter
-QuasiTriangular::findClosestDiagBlock(diag_iter start, diag_iter end, double a)
-{
-	return diagonal.findClosestBlock(start, end, a);
-}
-
-QuasiTriangular::diag_iter
-QuasiTriangular::findNextLargerBlock(diag_iter start, diag_iter end, double a)
-{
-	return diagonal.findNextLargerBlock(start, end, a);
-}
-
-int QuasiTriangular::getNumOffdiagonal() const
-{
-	return 	diagonal.getSize()*(diagonal.getSize()-1)/2 - diagonal.getNumComplex();
-}
diff --git a/dynare++/sylv/cc/QuasiTriangular.h b/dynare++/sylv/cc/QuasiTriangular.hh
similarity index 99%
rename from dynare++/sylv/cc/QuasiTriangular.h
rename to dynare++/sylv/cc/QuasiTriangular.hh
index d09fede07021373f32389ee2bb204c01943c4bae..6794f8e6db4bedd2415d2061d2e18a32c50cb50e 100644
--- a/dynare++/sylv/cc/QuasiTriangular.h
+++ b/dynare++/sylv/cc/QuasiTriangular.hh
@@ -5,9 +5,9 @@
 #ifndef QUASI_TRIANGULAR_H
 #define QUASI_TRIANGULAR_H
 
-#include "Vector.h"
-#include "KronVector.h"
-#include "SylvMatrix.h"
+#include "Vector.hh"
+#include "KronVector.hh"
+#include "SylvMatrix.hh"
 
 #include <list>
 
diff --git a/dynare++/sylv/cc/QuasiTriangularZero.cc b/dynare++/sylv/cc/QuasiTriangularZero.cc
new file mode 100644
index 0000000000000000000000000000000000000000..737736b30cb101e945da643be48f767bd7e4d875
--- /dev/null
+++ b/dynare++/sylv/cc/QuasiTriangularZero.cc
@@ -0,0 +1,157 @@
+/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/QuasiTriangularZero.cpp,v 1.1.1.1 2004/06/04 13:00:44 kamenik Exp $ */
+
+/* Tag $Name:  $ */
+
+#include "QuasiTriangularZero.hh"
+#include "SchurDecomp.hh"
+#include "SylvMatrix.hh"
+#include "SylvException.hh"
+
+#include <cstdio>
+
+QuasiTriangularZero::QuasiTriangularZero(int num_zeros, const double *d,
+                                         int d_size)
+  : QuasiTriangular(SqSylvMatrix(GeneralMatrix(d, num_zeros+d_size, d_size),
+                                 num_zeros, 0, d_size).getData().base(),
+                    d_size),
+    nz(num_zeros),
+    ru(GeneralMatrix(d, num_zeros+d_size, d_size), 0, 0, num_zeros, d_size)
+{
+}
+
+QuasiTriangularZero::QuasiTriangularZero(double r,
+                                         const QuasiTriangularZero &t)
+  : QuasiTriangular(r, t),
+    nz(t.nz),
+    ru(t.ru)
+{
+  ru.mult(r);
+}
+
+QuasiTriangularZero::QuasiTriangularZero(double r,
+                                         const QuasiTriangularZero &t,
+                                         double rr,
+                                         const QuasiTriangularZero &tt)
+  : QuasiTriangular(r, t, rr, tt),
+    nz(t.nz),
+    ru(t.ru)
+{
+  ru.mult(r);
+  ru.add(rr, tt.ru);
+}
+
+QuasiTriangularZero::QuasiTriangularZero(int p, const QuasiTriangularZero &t)
+  : QuasiTriangular(p, t),
+    nz(t.nz),
+    ru(t.ru)
+{
+  ru.multRight(t);
+}
+
+QuasiTriangularZero::QuasiTriangularZero(const SchurDecompZero &decomp)
+  : QuasiTriangular(decomp.getT().getData().base(),
+                    decomp.getT().numRows()),
+    nz(decomp.getZeroCols()),
+    ru(decomp.getRU())
+{
+}
+
+QuasiTriangularZero::QuasiTriangularZero(const QuasiTriangular &t)
+  : QuasiTriangular(t),
+    nz(0), ru(0, t.getDiagonal().getSize())
+{
+}
+
+QuasiTriangularZero::~QuasiTriangularZero()
+{
+}
+
+void
+QuasiTriangularZero::solvePre(Vector &x, double &eig_min)
+{
+  Vector xu(x, 0, nz);
+  Vector xl(x, nz, x.length()-nz);
+  QuasiTriangular::solvePre(xl, eig_min);
+  ru.multsVec(xu, xl);
+  if (nz > 0)
+    eig_min = (eig_min > 1.0) ? 1.0 : eig_min;
+}
+
+void
+QuasiTriangularZero::solvePreTrans(Vector &x, double &eig_min)
+{
+  Vector xu(x, 0, nz);
+  Vector xl(x, nz, x.length()-nz);
+  ru.multsVecTrans(xl, xu);
+  QuasiTriangular::solvePreTrans(xl, eig_min);
+  if (nz > 0)
+    eig_min = (eig_min > 1.0) ? 1.0 : eig_min;
+}
+
+void
+QuasiTriangularZero::multVec(Vector &x, const ConstVector &b) const
+{
+  x.zeros();
+  multaVec(x, b);
+}
+
+void
+QuasiTriangularZero::multVecTrans(Vector &x, const ConstVector &b) const
+{
+  x.zeros();
+  multaVecTrans(x, b);
+}
+
+void
+QuasiTriangularZero::multaVec(Vector &x, const ConstVector &b) const
+{
+  ConstVector bl(b, nz, b.length()-nz);
+  Vector xu(x, 0, nz);
+  Vector xl(x, nz, x.length()-nz);
+  xu.zeros();
+  ru.multaVec(xu, bl);
+  QuasiTriangular::multVec(xl, bl);
+}
+
+void
+QuasiTriangularZero::multaVecTrans(Vector &x, const ConstVector &b) const
+{
+  ConstVector bu(b, 0, b.length());
+  ConstVector bl(b, nz, b.length()-nz);
+  Vector xu(x, 0, nz);
+  Vector xl(x, nz, x.length()-nz);
+  xu.zeros();
+  QuasiTriangular::multVecTrans(xl, bl);
+  ru.multaVecTrans(xl, bu);
+}
+
+void
+QuasiTriangularZero::multLeftOther(GeneralMatrix &a) const
+{
+  GeneralMatrix a1(a, 0, 0, nz, a.numCols());
+  GeneralMatrix a2(a, nz, 0, a.numRows()-nz, a.numCols());
+  a1.mult(ru, a2);
+  QuasiTriangular::multLeftOther(a2);
+}
+
+void
+QuasiTriangularZero::print() const
+{
+  printf("super=\n");
+  QuasiTriangular::print();
+  printf("nz=%d\n", nz);
+  printf("ru=\n");
+  ru.print();
+}
+
+void
+QuasiTriangularZero::multKron(KronVector &x) const
+{
+  throw SYLV_MES_EXCEPTION("Attempt to run QuasiTriangularZero::multKron.");
+}
+
+void
+QuasiTriangularZero::multKronTrans(KronVector &x) const
+{
+  throw SYLV_MES_EXCEPTION("Attempt to run QuasiTriangularZero::multKronTrans.");
+}
diff --git a/dynare++/sylv/cc/QuasiTriangularZero.cpp b/dynare++/sylv/cc/QuasiTriangularZero.cpp
deleted file mode 100644
index a7e9213b94da403a4ff37fe35f66eea87be7f602..0000000000000000000000000000000000000000
--- a/dynare++/sylv/cc/QuasiTriangularZero.cpp
+++ /dev/null
@@ -1,148 +0,0 @@
-/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/QuasiTriangularZero.cpp,v 1.1.1.1 2004/06/04 13:00:44 kamenik Exp $ */
-
-/* Tag $Name:  $ */
-
-#include "QuasiTriangularZero.h"
-#include "SchurDecomp.h"
-#include "SylvMatrix.h"
-#include "SylvException.h"
-
-#include <cstdio>
-
-QuasiTriangularZero::QuasiTriangularZero(int num_zeros, const double* d,
-										 int d_size)
-	: QuasiTriangular(SqSylvMatrix(GeneralMatrix(d, num_zeros+d_size, d_size),
-								   num_zeros, 0, d_size).getData().base(),
-					  d_size),
-	  nz(num_zeros),
-	  ru(GeneralMatrix(d, num_zeros+d_size, d_size), 0, 0, num_zeros, d_size)
-{
-}
-
-QuasiTriangularZero::QuasiTriangularZero(double r,
-										 const QuasiTriangularZero& t)
-	: QuasiTriangular(r, t),
-	  nz(t.nz),
-	  ru(t.ru)
-{
-	ru.mult(r);
-}
-
-QuasiTriangularZero::QuasiTriangularZero(double r,
-										 const QuasiTriangularZero& t,
-										 double rr,
-										 const QuasiTriangularZero& tt)
-	: QuasiTriangular(r, t, rr, tt),
-	  nz(t.nz),
-	  ru(t.ru)
-{
-	ru.mult(r);
-	ru.add(rr, tt.ru);
-}
-
-QuasiTriangularZero::QuasiTriangularZero(int p, const QuasiTriangularZero& t)
-	: QuasiTriangular(p, t),
-	  nz(t.nz),
-	  ru(t.ru)
-{
-	ru.multRight(t);
-}
-
-QuasiTriangularZero::QuasiTriangularZero(const SchurDecompZero& decomp)
-	: QuasiTriangular(decomp.getT().getData().base(),
-					  decomp.getT().numRows()),
-	  nz(decomp.getZeroCols()),
-	  ru(decomp.getRU())
-{
-}
-
-QuasiTriangularZero::QuasiTriangularZero(const QuasiTriangular& t)
-	: QuasiTriangular(t),
-	  nz(0), ru(0, t.getDiagonal().getSize())
-{
-}
-
-QuasiTriangularZero::~QuasiTriangularZero()
-{
-}
-
-void QuasiTriangularZero::solvePre(Vector& x, double& eig_min)
-{
-	Vector xu(x, 0, nz);
-	Vector xl(x, nz, x.length()-nz);
-	QuasiTriangular::solvePre(xl, eig_min);
-	ru.multsVec(xu, xl);
-	if (nz > 0)
-		eig_min = (eig_min > 1.0)? 1.0 : eig_min;
-}
-
-void QuasiTriangularZero::solvePreTrans(Vector& x, double& eig_min)
-{
-	Vector xu(x, 0, nz);
-	Vector xl(x, nz, x.length()-nz);
-	ru.multsVecTrans(xl, xu);
-	QuasiTriangular::solvePreTrans(xl, eig_min);
-	if (nz > 0)
-		eig_min = (eig_min > 1.0)? 1.0 : eig_min;
-}
-
-void QuasiTriangularZero::multVec(Vector& x, const ConstVector& b) const
-{
-	x.zeros();
-	multaVec(x, b);
-}
-
-void QuasiTriangularZero::multVecTrans(Vector& x, const ConstVector& b) const
-{
-	x.zeros();
-	multaVecTrans(x, b);
-}
-
-void QuasiTriangularZero::multaVec(Vector& x, const ConstVector& b) const
-{
-	ConstVector bl(b, nz, b.length()-nz);
-	Vector xu(x, 0, nz);
-	Vector xl(x, nz, x.length()-nz);
-	xu.zeros();
-	ru.multaVec(xu, bl);
-	QuasiTriangular::multVec(xl, bl);
-}
-
-void QuasiTriangularZero::multaVecTrans(Vector& x, const ConstVector& b) const
-{
-	ConstVector bu(b, 0, b.length());
-	ConstVector bl(b, nz, b.length()-nz);
-	Vector xu(x, 0, nz);
-	Vector xl(x, nz, x.length()-nz);
-	xu.zeros();
-	QuasiTriangular::multVecTrans(xl, bl);
-	ru.multaVecTrans(xl, bu);
-}
-
-void QuasiTriangularZero::multLeftOther(GeneralMatrix& a) const
-{
-	GeneralMatrix a1(a, 0, 0, nz, a.numCols());
-	GeneralMatrix a2(a, nz, 0, a.numRows()-nz, a.numCols());
-	a1.mult(ru, a2);
-	QuasiTriangular::multLeftOther(a2);
-}
-
-void QuasiTriangularZero::print() const
-{
-	printf("super=\n");
-	QuasiTriangular::print();
-	printf("nz=%d\n",nz);
-	printf("ru=\n");
-	ru.print();
-}
-
-void QuasiTriangularZero::multKron(KronVector& x) const
-{
-	throw SYLV_MES_EXCEPTION("Attempt to run QuasiTriangularZero::multKron.");
-}
-
-void QuasiTriangularZero::multKronTrans(KronVector& x) const
-{
-	throw SYLV_MES_EXCEPTION("Attempt to run QuasiTriangularZero::multKronTrans.");
-}
-
diff --git a/dynare++/sylv/cc/QuasiTriangularZero.h b/dynare++/sylv/cc/QuasiTriangularZero.hh
similarity index 97%
rename from dynare++/sylv/cc/QuasiTriangularZero.h
rename to dynare++/sylv/cc/QuasiTriangularZero.hh
index 243c02123f5ee6fcf05c9d6dc106c6fbf77b8fc7..049f6a802b2eb923ae0a368038ef7ee9581621fb 100644
--- a/dynare++/sylv/cc/QuasiTriangularZero.h
+++ b/dynare++/sylv/cc/QuasiTriangularZero.hh
@@ -5,8 +5,8 @@
 #ifndef QUASI_TRIANGULAR_ZERO_H
 #define QUASI_TRIANGULAR_ZERO_H
 
-#include "QuasiTriangular.h"
-#include "GeneralMatrix.h"
+#include "QuasiTriangular.hh"
+#include "GeneralMatrix.hh"
 
 class QuasiTriangularZero : public QuasiTriangular
 {
diff --git a/dynare++/sylv/cc/SchurDecomp.cc b/dynare++/sylv/cc/SchurDecomp.cc
new file mode 100644
index 0000000000000000000000000000000000000000..265a53a37c8116fac1e0b4e4eacd5eeb00877751
--- /dev/null
+++ b/dynare++/sylv/cc/SchurDecomp.cc
@@ -0,0 +1,71 @@
+/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/SchurDecomp.cpp,v 1.1.1.1 2004/06/04 13:00:44 kamenik Exp $ */
+
+/* Tag $Name:  $ */
+
+#include "SchurDecomp.hh"
+
+#include <dynlapack.h>
+
+SchurDecomp::SchurDecomp(const SqSylvMatrix &m)
+  : q_destroy(true), t_destroy(true)
+{
+  lapack_int rows = m.numRows();
+  q = new SqSylvMatrix(rows);
+  SqSylvMatrix auxt(m);
+  lapack_int sdim;
+  double *const wr = new double[rows];
+  double *const wi = new double[rows];
+  lapack_int lwork = 6*rows;
+  double *const work = new double[lwork];
+  lapack_int info;
+  dgees("V", "N", 0, &rows, auxt.base(), &rows, &sdim,
+        wr, wi, q->base(), &rows,
+        work, &lwork, 0, &info);
+  delete [] work;
+  delete [] wi;
+  delete [] wr;
+  t = new QuasiTriangular(auxt.base(), rows);
+}
+
+SchurDecomp::SchurDecomp(const QuasiTriangular &tr)
+  : q_destroy(true), t_destroy(true)
+{
+  q = new SqSylvMatrix(tr.numRows());
+  q->setUnit();
+  t = new QuasiTriangular(tr);
+}
+
+SchurDecomp::SchurDecomp(QuasiTriangular &tr)
+  : q_destroy(true), t_destroy(false)
+{
+  q = new SqSylvMatrix(tr.numRows());
+  q->setUnit();
+  t = &tr;
+}
+
+SchurDecomp::~SchurDecomp()
+{
+  if (t_destroy)
+    delete t;
+  if (q_destroy)
+    delete q;
+}
+
+int
+SchurDecomp::getDim() const
+{
+  return t->numRows();
+}
+
+SchurDecompZero::SchurDecompZero(const GeneralMatrix &m)
+  : SchurDecomp(SqSylvMatrix(m, m.numRows()-m.numCols(), 0, m.numCols())),
+    ru(m, 0, 0, m.numRows()-m.numCols(), m.numCols())
+{
+  ru.multRight(getQ());
+}
+
+int
+SchurDecompZero::getDim() const
+{
+  return getT().numRows()+ru.numRows();
+}
diff --git a/dynare++/sylv/cc/SchurDecomp.cpp b/dynare++/sylv/cc/SchurDecomp.cpp
deleted file mode 100644
index f76b48b177ca4569f8c897069a92847e39ca831a..0000000000000000000000000000000000000000
--- a/dynare++/sylv/cc/SchurDecomp.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/SchurDecomp.cpp,v 1.1.1.1 2004/06/04 13:00:44 kamenik Exp $ */
-
-/* Tag $Name:  $ */
-
-#include "SchurDecomp.h"
-
-#include <dynlapack.h>
-
-SchurDecomp::SchurDecomp(const SqSylvMatrix& m)
-	: q_destroy(true), t_destroy(true)
-{
-	lapack_int rows = m.numRows();
-	q = new SqSylvMatrix(rows);
-	SqSylvMatrix auxt(m);
-	lapack_int sdim;
-	double* const wr = new double[rows];
-	double* const wi = new double[rows];
-	lapack_int lwork = 6*rows;
-	double* const work = new double[lwork];
-	lapack_int info;
-	dgees("V", "N", 0, &rows, auxt.base(), &rows, &sdim,
-				 wr, wi, q->base(), &rows,
-				 work, &lwork, 0, &info);
-	delete [] work;
-	delete [] wi;
-	delete [] wr;
-	t = new QuasiTriangular(auxt.base(), rows);
-}
-
-SchurDecomp::SchurDecomp(const QuasiTriangular& tr)
-	: q_destroy(true), t_destroy(true)
-{
-	q = new SqSylvMatrix(tr.numRows());
-	q->setUnit();
-	t = new QuasiTriangular(tr);
-}
-
-SchurDecomp::SchurDecomp(QuasiTriangular& tr)
-	: q_destroy(true), t_destroy(false)
-{
-	q = new SqSylvMatrix(tr.numRows());
-	q->setUnit();
-	t = &tr;
-}
-
-SchurDecomp::~SchurDecomp()
-{
-	if (t_destroy)
-		delete t;
-	if (q_destroy)
-		delete q;
-}
-
-int SchurDecomp::getDim() const
-{
-	return t->numRows();
-}
-
-SchurDecompZero::SchurDecompZero(const GeneralMatrix& m)
-	: SchurDecomp(SqSylvMatrix(m, m.numRows()-m.numCols(), 0, m.numCols())),
-	  ru(m, 0, 0, m.numRows()-m.numCols(), m.numCols())
-{
-	ru.multRight(getQ());
-}
-
-int SchurDecompZero::getDim() const
-{
-	return getT().numRows()+ru.numRows();
-}
-
-
diff --git a/dynare++/sylv/cc/SchurDecomp.h b/dynare++/sylv/cc/SchurDecomp.hh
similarity index 95%
rename from dynare++/sylv/cc/SchurDecomp.h
rename to dynare++/sylv/cc/SchurDecomp.hh
index 9e83c92219269003bc6f552ec8d8bff0ebd1649e..8dd53525b75351917bfbf2010b091f47b48682b9 100644
--- a/dynare++/sylv/cc/SchurDecomp.h
+++ b/dynare++/sylv/cc/SchurDecomp.hh
@@ -5,8 +5,8 @@
 #ifndef SCHUR_DECOMP_H
 #define SCHUR_DECOMP_H
 
-#include "SylvMatrix.h"
-#include "QuasiTriangular.h"
+#include "SylvMatrix.hh"
+#include "QuasiTriangular.hh"
 
 class QuasiTriangular;
 class SchurDecomp
diff --git a/dynare++/sylv/cc/SchurDecompEig.cc b/dynare++/sylv/cc/SchurDecompEig.cc
new file mode 100644
index 0000000000000000000000000000000000000000..751b52818df6c4eecea820355ac2d8f7e44c83c2
--- /dev/null
+++ b/dynare++/sylv/cc/SchurDecompEig.cc
@@ -0,0 +1,101 @@
+#include "SchurDecompEig.hh"
+#include "SylvException.hh"
+
+#include <dynlapack.h>
+
+/* bubble diagonal 1-1, or 2-2 block from position 'from' to position
+ * 'to'. If an eigenvalue cannot be swapped with its neighbour, the
+ * neighbour is bubbled also in front. The method returns a new
+ * position 'to', where the original block pointed by 'to' happens to
+ * appear at the end. 'from' must be greater than 'to'.
+ */
+SchurDecompEig::diag_iter
+SchurDecompEig::bubbleEigen(diag_iter from, diag_iter to)
+{
+  diag_iter run = from;
+  while (run != to)
+    {
+      diag_iter runm = run;
+      if (!tryToSwap(run, runm) && runm == to)
+        {
+          ++to;
+        }
+      else
+        {
+          // bubble all eigenvalues from runm(incl.) to run(excl.),
+          // this includes either bubbling generated eigenvalues due
+          // to split, or an eigenvalue which couldn't be swapped
+          while (runm != run)
+            {
+              to = bubbleEigen(runm, to);
+              ++runm;
+            }
+        }
+    }
+  return to;
+}
+
+/* this tries to swap two neighbouring eigenvalues, 'it' and '--it',
+ * and returns 'itadd'. If the blocks can be swapped, new eigenvalues
+ * can emerge due to possible 2-2 block splits. 'it' then points to
+ * the last eigenvalue coming from block pointed by 'it' at the
+ * begining, and 'itadd' points to the first. On swap failure, 'it' is
+ * not changed, and 'itadd' points to previous eignevalue (which must
+ * be moved backwards before). In either case, it is necessary to
+ * resolve eigenvalues from 'itadd' to 'it', before the 'it' can be
+ * resolved.
+ * The success is signaled by returned true.
+ */
+bool
+SchurDecompEig::tryToSwap(diag_iter &it, diag_iter &itadd)
+{
+  itadd = it;
+  --itadd;
+
+  lapack_int n = getDim();
+  lapack_int ifst = (*it).getIndex() + 1;
+  lapack_int ilst = (*itadd).getIndex() + 1;
+  double *work = new double[n];
+  lapack_int info;
+  dtrexc("V", &n, getT().base(), &n, getQ().base(), &n, &ifst, &ilst, work,
+         &info);
+  delete [] work;
+  if (info < 0)
+    {
+      throw SYLV_MES_EXCEPTION("Wrong argument to dtrexc.");
+    }
+
+  if (info == 0)
+    {
+      // swap successful
+      getT().swapDiagLogically(itadd);
+      //check for 2-2 block splits
+      getT().checkDiagConsistency(it);
+      getT().checkDiagConsistency(itadd);
+      // and go back by 'it' in NEW eigenvalue set
+      --it;
+      return true;
+    }
+  return false;
+}
+
+void
+SchurDecompEig::orderEigen()
+{
+  diag_iter run = getT().diag_begin();
+  diag_iter runp = run;
+  ++runp;
+  double last_size = 0.0;
+  while (runp != getT().diag_end())
+    {
+      diag_iter least = getT().findNextLargerBlock(run, getT().diag_end(),
+                                                   last_size);
+      last_size = (*least).getSize();
+      if (run == least)
+        ++run;
+      else
+        run = bubbleEigen(least, run);
+      runp = run;
+      ++runp;
+    }
+}
diff --git a/dynare++/sylv/cc/SchurDecompEig.cpp b/dynare++/sylv/cc/SchurDecompEig.cpp
deleted file mode 100644
index b2fda2e0d64e4ca9e1095eb194e13f379edca661..0000000000000000000000000000000000000000
--- a/dynare++/sylv/cc/SchurDecompEig.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-#include "SchurDecompEig.h"
-#include "SylvException.h"
-
-#include <dynlapack.h>
-
-/* bubble diagonal 1-1, or 2-2 block from position 'from' to position
- * 'to'. If an eigenvalue cannot be swapped with its neighbour, the
- * neighbour is bubbled also in front. The method returns a new
- * position 'to', where the original block pointed by 'to' happens to
- * appear at the end. 'from' must be greater than 'to'.
- */
-SchurDecompEig::diag_iter
-SchurDecompEig::bubbleEigen(diag_iter from, diag_iter to)
-{
-	diag_iter run = from;
-	while (run != to) {
-		diag_iter runm = run;
-		if (!tryToSwap(run, runm) && runm == to) {
-			++to;
-		} else {
-			// bubble all eigenvalues from runm(incl.) to run(excl.),
-			// this includes either bubbling generated eigenvalues due
-			// to split, or an eigenvalue which couldn't be swapped
-			while (runm != run) {
-				to = bubbleEigen(runm, to);
-				++runm;
-			}
-		}
-	}
-	return to;
-}
-
-/* this tries to swap two neighbouring eigenvalues, 'it' and '--it',
- * and returns 'itadd'. If the blocks can be swapped, new eigenvalues
- * can emerge due to possible 2-2 block splits. 'it' then points to
- * the last eigenvalue coming from block pointed by 'it' at the
- * begining, and 'itadd' points to the first. On swap failure, 'it' is
- * not changed, and 'itadd' points to previous eignevalue (which must
- * be moved backwards before). In either case, it is necessary to
- * resolve eigenvalues from 'itadd' to 'it', before the 'it' can be
- * resolved.
- * The success is signaled by returned true.
- */
-bool SchurDecompEig::tryToSwap(diag_iter& it, diag_iter& itadd)
-{
-	itadd = it;
-	--itadd;
-
-	lapack_int n = getDim();
-	lapack_int ifst = (*it).getIndex() + 1;
-	lapack_int ilst = (*itadd).getIndex() + 1;
-	double* work = new double[n];
-	lapack_int info;
-	dtrexc("V", &n, getT().base(), &n, getQ().base(), &n, &ifst, &ilst, work,
-				  &info);
-	delete [] work;
-	if (info < 0) {
-		throw SYLV_MES_EXCEPTION("Wrong argument to dtrexc.");
-	}
-
-	if (info == 0) {
-		// swap successful
-		getT().swapDiagLogically(itadd);
-		//check for 2-2 block splits
-		getT().checkDiagConsistency(it);
-		getT().checkDiagConsistency(itadd);
-		// and go back by 'it' in NEW eigenvalue set
-		--it;
-		return true;
-	}
-	return false;
-}
-
-
-void SchurDecompEig::orderEigen()
-{
-	diag_iter run = getT().diag_begin();
-	diag_iter runp = run;
-	++runp;
-	double last_size = 0.0;
-	while (runp != getT().diag_end()) {
-		diag_iter least = getT().findNextLargerBlock(run, getT().diag_end(),
-													 last_size);
-		last_size = (*least).getSize();
-		if (run == least)
-			++run;
-		else
-			run = bubbleEigen(least, run);
-		runp = run;
-		++runp;
-	}
-}
diff --git a/dynare++/sylv/cc/SchurDecompEig.h b/dynare++/sylv/cc/SchurDecompEig.hh
similarity index 93%
rename from dynare++/sylv/cc/SchurDecompEig.h
rename to dynare++/sylv/cc/SchurDecompEig.hh
index 567f457831acd4a8f22fac71c9e575b89b675f37..6b9a7747e4aaaface84c413daeecceb20b27c4b7 100644
--- a/dynare++/sylv/cc/SchurDecompEig.h
+++ b/dynare++/sylv/cc/SchurDecompEig.hh
@@ -7,8 +7,8 @@
 #ifndef SCHUR_DECOMP_EIG_H
 #define SCHUR_DECOMP_EIG_H
 
-#include "SchurDecomp.h"
-#include "QuasiTriangular.h"
+#include "SchurDecomp.hh"
+#include "QuasiTriangular.hh"
 
 class SchurDecompEig : public SchurDecomp
 {
diff --git a/dynare++/sylv/cc/SimilarityDecomp.cc b/dynare++/sylv/cc/SimilarityDecomp.cc
new file mode 100644
index 0000000000000000000000000000000000000000..7c23e3c2f858dbed1bd61074f5b4bcfe5368eacd
--- /dev/null
+++ b/dynare++/sylv/cc/SimilarityDecomp.cc
@@ -0,0 +1,171 @@
+/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/SimilarityDecomp.cpp,v 1.1.1.1 2004/06/04 13:00:44 kamenik Exp $ */
+
+/* Tag $Name:  $ */
+
+#include "SimilarityDecomp.hh"
+#include "SchurDecomp.hh"
+#include "SchurDecompEig.hh"
+#include "SylvException.hh"
+
+#include <dynlapack.h>
+
+#include <cmath>
+
+SimilarityDecomp::SimilarityDecomp(const double *d, int d_size, double log10norm)
+{
+  SchurDecomp sd(SqSylvMatrix(d, d_size));
+  q = new SqSylvMatrix(sd.getQ());
+  b = new BlockDiagonal(sd.getT());
+  invq = new SqSylvMatrix(d_size);
+  invq->setUnit();
+  invq->multLeftTrans(sd.getQ());
+  double norm = pow(10.0, log10norm);
+  diagonalize(norm);
+}
+
+SimilarityDecomp::~SimilarityDecomp()
+{
+  delete invq;
+  delete b;
+  delete q;
+}
+
+void
+SimilarityDecomp::getXDim(diag_iter start, diag_iter end,
+                          int &rows, int &cols) const
+{
+  int si = (*start).getIndex();
+  int ei = (*end).getIndex();
+  cols = b->numRows() - ei;
+  rows = ei - si;
+}
+
+/* find solution of X for diagonal block given by start(incl.) and
+ * end(excl.). If the solution cannot be found, or it is greater than
+ * norm, X is not changed and flase is returned.
+ */
+bool
+SimilarityDecomp::solveX(diag_iter start, diag_iter end,
+                         GeneralMatrix &X, double norm) const
+{
+  int si = (*start).getIndex();
+  int ei = (*end).getIndex();
+
+  SqSylvMatrix A((const GeneralMatrix &)*b, si, si, X.numRows());
+  SqSylvMatrix B((const GeneralMatrix &)*b, ei, ei, X.numCols());
+  GeneralMatrix C((const GeneralMatrix &)*b, si, ei, X.numRows(), X.numCols());
+
+  lapack_int isgn = -1;
+  lapack_int m = A.numRows();
+  lapack_int n = B.numRows();
+  double scale;
+  lapack_int info;
+  dtrsyl("N", "N", &isgn, &m, &n, A.base(), &m, B.base(), &n,
+         C.base(), &m, &scale, &info);
+  if (info < -1)
+    throw SYLV_MES_EXCEPTION("Wrong parameter to LAPACK dtrsyl.");
+
+  if (info == 1 || scale < 1)
+    return false;
+  if (C.getData().getMax() > norm)
+    return false;
+
+  X = C;
+  return true;
+}
+
+/* multiply Q and invQ with (I -X; 0 I), and (I X; 0 I). This also sets X=-X. */
+void
+SimilarityDecomp::updateTransform(diag_iter start, diag_iter end,
+                                  GeneralMatrix &X)
+{
+  int si = (*start).getIndex();
+  int ei = (*end).getIndex();
+
+  SqSylvMatrix iX(q->numRows());
+  iX.setUnit();
+  iX.place(X, si, ei);
+  invq->GeneralMatrix::multLeft(iX);
+
+  iX.setUnit();
+  X.mult(-1.0);
+  iX.place(X, si, ei);
+  q->multRight(iX);
+}
+
+void
+SimilarityDecomp::bringGuiltyBlock(diag_iter start, diag_iter &end)
+{
+  double av = b->getAverageDiagSize(start, end);
+  diag_iter guilty = b->findClosestDiagBlock(end, b->diag_end(), av);
+  SchurDecompEig sd((QuasiTriangular&)*b); // works on b including diagonal structure
+  end = sd.bubbleEigen(guilty, end); // iterators are valid
+  ++end;
+  q->multRight(sd.getQ());
+  invq->multLeftTrans(sd.getQ());
+}
+
+void
+SimilarityDecomp::diagonalize(double norm)
+{
+  diag_iter start = b->diag_begin();
+  diag_iter end = start;
+  ++end;
+
+  while (end != b->diag_end())
+    {
+      int xrows;
+      int xcols;
+      getXDim(start, end, xrows, xcols);
+      GeneralMatrix X(xrows, xcols);
+      if (solveX(start, end, X, norm))
+        {
+          updateTransform(start, end, X);
+          b->setZeroBlockEdge(end);
+          start = end;
+          ++end;
+        }
+      else
+        {
+          bringGuiltyBlock(start, end); // moves with end
+        }
+    }
+}
+
+void
+SimilarityDecomp::check(SylvParams &pars, const GeneralMatrix &m) const
+{
+  // M - Q*B*inv(Q)
+  SqSylvMatrix c(getQ(), getB());
+  c.multRight(getInvQ());
+  c.add(-1.0, m);
+  pars.f_err1 = c.getNorm1();
+  pars.f_errI = c.getNormInf();
+
+  // I - Q*inv(Q)
+  c.setUnit();
+  c.mult(-1);
+  c.multAndAdd(getQ(), getInvQ());
+  pars.viv_err1 = c.getNorm1();
+  pars.viv_errI = c.getNormInf();
+
+  // I - inv(Q)*Q
+  c.setUnit();
+  c.mult(-1);
+  c.multAndAdd(getInvQ(), getQ());
+  pars.ivv_err1 = c.getNorm1();
+  pars.ivv_errI = c.getNormInf();
+}
+
+void
+SimilarityDecomp::infoToPars(SylvParams &pars) const
+{
+  pars.f_blocks = getB().getNumBlocks();
+  pars.f_largest = getB().getLargestBlock();
+  pars.f_zeros = getB().getNumZeros();
+  pars.f_offdiag = getB().getNumOffdiagonal();
+}
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/dynare++/sylv/cc/SimilarityDecomp.cpp b/dynare++/sylv/cc/SimilarityDecomp.cpp
deleted file mode 100644
index 9f9b091b2f61634b7914535413e375fa6438f4f2..0000000000000000000000000000000000000000
--- a/dynare++/sylv/cc/SimilarityDecomp.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/SimilarityDecomp.cpp,v 1.1.1.1 2004/06/04 13:00:44 kamenik Exp $ */
-
-/* Tag $Name:  $ */
-
-#include "SimilarityDecomp.h"
-#include "SchurDecomp.h"
-#include "SchurDecompEig.h"
-#include "SylvException.h"
-
-#include <dynlapack.h>
-
-#include <cmath>
-
-SimilarityDecomp::SimilarityDecomp(const double* d, int d_size, double log10norm)
-{
-	SchurDecomp sd(SqSylvMatrix(d, d_size));
-	q = new SqSylvMatrix(sd.getQ());
-	b = new BlockDiagonal(sd.getT());
-	invq = new SqSylvMatrix(d_size);
-	invq->setUnit();
-	invq->multLeftTrans(sd.getQ());
-	double norm = pow(10.0, log10norm);
-	diagonalize(norm);
-}
-
-SimilarityDecomp::~SimilarityDecomp()
-{
-	delete invq;
-	delete b;
-	delete q;
-}
-
-void SimilarityDecomp::getXDim(diag_iter start, diag_iter end,
-							   int &rows, int& cols) const
-{
-	int si = (*start).getIndex();
-	int ei = (*end).getIndex();
-	cols = b->numRows() - ei;
-	rows = ei - si;
-}
-
-/* find solution of X for diagonal block given by start(incl.) and
- * end(excl.). If the solution cannot be found, or it is greater than
- * norm, X is not changed and flase is returned.
- */
-bool SimilarityDecomp::solveX(diag_iter start, diag_iter end,
-							  GeneralMatrix& X, double norm) const
-{
-	int si = (*start).getIndex();
-	int ei = (*end).getIndex();
-
-	SqSylvMatrix A((const GeneralMatrix&)*b, si, si, X.numRows());
-	SqSylvMatrix B((const GeneralMatrix&)*b, ei, ei, X.numCols());
-	GeneralMatrix C((const GeneralMatrix&)*b, si, ei, X.numRows(), X.numCols());
-
-	lapack_int isgn = -1;
-	lapack_int m = A.numRows();
-	lapack_int n = B.numRows();
-	double scale;
-	lapack_int info;
-	dtrsyl("N", "N", &isgn, &m, &n, A.base(), &m, B.base(), &n,
-				  C.base(), &m, &scale, &info);
-	if (info < -1)
-		throw SYLV_MES_EXCEPTION("Wrong parameter to LAPACK dtrsyl.");
-
-	if (info == 1 || scale < 1)
-		return false;
-	if (C.getData().getMax() > norm)
-		return false;
-	
-	X = C;
-	return true;
-}
-
-/* multiply Q and invQ with (I -X; 0 I), and (I X; 0 I). This also sets X=-X. */
-void SimilarityDecomp::updateTransform(diag_iter start, diag_iter end,
-									   GeneralMatrix& X)
-{
-	int si = (*start).getIndex();
-	int ei = (*end).getIndex();
-	
-	SqSylvMatrix iX(q->numRows());
-	iX.setUnit();
-	iX.place(X, si, ei);
-	invq->GeneralMatrix::multLeft(iX);
-
-	iX.setUnit();
-	X.mult(-1.0);
-	iX.place(X, si, ei);
-	q->multRight(iX);
-}
-
-void SimilarityDecomp::bringGuiltyBlock(diag_iter start, diag_iter& end)
-{
-	double av = b->getAverageDiagSize(start, end);
-	diag_iter guilty = b->findClosestDiagBlock(end, b->diag_end(), av);
-	SchurDecompEig sd((QuasiTriangular&)*b); // works on b including diagonal structure
-	end = sd.bubbleEigen(guilty, end); // iterators are valid
-	++end;
-	q->multRight(sd.getQ());
-	invq->multLeftTrans(sd.getQ());
-}
-
-void SimilarityDecomp::diagonalize(double norm)
-{
-	diag_iter start = b->diag_begin();
-	diag_iter end = start;
-	++end;
-
-	while (end != b->diag_end()) {
-		int xrows;
-		int xcols;
-		getXDim(start, end, xrows, xcols);
-		GeneralMatrix X(xrows, xcols);
-		if (solveX(start, end, X, norm)) {
-			updateTransform(start, end, X);
-			b->setZeroBlockEdge(end);
-			start = end;
-			++end;
-		} else {
-			bringGuiltyBlock(start, end); // moves with end
-		}
-	}
-}
-
-void SimilarityDecomp::check(SylvParams& pars, const GeneralMatrix& m) const
-{
-	// M - Q*B*inv(Q)
-	SqSylvMatrix c(getQ(), getB());
-	c.multRight(getInvQ());
-	c.add(-1.0, m);
-	pars.f_err1 = c.getNorm1();
-	pars.f_errI = c.getNormInf();
-
-	// I - Q*inv(Q)
-	c.setUnit();
-	c.mult(-1);
-	c.multAndAdd(getQ(), getInvQ());
-	pars.viv_err1 = c.getNorm1();
-	pars.viv_errI = c.getNormInf();
-
-	// I - inv(Q)*Q
-	c.setUnit();
-	c.mult(-1);
-	c.multAndAdd(getInvQ(), getQ());
-	pars.ivv_err1 = c.getNorm1();
-	pars.ivv_errI = c.getNormInf();	
-}
-
-void SimilarityDecomp::infoToPars(SylvParams& pars) const
-{
-	pars.f_blocks = getB().getNumBlocks();
-	pars.f_largest = getB().getLargestBlock();
-	pars.f_zeros = getB().getNumZeros();
-	pars.f_offdiag = getB().getNumOffdiagonal();
-}
-
-// Local Variables:
-// mode:C++
-// End:
diff --git a/dynare++/sylv/cc/SimilarityDecomp.h b/dynare++/sylv/cc/SimilarityDecomp.hh
similarity index 93%
rename from dynare++/sylv/cc/SimilarityDecomp.h
rename to dynare++/sylv/cc/SimilarityDecomp.hh
index 107da24e0cc2dfa43ea2b12d78a818e5938ab868..6cc275efc993c2428f86569da84a8669b912569d 100644
--- a/dynare++/sylv/cc/SimilarityDecomp.h
+++ b/dynare++/sylv/cc/SimilarityDecomp.hh
@@ -5,9 +5,9 @@
 #ifndef SIMILARITY_DECOMP_H
 #define SIMILARITY_DECOMP_H
 
-#include "SylvMatrix.h"
-#include "BlockDiagonal.h"
-#include "SylvParams.h"
+#include "SylvMatrix.hh"
+#include "BlockDiagonal.hh"
+#include "SylvParams.hh"
 
 class SimilarityDecomp
 {
diff --git a/dynare++/sylv/cc/SylvException.cc b/dynare++/sylv/cc/SylvException.cc
new file mode 100644
index 0000000000000000000000000000000000000000..4e2c88e26cdfdcdfc28b8c703bd2b916cf5f9a0b
--- /dev/null
+++ b/dynare++/sylv/cc/SylvException.cc
@@ -0,0 +1,74 @@
+/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/SylvException.cpp,v 1.2 2004/10/01 10:30:40 kamenik Exp $ */
+
+/* Tag $Name:  $ */
+
+#include "SylvException.hh"
+
+#include <cstring>
+#include <cstdio>
+
+SylvException::SylvException(const char *f, int l, const SylvException *s)
+{
+  strcpy(file, f);
+  line = l;
+  source = s;
+}
+
+SylvException::~SylvException()
+{
+  if (source != NULL)
+    {
+      delete source;
+    }
+}
+
+void
+SylvException::printMessage() const
+{
+  char mes[1500];
+  mes[0] = '\0';
+  printMessage(mes, 1499);
+  puts(mes);
+}
+
+int
+SylvException::printMessage(char *str, int maxlen) const
+{
+  int remain = maxlen;
+  if (source != NULL)
+    {
+      remain = source->printMessage(str, maxlen);
+    }
+  char aux[100];
+  sprintf(aux, "From %s:%d\n", file, line);
+  int newremain = remain - strlen(aux);
+  if (newremain < 0)
+    {
+      aux[remain] = '\0';
+      newremain = 0;
+    }
+  strcat(str, aux);
+  return newremain;
+}
+
+SylvExceptionMessage::SylvExceptionMessage(const char *f, int i,
+                                           const char *mes)
+  : SylvException(f, i, NULL)
+{
+  strcpy(message, mes);
+}
+
+int
+SylvExceptionMessage::printMessage(char *str, int maxlen) const
+{
+  char aux[600];
+  sprintf(aux, "At %s:%d:%s\n", file, line, message);
+  int newremain = maxlen - strlen(aux);
+  if (newremain < 0)
+    {
+      aux[maxlen] = '\0';
+      newremain = 0;
+    }
+  strcat(str, aux);
+  return newremain;
+}
diff --git a/dynare++/sylv/cc/SylvException.cpp b/dynare++/sylv/cc/SylvException.cpp
deleted file mode 100644
index 43206138cf129ce72760c06839a190993ea6af55..0000000000000000000000000000000000000000
--- a/dynare++/sylv/cc/SylvException.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/SylvException.cpp,v 1.2 2004/10/01 10:30:40 kamenik Exp $ */
-
-/* Tag $Name:  $ */
-
-#include "SylvException.h"
-
-#include <cstring>
-#include <cstdio>
-
-SylvException::SylvException(const char* f, int l, const SylvException* s)
-{
-	strcpy(file,f);
-	line = l;
-	source = s;
-}
-
-SylvException::~SylvException()
-{
-	if (source != NULL) {
-		delete source;
-	}
-}
-
-void SylvException::printMessage() const
-{
-	char mes[1500];
-	mes[0] = '\0';
-	printMessage(mes, 1499);
-	puts(mes);
-}
-
-int SylvException::printMessage(char* str, int maxlen) const
-{
-	int remain = maxlen;
-	if (source != NULL) {
-		remain = source->printMessage(str, maxlen);
-	}
-	char aux[100];
-	sprintf(aux, "From %s:%d\n", file, line);
-	int newremain = remain - strlen(aux);
-	if (newremain < 0) {
-		aux[remain] = '\0';
-		newremain = 0;
-	}
-	strcat(str, aux);
-	return newremain;
-}
-
-SylvExceptionMessage::SylvExceptionMessage(const char* f, int i,
-										   const char* mes)
-	: SylvException(f,i,NULL)
-{
-	strcpy(message,mes);
-}
-
-int SylvExceptionMessage::printMessage(char* str, int maxlen) const
-{
-	char aux[600];
-	sprintf(aux, "At %s:%d:%s\n", file, line, message);
-	int newremain = maxlen - strlen(aux);
-	if (newremain < 0) {
-		aux[maxlen] = '\0';
-		newremain = 0;
-	}
-	strcat(str, aux);
-	return newremain;
-}
-
-
diff --git a/dynare++/sylv/cc/SylvException.h b/dynare++/sylv/cc/SylvException.hh
similarity index 97%
rename from dynare++/sylv/cc/SylvException.h
rename to dynare++/sylv/cc/SylvException.hh
index 5beb212a370a7d9f20b73f1f5c2b0c010eba6977..2bc1757ce2f602d6bd69abc863a4495afc8fef3e 100644
--- a/dynare++/sylv/cc/SylvException.h
+++ b/dynare++/sylv/cc/SylvException.hh
@@ -5,7 +5,7 @@
 #ifndef SYLV_EXCEPTION_H
 #define SYLV_EXCEPTION_H
 
-#include "SylvMemory.h"
+#include "SylvMemory.hh"
 
 class SylvException : public MallocAllocator
 {
diff --git a/dynare++/sylv/cc/SylvMatrix.cc b/dynare++/sylv/cc/SylvMatrix.cc
new file mode 100644
index 0000000000000000000000000000000000000000..5a4059ec6e02832d898367353a530c4502c5b647
--- /dev/null
+++ b/dynare++/sylv/cc/SylvMatrix.cc
@@ -0,0 +1,291 @@
+/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/SylvMatrix.cpp,v 1.1.1.1 2004/06/04 13:00:44 kamenik Exp $ */
+
+/* Tag $Name:  $ */
+
+#include "SylvException.hh"
+#include "SylvMatrix.hh"
+
+#include <dynblas.h>
+#include <dynlapack.h>
+
+#include <cstdio>
+#include <cstring>
+#include <cmath>
+
+void
+SylvMatrix::multLeftI(const SqSylvMatrix &m)
+{
+  int off = rows - m.numRows();
+  if (off < 0)
+    {
+      throw SYLV_MES_EXCEPTION("Wrong matrix dimensions for multLeftI.");
+    }
+  GeneralMatrix subtmp(*this, off, 0, m.numRows(), cols);
+  subtmp.multLeft(m);
+}
+
+void
+SylvMatrix::multLeftITrans(const SqSylvMatrix &m)
+{
+  int off = rows - m.numRows();
+  if (off < 0)
+    {
+      throw SYLV_MES_EXCEPTION("Wrong matrix dimensions for multLeftITrans.");
+    }
+  GeneralMatrix subtmp(*this, off, 0, m.numRows(), cols);
+  subtmp.multLeftTrans(m);
+}
+
+void
+SylvMatrix::multLeft(int zero_cols, const GeneralMatrix &a, const GeneralMatrix &b)
+{
+  int off = a.numRows() - a.numCols();
+  if (off < 0 || a.numRows() != rows || off != zero_cols
+      || rows != b.numRows() || cols != b.numCols())
+    {
+      throw SYLV_MES_EXCEPTION("Wrong matrix dimensions for multLeft.");
+    }
+  // here we cannot call SylvMatrix::gemm since it would require
+  // another copy of (usually big) b (we are not able to do inplace
+  // submatrix of const GeneralMatrix)
+  if (a.getLD() > 0 && ld > 0)
+    {
+      blas_int mm = a.numRows();
+      blas_int nn = cols;
+      blas_int kk = a.numCols();
+      double alpha = 1.0;
+      blas_int lda = a.getLD();
+      blas_int ldb = ld;
+      double beta = 0.0;
+      blas_int ldc = ld;
+      dgemm("N", "N", &mm, &nn, &kk, &alpha, a.getData().base(), &lda,
+            b.getData().base()+off, &ldb, &beta, data.base(), &ldc);
+    }
+}
+
+void
+SylvMatrix::multRightKron(const SqSylvMatrix &m, int order)
+{
+  if (power(m.numRows(), order) != cols)
+    {
+      throw SYLV_MES_EXCEPTION("Wrong number of cols for right kron multiply.");
+    }
+  KronVector auxrow(m.numRows(), m.numRows(), order-1);
+  for (int i = 0; i < rows; i++)
+    {
+      Vector rowi(data.base()+i, rows, cols);
+      KronVector rowikron(rowi, m.numRows(), m.numRows(), order-1);
+      auxrow = rowi; // copy data
+      m.multVecKronTrans(rowikron, auxrow);
+    }
+}
+
+void
+SylvMatrix::multRightKronTrans(const SqSylvMatrix &m, int order)
+{
+  if (power(m.numRows(), order) != cols)
+    {
+      throw SYLV_MES_EXCEPTION("Wrong number of cols for right kron multiply.");
+    }
+
+  KronVector auxrow(m.numRows(), m.numRows(), order-1);
+  for (int i = 0; i < rows; i++)
+    {
+      Vector rowi(data.base()+i, rows, cols);
+      KronVector rowikron(rowi, m.numRows(), m.numRows(), order-1);
+      auxrow = rowi; // copy data
+      m.multVecKron(rowikron, auxrow);
+    }
+}
+
+void
+SylvMatrix::eliminateLeft(int row, int col, Vector &x)
+{
+  double d = get(col, col);
+  double e = get(row, col);
+  if (std::abs(d) > std::abs(e))
+    {
+      get(row, col) = 0.0;
+      double mult = e/d;
+      for (int i = col + 1; i < numCols(); i++)
+        {
+          get(row, i) = get(row, i) - mult*get(col, i);
+        }
+      x[row] = x[row] - mult*x[col];
+    }
+  else if (std::abs(e) > std::abs(d))
+    {
+      get(row, col) = 0.0;
+      get(col, col) = e;
+      double mult = d/e;
+      for (int i = col + 1; i < numCols(); i++)
+        {
+          double tx = get(col, i);
+          double ty = get(row, i);
+          get(col, i) = ty;
+          get(row, i) = tx - mult*ty;
+        }
+      double tx = x[col];
+      double ty = x[row];
+      x[col] = ty;
+      x[row] = tx - mult*ty;
+    }
+}
+
+void
+SylvMatrix::eliminateRight(int row, int col, Vector &x)
+{
+  double d = get(row, row);
+  double e = get(row, col);
+
+  if (std::abs(d) > std::abs(e))
+    {
+      get(row, col) = 0.0;
+      double mult = e/d;
+      for (int i = 0; i < row; i++)
+        {
+          get(i, col) = get(i, col) - mult*get(i, row);
+        }
+      x[col] = x[col] - mult*x[row];
+    }
+  else if (std::abs(e) > std::abs(d))
+    {
+      get(row, col) = 0.0;
+      get(row, row) = e;
+      double mult = d/e;
+      for (int i = 0; i < row; i++)
+        {
+          double tx = get(i, row);
+          double ty = get(i, col);
+          get(i, row) = ty;
+          get(i, col) = tx - mult*ty;
+        }
+      double tx = x[row];
+      double ty = x[col];
+      x[row] = ty;
+      x[col] = tx - mult*ty;
+    }
+}
+
+SqSylvMatrix::SqSylvMatrix(const GeneralMatrix &a, const GeneralMatrix &b)
+  : SylvMatrix(a, b)
+{
+  if (rows != cols)
+    throw SYLV_MES_EXCEPTION("Wrong matrix dimensions in multiplication constructor of square matrix.");
+}
+
+void
+SqSylvMatrix::multVecKron(KronVector &x, const KronVector &d) const
+{
+  x.zeros();
+  if (d.getDepth() == 0)
+    {
+      multaVec(x, d);
+    }
+  else
+    {
+      KronVector aux(x.getM(), x.getN(), x.getDepth());
+      for (int i = 0; i < x.getM(); i++)
+        {
+          KronVector auxi(aux, i);
+          ConstKronVector di(d, i);
+          multVecKron(auxi, di);
+        }
+      for (int i = 0; i < rows; i++)
+        {
+          KronVector xi(x, i);
+          for (int j = 0; j < cols; j++)
+            {
+              KronVector auxj(aux, j);
+              xi.add(get(i, j), auxj);
+            }
+        }
+    }
+}
+
+void
+SqSylvMatrix::multVecKronTrans(KronVector &x, const KronVector &d) const
+{
+  x.zeros();
+  if (d.getDepth() == 0)
+    {
+      multaVecTrans(x, d);
+    }
+  else
+    {
+      KronVector aux(x.getM(), x.getN(), x.getDepth());
+      for (int i = 0; i < x.getM(); i++)
+        {
+          KronVector auxi(aux, i);
+          ConstKronVector di(d, i);
+          multVecKronTrans(auxi, di);
+        }
+      for (int i = 0; i < rows; i++)
+        {
+          KronVector xi(x, i);
+          for (int j = 0; j < cols; j++)
+            {
+              KronVector auxj(aux, j);
+              xi.add(get(j, i), auxj);
+            }
+        }
+    }
+}
+
+void
+SqSylvMatrix::multInvLeft2(GeneralMatrix &a, GeneralMatrix &b,
+                           double &rcond1, double &rcondinf) const
+{
+  if (rows != a.numRows() || rows != b.numRows())
+    {
+      throw SYLV_MES_EXCEPTION("Wrong dimensions for multInvLeft2.");
+    }
+  // PLU factorization
+  Vector inv(data);
+  lapack_int *const ipiv = new lapack_int[rows];
+  lapack_int info;
+  lapack_int rows2 = rows;
+  dgetrf(&rows2, &rows2, inv.base(), &rows2, ipiv, &info);
+  // solve a
+  lapack_int acols = a.numCols();
+  double *abase = a.base();
+  dgetrs("N", &rows2, &acols, inv.base(), &rows2, ipiv,
+         abase, &rows2, &info);
+  // solve b
+  lapack_int bcols = b.numCols();
+  double *bbase = b.base();
+  dgetrs("N", &rows2, &bcols, inv.base(), &rows2, ipiv,
+         bbase, &rows2, &info);
+  delete [] ipiv;
+
+  // condition numbers
+  double *const work = new double[4*rows];
+  lapack_int *const iwork = new lapack_int[rows];
+  double norm1 = getNorm1();
+  dgecon("1", &rows2, inv.base(), &rows2, &norm1, &rcond1,
+         work, iwork, &info);
+  double norminf = getNormInf();
+  dgecon("I", &rows2, inv.base(), &rows2, &norminf, &rcondinf,
+         work, iwork, &info);
+  delete [] iwork;
+  delete [] work;
+}
+
+void
+SqSylvMatrix::setUnit()
+{
+  for (int i = 0; i < rows; i++)
+    {
+      for (int j = 0; j < cols; j++)
+        {
+          if (i == j)
+            get(i, j) = 1.0;
+          else
+            get(i, j) = 0.0;
+        }
+    }
+}
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/dynare++/sylv/cc/SylvMatrix.cpp b/dynare++/sylv/cc/SylvMatrix.cpp
deleted file mode 100644
index 6935815e0d5ae749222c631eb8db60e91b5d6ad8..0000000000000000000000000000000000000000
--- a/dynare++/sylv/cc/SylvMatrix.cpp
+++ /dev/null
@@ -1,252 +0,0 @@
-/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/SylvMatrix.cpp,v 1.1.1.1 2004/06/04 13:00:44 kamenik Exp $ */
-
-/* Tag $Name:  $ */
-
-#include "SylvException.h"
-#include "SylvMatrix.h"
-
-#include <dynblas.h>
-#include <dynlapack.h>
-
-#include <cstdio>
-#include <cstring>
-#include <cmath>
-
-void SylvMatrix::multLeftI(const SqSylvMatrix& m)
-{
-	int off = rows - m.numRows();
-	if (off < 0) {
-		throw SYLV_MES_EXCEPTION("Wrong matrix dimensions for multLeftI.");
-	}
-	GeneralMatrix subtmp(*this, off, 0, m.numRows(), cols);
-	subtmp.multLeft(m);
-}
-
-void SylvMatrix::multLeftITrans(const SqSylvMatrix& m)
-{
-	int off = rows - m.numRows();
-	if (off < 0) {
-		throw SYLV_MES_EXCEPTION("Wrong matrix dimensions for multLeftITrans.");
-	}
-	GeneralMatrix subtmp(*this, off, 0, m.numRows(), cols);
-	subtmp.multLeftTrans(m);
-}
-
-
-void SylvMatrix::multLeft(int zero_cols, const GeneralMatrix& a, const GeneralMatrix& b)
-{
-	int off = a.numRows() - a.numCols();
-	if (off < 0 || a.numRows() != rows || off != zero_cols ||
-		rows != b.numRows() || cols != b.numCols()) {
-		throw SYLV_MES_EXCEPTION("Wrong matrix dimensions for multLeft.");
-	}
-	// here we cannot call SylvMatrix::gemm since it would require
-	// another copy of (usually big) b (we are not able to do inplace
-	// submatrix of const GeneralMatrix)
-	if (a.getLD() > 0 && ld > 0) {
-		blas_int mm = a.numRows();
-		blas_int nn = cols;
-		blas_int kk = a.numCols();
-		double alpha = 1.0;
-		blas_int lda = a.getLD();
-		blas_int ldb = ld;
-		double beta = 0.0;
-		blas_int ldc = ld;
-		dgemm("N", "N", &mm, &nn, &kk, &alpha, a.getData().base(), &lda,
-				   b.getData().base()+off, &ldb, &beta, data.base(), &ldc);
-	}
-}
-
-
-void SylvMatrix::multRightKron(const SqSylvMatrix& m, int order)
-{
-	if (power(m.numRows(), order) != cols) {
-		throw SYLV_MES_EXCEPTION("Wrong number of cols for right kron multiply.");
-	}
-	KronVector auxrow(m.numRows(), m.numRows(), order-1);
-	for (int i = 0; i < rows; i++) {
-		Vector rowi(data.base()+i, rows, cols);
-		KronVector rowikron(rowi, m.numRows(), m.numRows(), order-1);
-		auxrow = rowi; // copy data
-		m.multVecKronTrans(rowikron, auxrow);
-	}
-}
-
-void SylvMatrix::multRightKronTrans(const SqSylvMatrix& m, int order)
-{
-	if (power(m.numRows(), order) != cols) {
-		throw SYLV_MES_EXCEPTION("Wrong number of cols for right kron multiply.");
-	}
-	
-	KronVector auxrow(m.numRows(), m.numRows(), order-1);
-	for (int i = 0; i < rows; i++) {
-		Vector rowi(data.base()+i, rows, cols);
-		KronVector rowikron(rowi, m.numRows(), m.numRows(), order-1);
-		auxrow = rowi; // copy data
-		m.multVecKron(rowikron, auxrow);
-	}
-}
-
-void SylvMatrix::eliminateLeft(int row, int col, Vector& x)
-{
-	double d = get(col, col);
-	double e = get(row, col);
-	if (std::abs(d) > std::abs(e)) {
-		get(row, col) = 0.0;
-		double mult = e/d;
-		for (int i = col + 1; i < numCols(); i++) {
-			get(row, i) = get(row, i) - mult*get(col, i);
-		}
-		x[row] = x[row] - mult*x[col];
-	} else if (std::abs(e) > std::abs(d)) {
-		get(row, col) = 0.0;
-		get(col, col) = e;
-		double mult = d/e;
-		for (int i = col + 1; i < numCols(); i++) {
-			double tx = get(col, i);
-			double ty = get(row, i);
-			get(col, i) = ty;
-			get(row, i) = tx - mult*ty;
-		}
-		double tx = x[col];
-		double ty = x[row];
-		x[col] = ty;
-		x[row] = tx - mult*ty;
-	}
-}
-
-void SylvMatrix::eliminateRight(int row, int col, Vector& x)
-{
-	double d = get(row, row);
-	double e = get(row, col);
-	
-	if (std::abs(d) > std::abs(e)) {
-		get(row, col) = 0.0;
-		double mult = e/d;
-		for (int i = 0; i < row; i++) {
-			get(i, col) = get(i, col) - mult*get(i, row);
-		}
-		x[col] = x[col] - mult*x[row];
-	} else if (std::abs(e) > std::abs(d)) {
-		get(row, col) = 0.0;
-		get(row, row) = e;
-		double mult = d/e;
-		for (int i = 0; i < row; i++) {
-			double tx = get(i, row);
-			double ty = get(i, col);
-			get(i, row) = ty;
-			get(i, col) = tx - mult*ty;
-		}
-		double tx = x[row];
-		double ty = x[col];
-		x[row] = ty;
-		x[col] = tx - mult*ty;
-	}
-}
-
-
-
-SqSylvMatrix::SqSylvMatrix(const GeneralMatrix& a, const GeneralMatrix& b)
-	: SylvMatrix(a,b)
-{
-	if (rows != cols)
-		throw SYLV_MES_EXCEPTION("Wrong matrix dimensions in multiplication constructor of square matrix.");
-}
-
-void SqSylvMatrix::multVecKron(KronVector& x, const KronVector& d) const
-{
-	x.zeros();
-	if (d.getDepth() == 0) {
-		multaVec(x, d);
-	} else {
-		KronVector aux(x.getM(), x.getN(), x.getDepth());
-		for (int i = 0; i < x.getM(); i++) {
-			KronVector auxi(aux, i);
-			ConstKronVector di(d, i);
-			multVecKron(auxi, di);
-		}
-		for (int i = 0; i < rows; i++) {
-			KronVector xi(x, i);
-			for (int j = 0; j < cols; j++) {
-				KronVector auxj(aux, j);
-				xi.add(get(i,j),auxj);
-			}
-		}
-	}
-}
-
-
-void SqSylvMatrix::multVecKronTrans(KronVector& x, const KronVector& d) const
-{
-	x.zeros();
-	if (d.getDepth() == 0) {
-		multaVecTrans(x, d);
-	} else {
-		KronVector aux(x.getM(), x.getN(), x.getDepth());
-		for (int i = 0; i < x.getM(); i++) {
-			KronVector auxi(aux, i);
-			ConstKronVector di(d, i);
-			multVecKronTrans(auxi, di);
-		}
-		for (int i = 0; i < rows; i++) {
-			KronVector xi(x, i);
-			for (int j = 0; j < cols; j++) {
-				KronVector auxj(aux, j);
-				xi.add(get(j,i), auxj);
-			}
-		}
-	}
-}
-
-void SqSylvMatrix::multInvLeft2(GeneralMatrix& a, GeneralMatrix& b,
-								double& rcond1, double& rcondinf) const
-{
-	if (rows != a.numRows() || rows != b.numRows()) {
-		throw SYLV_MES_EXCEPTION("Wrong dimensions for multInvLeft2.");
-	}
-	// PLU factorization
-	Vector inv(data);
-	lapack_int * const ipiv = new lapack_int[rows];
-	lapack_int info;
-	lapack_int rows2 = rows;
-	dgetrf(&rows2, &rows2, inv.base(), &rows2, ipiv, &info);
-	// solve a
-	lapack_int acols = a.numCols();
-	double* abase = a.base();
-	dgetrs("N", &rows2, &acols, inv.base(), &rows2, ipiv,
-				  abase, &rows2, &info);
-	// solve b
-	lapack_int bcols = b.numCols();
-	double* bbase = b.base();
-	dgetrs("N", &rows2, &bcols, inv.base(), &rows2, ipiv,
-				  bbase, &rows2, &info);
-	delete [] ipiv;
-
-	// condition numbers
-	double* const work = new double[4*rows];
-	lapack_int* const iwork = new lapack_int[rows];
-	double norm1 = getNorm1();
-	dgecon("1", &rows2, inv.base(), &rows2, &norm1, &rcond1, 
-				  work, iwork, &info);
-	double norminf = getNormInf();
-	dgecon("I", &rows2, inv.base(), &rows2, &norminf, &rcondinf, 
-				  work, iwork, &info);
-	delete [] iwork;
-	delete [] work;
-}
-
-void SqSylvMatrix::setUnit()
-{
-	for (int i = 0; i < rows; i++) {
-		for (int j = 0; j < cols; j++) {
-			if (i==j)
-				get(i,j) = 1.0;
-			else 
-				get(i,j) = 0.0;
-		}
-	}
-}
-
-// Local Variables:
-// mode:C++
-// End:
diff --git a/dynare++/sylv/cc/SylvMatrix.h b/dynare++/sylv/cc/SylvMatrix.hh
similarity index 98%
rename from dynare++/sylv/cc/SylvMatrix.h
rename to dynare++/sylv/cc/SylvMatrix.hh
index 063e6b30b75ba3e5a037a62bc5a895eb01162a57..9c6b3ea0cc73ada92f76882a2c71bfb69b2c3e29 100644
--- a/dynare++/sylv/cc/SylvMatrix.h
+++ b/dynare++/sylv/cc/SylvMatrix.hh
@@ -5,8 +5,8 @@
 #ifndef SYLV_MATRIX_H
 #define SYLV_MATRIX_H
 
-#include "GeneralMatrix.h"
-#include "KronVector.h"
+#include "GeneralMatrix.hh"
+#include "KronVector.hh"
 
 class SqSylvMatrix;
 
diff --git a/dynare++/sylv/cc/SylvMemory.cc b/dynare++/sylv/cc/SylvMemory.cc
new file mode 100644
index 0000000000000000000000000000000000000000..57eee9af17ee6b8e12cb037499abc4405113aac1
--- /dev/null
+++ b/dynare++/sylv/cc/SylvMemory.cc
@@ -0,0 +1,238 @@
+/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/SylvMemory.cpp,v 1.1.1.1 2004/06/04 13:00:49 kamenik Exp $ */
+
+/* Tag $Name:  $ */
+
+#include "SylvMemory.hh"
+#include "SylvException.hh"
+#include "KronVector.hh"
+
+#if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
+# include <dynmex.h>
+#endif
+
+#include <cmath>
+#include <cstdio>
+#include <cstdlib>
+
+/**********************************************************/
+/*   SylvMemoryPool                                       */
+/**********************************************************/
+
+SylvMemoryPool memory_pool;
+
+SylvMemoryPool::SylvMemoryPool()
+  : base(0), length(0), allocated(0), stack_mode(false)
+{
+}
+
+void
+SylvMemoryPool::init(size_t size)
+{
+#ifdef USE_MEMORY_POOL
+  length = size;
+
+# if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
+  if (base)
+    throw SYLV_MES_EXCEPTION("Attempt to use matlab memory pool twice.");
+  base = (char *) mxMalloc(length);
+# else
+  base = (char *) malloc(length);
+# endif
+
+#else
+  throw SYLV_MES_EXCEPTION("SylvMemoryPool::init() called for non memory pool code.");
+#endif
+}
+
+void *
+SylvMemoryPool::allocate(size_t size)
+{
+#ifdef USE_MEMORY_POOL
+  if (allocated + size < length)
+    {
+      char *res = base + allocated;
+      allocated += size;
+      return res;
+    }
+  else
+    {
+      throw SYLV_MES_EXCEPTION("Run out of memory space");
+    }
+#else
+  throw SYLV_MES_EXCEPTION("SylvMemoryPool::allocate() called for non memory pool code.");
+#endif
+}
+
+void
+SylvMemoryPool::free(void *p)
+{
+#ifdef USE_MEMORY_POOL
+  int offset = ((char *) p) - base;
+
+# ifdef DEBUG
+  if (offset < 0)
+    throw SYLV_MES_EXCEPTION("SylvMemoryPool::free() frees wrong address < begin.");
+  if (offset >= (int) length)
+    throw SYLV_MES_EXCEPTION("SylvMemoryPool::free() frees wrong address > end.");
+# endif
+
+  if (stack_mode && offset >= 0 && offset < (int) allocated)
+    allocated = offset;
+
+#else
+  throw SYLV_MES_EXCEPTION("SylvMemoryPool::free() called for non memory pool code.");
+#endif
+}
+
+void
+SylvMemoryPool::setStackMode(bool mode)
+{
+  stack_mode = mode;
+}
+
+SylvMemoryPool::~SylvMemoryPool()
+{
+  reset();
+}
+
+void
+SylvMemoryPool::reset()
+{
+#if !defined(MATLAB_MEX_FILE) && !defined(OCTAVE_MEX_FILE)
+  delete [] base;
+  base = 0;
+  allocated = 0;
+  length = 0;
+  stack_mode = false;
+#endif
+}
+
+/**********************************************************/
+/*   global new and delete                                */
+/**********************************************************/
+
+#ifdef USE_MEMORY_POOL
+
+void *
+operator new(size_t size)
+{
+  return memory_pool.allocate(size);
+}
+
+void *
+operator new[](size_t size)
+{
+  return memory_pool.allocate(size);
+}
+
+void
+operator delete(void *p)
+{
+  memory_pool.free(p);
+}
+
+void
+operator delete[](void *p)
+{
+  memory_pool.free(p);
+}
+
+#endif
+
+/**********************************************************/
+/*   saved version of global new and delete               */
+/**********************************************************/
+
+#ifdef USE_MEMORY_POOL
+void *
+MallocAllocator::operator new(size_t size)
+{
+# if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
+  throw SYLV_MES_EXCEPTION("Attempt to call wrong memory allocator.");
+# else
+  void *res = malloc(size);
+  if (!res)
+    throw SYLV_MES_EXCEPTION("Malloc unable to allocate memory.");
+  return res;
+# endif
+}
+
+void *
+MallocAllocator::operator new[](size_t size)
+{
+# if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
+  throw SYLV_MES_EXCEPTION("Attempt to call wrong memory allocator.");
+# else
+  void *res = malloc(size);
+  if (!res)
+    throw SYLV_MES_EXCEPTION("Malloc unable allocate memory.");
+  return res;
+# endif
+}
+
+void
+MallocAllocator::operator delete(void *p)
+{
+# if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
+  throw SYLV_MES_EXCEPTION("Attempt to call wrong memory destructor.");
+# else
+  free(p);
+# endif
+}
+
+void
+MallocAllocator::operator delete[](void *p)
+{
+# if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
+  throw SYLV_MES_EXCEPTION("Attempt to call wrong memory destructor.");
+# else
+  free(p);
+# endif
+}
+
+#endif
+
+/**********************************************************/
+/*   SylvMemoryDriver                                     */
+/**********************************************************/
+
+void
+SylvMemoryDriver::allocate(int num_d, int m, int n, int order)
+{
+#ifdef USE_MEMORY_POOL
+  int x_cols = power(m, order);
+  int total = num_d*x_cols*n; // storage for big matrices
+  total += x_cols; // storage for one extra row of a big matrix
+  int dig_vectors = (int) ceil(((double) (power(m, order)-1))/(m-1));
+  total += 8*n*dig_vectors; // storage for kron vectors instantiated during solv
+  total += 50*(m*m+n*n); // some storage for small square matrices
+  total *= sizeof(double); // everything in doubles
+  memory_pool.init(total);
+#endif
+}
+
+SylvMemoryDriver::SylvMemoryDriver(int num_d, int m, int n, int order)
+{
+  allocate(num_d, m, n, order);
+}
+
+SylvMemoryDriver::SylvMemoryDriver(const SylvParams &pars, int num_d,
+                                   int m, int n, int order)
+{
+  if (*(pars.method) == SylvParams::iter)
+    num_d++;
+  if (*(pars.want_check))
+    num_d++;
+  allocate(num_d, m, n, order);
+}
+
+SylvMemoryDriver::~SylvMemoryDriver()
+{
+  memory_pool.reset();
+}
+
+void
+SylvMemoryDriver::setStackMode(bool mode)
+{
+  memory_pool.setStackMode(mode);
+}
diff --git a/dynare++/sylv/cc/SylvMemory.cpp b/dynare++/sylv/cc/SylvMemory.cpp
deleted file mode 100644
index 8f7a21738948fc1b8ea0a0dd208e08865fc16ad2..0000000000000000000000000000000000000000
--- a/dynare++/sylv/cc/SylvMemory.cpp
+++ /dev/null
@@ -1,221 +0,0 @@
-/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/SylvMemory.cpp,v 1.1.1.1 2004/06/04 13:00:49 kamenik Exp $ */
-
-/* Tag $Name:  $ */
-
-#include "SylvMemory.h"
-#include "SylvException.h"
-#include "KronVector.h"
-
-#if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
-# include <dynmex.h>
-#endif
-
-#include <cmath> 
-#include <cstdio>
-#include <cstdlib>
-
-/**********************************************************/
-/*   SylvMemoryPool                                       */
-/**********************************************************/
-
-SylvMemoryPool memory_pool;
-
-SylvMemoryPool::SylvMemoryPool()
-	: base(0), length(0), allocated(0), stack_mode(false)
-{
-}
-
-void SylvMemoryPool::init(size_t size)
-{
-#ifdef USE_MEMORY_POOL
-	length = size;
-
-#if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
-	if (base)
-		throw SYLV_MES_EXCEPTION("Attempt to use matlab memory pool twice.");
-	base = (char*) mxMalloc(length);
-#else
-	base = (char*) malloc(length);
-#endif
-
-#else
-	throw SYLV_MES_EXCEPTION("SylvMemoryPool::init() called for non memory pool code.");
-#endif
-}
-
-void* SylvMemoryPool::allocate(size_t size)
-{
-#ifdef USE_MEMORY_POOL
-	if (allocated + size < length) {
-		char* res = base + allocated;
-		allocated += size;
-		return res;
-	} else {
-		throw SYLV_MES_EXCEPTION("Run out of memory space");
-	}
-#else
-	throw SYLV_MES_EXCEPTION("SylvMemoryPool::allocate() called for non memory pool code.");
-#endif
-}
-
-void SylvMemoryPool::free(void* p)
-{
-#ifdef USE_MEMORY_POOL
-	int offset = ((char*)p) - base;
-
-#ifdef DEBUG
-	if (offset < 0)
-		throw SYLV_MES_EXCEPTION("SylvMemoryPool::free() frees wrong address < begin.");
-	if (offset >= (int)length)
-		throw SYLV_MES_EXCEPTION("SylvMemoryPool::free() frees wrong address > end.");
-#endif	
-
-	if (stack_mode && offset >= 0 && offset < (int)allocated)
-		allocated = offset;
-
-#else
-	throw SYLV_MES_EXCEPTION("SylvMemoryPool::free() called for non memory pool code.");
-#endif
-}
-
-void SylvMemoryPool::setStackMode(bool mode)
-{
-	stack_mode = mode;
-}
-
-SylvMemoryPool::~SylvMemoryPool()
-{
-	reset();
-}
-
-void SylvMemoryPool::reset()
-{
-#if !defined(MATLAB_MEX_FILE) && !defined(OCTAVE_MEX_FILE)
-	delete [] base;
-	base = 0;
-	allocated = 0;
-	length = 0;
-	stack_mode = false;
-#endif
-}
-
-/**********************************************************/
-/*   global new and delete                                */
-/**********************************************************/
-
-#ifdef USE_MEMORY_POOL
-
-void* operator new(size_t size)
-{
-	return memory_pool.allocate(size);
-}
-
-void* operator new[](size_t size)
-{
-	return memory_pool.allocate(size);
-}
-
-void operator delete(void* p)
-{
-	memory_pool.free(p);
-}
-
-void operator delete[](void* p)
-{
-	memory_pool.free(p);
-}
-
-#endif
-
-/**********************************************************/
-/*   saved version of global new and delete               */
-/**********************************************************/
-
-#ifdef USE_MEMORY_POOL
-void* MallocAllocator::operator new(size_t size)
-{
-#if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
-	throw SYLV_MES_EXCEPTION("Attempt to call wrong memory allocator.");
-#else
-	void* res = malloc(size);
-	if (!res) 
-		throw SYLV_MES_EXCEPTION("Malloc unable to allocate memory.");
-	return res;
-#endif
-}
-
-void* MallocAllocator::operator new[](size_t size)
-{
-#if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
-	throw SYLV_MES_EXCEPTION("Attempt to call wrong memory allocator.");
-#else
-	void* res = malloc(size);
-	if (!res)
-		throw SYLV_MES_EXCEPTION("Malloc unable allocate memory.");
-	return res;
-#endif
-}
-
-void MallocAllocator::operator delete(void* p)
-{
-#if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
-	throw SYLV_MES_EXCEPTION("Attempt to call wrong memory destructor.");
-#else
-	free(p);
-#endif
-}
-
-void MallocAllocator::operator delete[](void* p)
-{
-#if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
-	throw SYLV_MES_EXCEPTION("Attempt to call wrong memory destructor.");
-#else
-	free(p);
-#endif
-}
-
-#endif
-
-
-/**********************************************************/
-/*   SylvMemoryDriver                                     */
-/**********************************************************/
-
-void SylvMemoryDriver::allocate(int num_d, int m, int n, int order)
-{
-#ifdef USE_MEMORY_POOL
-	int x_cols = power(m,order);
-	int total = num_d*x_cols*n; // storage for big matrices
-	total += x_cols; // storage for one extra row of a big matrix
-	int dig_vectors = (int)ceil(((double)(power(m,order)-1))/(m-1));
-	total += 8*n*dig_vectors; // storage for kron vectors instantiated during solv
-	total += 50*(m*m+n*n); // some storage for small square matrices
-	total *= sizeof(double); // everything in doubles
-	memory_pool.init(total);
-#endif
-}
-
-
-SylvMemoryDriver::SylvMemoryDriver(int num_d, int m, int n, int order)
-{
-	allocate(num_d, m, n, order);
-}
-
-SylvMemoryDriver::SylvMemoryDriver(const SylvParams& pars, int num_d,
-								   int m, int n, int order)
-{
-	if (*(pars.method) == SylvParams::iter)
-		num_d++;
-	if (*(pars.want_check))
-		num_d++;
-	allocate(num_d, m, n, order);
-}
-
-SylvMemoryDriver::~SylvMemoryDriver()
-{
-	memory_pool.reset();
-}
-
-void SylvMemoryDriver::setStackMode(bool mode) {
-	memory_pool.setStackMode(mode);
-}
diff --git a/dynare++/sylv/cc/SylvMemory.h b/dynare++/sylv/cc/SylvMemory.hh
similarity index 98%
rename from dynare++/sylv/cc/SylvMemory.h
rename to dynare++/sylv/cc/SylvMemory.hh
index 48a0fcd3dc095779c70d69f230ec0ed6369fa9c9..73a35dfc7f38e1a6ed07abcfcaaf28d47fc59052 100644
--- a/dynare++/sylv/cc/SylvMemory.h
+++ b/dynare++/sylv/cc/SylvMemory.hh
@@ -5,7 +5,7 @@
 #ifndef SYLV_MEMORY_H
 #define SYLV_MEMORY_H
 
-#include "SylvParams.h"
+#include "SylvParams.hh"
 
 #include <new>
 
diff --git a/dynare++/sylv/cc/SylvParams.cc b/dynare++/sylv/cc/SylvParams.cc
new file mode 100644
index 0000000000000000000000000000000000000000..6d03ef39de1570452bbee3a911a7c032642a1385
--- /dev/null
+++ b/dynare++/sylv/cc/SylvParams.cc
@@ -0,0 +1,241 @@
+/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/SylvParams.cpp,v 1.1.1.1 2004/06/04 13:00:52 kamenik Exp $ */
+
+/* Tag $Name:  $ */
+
+#include "SylvParams.hh"
+
+void
+SylvParams::print(const char *prefix) const
+{
+  print(stdout, prefix);
+}
+
+void
+SylvParams::print(FILE *fdesc, const char *prefix) const
+{
+  rcondA1.print(fdesc, prefix,  "reci. cond1 A      ", "%8.4g");
+  rcondAI.print(fdesc, prefix,  "reci. condInf A    ", "%8.4g");
+  bs_norm.print(fdesc, prefix,  "log10 diag norm    ", "%8.4g");
+  f_err1.print(fdesc, prefix,   "abs. err 1 F diag  ", "%8.4g");
+  f_errI.print(fdesc, prefix,   "abs. err I F diag  ", "%8.4g");
+  viv_err1.print(fdesc, prefix, "abs. err 1 V*invV  ", "%8.4g");
+  viv_errI.print(fdesc, prefix, "abs. err I V*invV  ", "%8.4g");
+  ivv_err1.print(fdesc, prefix, "abs. err 1 invV*V  ", "%8.4g");
+  ivv_errI.print(fdesc, prefix, "abs. err I invV*V  ", "%8.4g");
+  f_blocks.print(fdesc, prefix, "num blocks in F    ", "%d");
+  f_largest.print(fdesc, prefix, "largest block in F ", "%d");
+  f_zeros.print(fdesc, prefix,  "num zeros in F     ", "%d");
+  f_offdiag.print(fdesc, prefix, "num offdiag in F   ", "%d");
+  if (*method == iter)
+    {
+      converged.print(fdesc, prefix,       "converged          ", "%d");
+      convergence_tol.print(fdesc, prefix, "convergence tol.   ", "%8.4g");
+      iter_last_norm.print(fdesc, prefix,  "last norm          ", "%8.4g");
+      max_num_iter.print(fdesc, prefix,    "max num iter       ", "%d");
+      num_iter.print(fdesc, prefix,        "num iter           ", "%d");
+    }
+  else
+    {
+      eig_min.print(fdesc, prefix,         "minimum eigenvalue ", "%8.4g");
+    }
+  mat_err1.print(fdesc, prefix, "rel. matrix norm1  ", "%8.4g");
+  mat_errI.print(fdesc, prefix, "rel. matrix normInf", "%8.4g");
+  mat_errF.print(fdesc, prefix, "rel. matrix normFro", "%8.4g");
+  vec_err1.print(fdesc, prefix, "rel. vector norm1  ", "%8.4g");
+  vec_errI.print(fdesc, prefix, "rel. vector normInf", "%8.4g");
+  cpu_time.print(fdesc, prefix, "time (CPU secs)    ", "%8.4g");
+}
+
+void
+SylvParams::copy(const SylvParams &p)
+{
+  method = p.method;
+  convergence_tol = p.convergence_tol;
+  max_num_iter = p.max_num_iter;
+  bs_norm = p.bs_norm;
+  want_check = p.want_check;
+  converged = p.converged;
+  iter_last_norm = p.iter_last_norm;
+  num_iter = p.num_iter;
+  f_err1 = p.f_err1;
+  f_errI = p.f_errI;
+  viv_err1 = p.viv_err1;
+  viv_errI = p.viv_errI;
+  ivv_err1 = p.ivv_err1;
+  ivv_errI = p.ivv_errI;
+  f_blocks = p.f_blocks;
+  f_largest = p.f_largest;
+  f_zeros = p.f_zeros;
+  f_offdiag = p.f_offdiag;
+  rcondA1 = p.rcondA1;
+  rcondAI = p.rcondAI;
+  eig_min = p.eig_min;
+  mat_err1 = p.mat_err1;
+  mat_errI = p.mat_errI;
+  mat_errF = p.mat_errF;
+  vec_err1 = p.vec_err1;
+  vec_errI = p.vec_errI;
+  cpu_time = p.cpu_time;
+}
+
+void
+SylvParams::setArrayNames(int &num, const char **names) const
+{
+  num = 0;
+  if (method.getStatus() != undef)
+    names[num++] = "method";
+  if (convergence_tol.getStatus() != undef)
+    names[num++] = "convergence_tol";
+  if (max_num_iter.getStatus() != undef)
+    names[num++] = "max_num_iter";
+  if (bs_norm.getStatus() != undef)
+    names[num++] = "bs_norm";
+  if (converged.getStatus() != undef)
+    names[num++] = "converged";
+  if (iter_last_norm.getStatus() != undef)
+    names[num++] = "iter_last_norm";
+  if (num_iter.getStatus() != undef)
+    names[num++] = "num_iter";
+  if (f_err1.getStatus() != undef)
+    names[num++] = "f_err1";
+  if (f_errI.getStatus() != undef)
+    names[num++] = "f_errI";
+  if (viv_err1.getStatus() != undef)
+    names[num++] = "viv_err1";
+  if (viv_errI.getStatus() != undef)
+    names[num++] = "viv_errI";
+  if (ivv_err1.getStatus() != undef)
+    names[num++] = "ivv_err1";
+  if (ivv_errI.getStatus() != undef)
+    names[num++] = "ivv_errI";
+  if (f_blocks.getStatus() != undef)
+    names[num++] = "f_blocks";
+  if (f_largest.getStatus() != undef)
+    names[num++] = "f_largest";
+  if (f_zeros.getStatus() != undef)
+    names[num++] = "f_zeros";
+  if (f_offdiag.getStatus() != undef)
+    names[num++] = "f_offdiag";
+  if (rcondA1.getStatus() != undef)
+    names[num++] = "rcondA1";
+  if (rcondAI.getStatus() != undef)
+    names[num++] = "rcondAI";
+  if (eig_min.getStatus() != undef)
+    names[num++] = "eig_min";
+  if (mat_err1.getStatus() != undef)
+    names[num++] = "mat_err1";
+  if (mat_errI.getStatus() != undef)
+    names[num++] = "mat_errI";
+  if (mat_errF.getStatus() != undef)
+    names[num++] = "mat_errF";
+  if (vec_err1.getStatus() != undef)
+    names[num++] = "vec_err1";
+  if (vec_errI.getStatus() != undef)
+    names[num++] = "vec_errI";
+  if (cpu_time.getStatus() != undef)
+    names[num++] = "cpu_time";
+}
+
+#if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
+mxArray *
+SylvParams::DoubleParamItem::createMatlabArray() const
+{
+  return mxCreateDoubleScalar(value);
+}
+
+mxArray *
+SylvParams::IntParamItem::createMatlabArray() const
+{
+  mxArray *res = mxCreateNumericMatrix(1, 1, mxINT32_CLASS, mxREAL);
+  *((int *) mxGetData(res)) = value;
+  return res;
+}
+
+mxArray *
+SylvParams::BoolParamItem::createMatlabArray() const
+{
+  if (value)
+    return mxCreateString("true");
+  else
+    return mxCreateString("false");
+}
+
+mxArray *
+SylvParams::MethodParamItem::createMatlabArray() const
+{
+  if (value == iter)
+    return mxCreateString("iterative");
+  else
+    return mxCreateString("recursive");
+}
+
+mxArray *
+SylvParams::createStructArray() const
+{
+  const char *names[50];
+  int num;
+  setArrayNames(num, names);
+  const mwSize dims[] = {1, 1};
+  mxArray *const res = mxCreateStructArray(2, dims, num, names);
+
+  int i = 0;
+  if (method.getStatus() != undef)
+    mxSetFieldByNumber(res, 0, i++, method.createMatlabArray());
+  if (convergence_tol.getStatus() != undef)
+    mxSetFieldByNumber(res, 0, i++, convergence_tol.createMatlabArray());
+  if (max_num_iter.getStatus() != undef)
+    mxSetFieldByNumber(res, 0, i++, max_num_iter.createMatlabArray());
+  if (bs_norm.getStatus() != undef)
+    mxSetFieldByNumber(res, 0, i++, bs_norm.createMatlabArray());
+  if (converged.getStatus() != undef)
+    mxSetFieldByNumber(res, 0, i++, converged.createMatlabArray());
+  if (iter_last_norm.getStatus() != undef)
+    mxSetFieldByNumber(res, 0, i++, iter_last_norm.createMatlabArray());
+  if (num_iter.getStatus() != undef)
+    mxSetFieldByNumber(res, 0, i++, num_iter.createMatlabArray());
+  if (f_err1.getStatus() != undef)
+    mxSetFieldByNumber(res, 0, i++, f_err1.createMatlabArray());
+  if (f_errI.getStatus() != undef)
+    mxSetFieldByNumber(res, 0, i++, f_errI.createMatlabArray());
+  if (viv_err1.getStatus() != undef)
+    mxSetFieldByNumber(res, 0, i++, viv_err1.createMatlabArray());
+  if (viv_errI.getStatus() != undef)
+    mxSetFieldByNumber(res, 0, i++, viv_errI.createMatlabArray());
+  if (ivv_err1.getStatus() != undef)
+    mxSetFieldByNumber(res, 0, i++, ivv_err1.createMatlabArray());
+  if (ivv_errI.getStatus() != undef)
+    mxSetFieldByNumber(res, 0, i++, ivv_errI.createMatlabArray());
+  if (f_blocks.getStatus() != undef)
+    mxSetFieldByNumber(res, 0, i++, f_blocks.createMatlabArray());
+  if (f_largest.getStatus() != undef)
+    mxSetFieldByNumber(res, 0, i++, f_largest.createMatlabArray());
+  if (f_zeros.getStatus() != undef)
+    mxSetFieldByNumber(res, 0, i++, f_zeros.createMatlabArray());
+  if (f_offdiag.getStatus() != undef)
+    mxSetFieldByNumber(res, 0, i++, f_offdiag.createMatlabArray());
+  if (rcondA1.getStatus() != undef)
+    mxSetFieldByNumber(res, 0, i++, rcondA1.createMatlabArray());
+  if (rcondAI.getStatus() != undef)
+    mxSetFieldByNumber(res, 0, i++, rcondAI.createMatlabArray());
+  if (eig_min.getStatus() != undef)
+    mxSetFieldByNumber(res, 0, i++, eig_min.createMatlabArray());
+  if (mat_err1.getStatus() != undef)
+    mxSetFieldByNumber(res, 0, i++, mat_err1.createMatlabArray());
+  if (mat_errI.getStatus() != undef)
+    mxSetFieldByNumber(res, 0, i++, mat_errI.createMatlabArray());
+  if (mat_errF.getStatus() != undef)
+    mxSetFieldByNumber(res, 0, i++, mat_errF.createMatlabArray());
+  if (vec_err1.getStatus() != undef)
+    mxSetFieldByNumber(res, 0, i++, vec_err1.createMatlabArray());
+  if (vec_errI.getStatus() != undef)
+    mxSetFieldByNumber(res, 0, i++, vec_errI.createMatlabArray());
+  if (cpu_time.getStatus() != undef)
+    mxSetFieldByNumber(res, 0, i++, cpu_time.createMatlabArray());
+
+  return res;
+}
+#endif
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/dynare++/sylv/cc/SylvParams.cpp b/dynare++/sylv/cc/SylvParams.cpp
deleted file mode 100644
index ee1b90e480d2ea818feeb98564519fc5091c4050..0000000000000000000000000000000000000000
--- a/dynare++/sylv/cc/SylvParams.cpp
+++ /dev/null
@@ -1,230 +0,0 @@
-/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/SylvParams.cpp,v 1.1.1.1 2004/06/04 13:00:52 kamenik Exp $ */
-
-/* Tag $Name:  $ */
-
-#include "SylvParams.h"
-
-
-void SylvParams::print(const char* prefix) const
-{
-	print(stdout, prefix);
-}
-
-void SylvParams::print(FILE* fdesc, const char* prefix) const
-{
-	rcondA1.print(fdesc, prefix,  "reci. cond1 A      ", "%8.4g");
-	rcondAI.print(fdesc, prefix,  "reci. condInf A    ", "%8.4g");
-	bs_norm.print(fdesc, prefix,  "log10 diag norm    ", "%8.4g");
-	f_err1.print(fdesc, prefix,   "abs. err 1 F diag  ", "%8.4g");
-	f_errI.print(fdesc, prefix,   "abs. err I F diag  ", "%8.4g");
-	viv_err1.print(fdesc, prefix, "abs. err 1 V*invV  ", "%8.4g");
-	viv_errI.print(fdesc, prefix, "abs. err I V*invV  ", "%8.4g");
-	ivv_err1.print(fdesc, prefix, "abs. err 1 invV*V  ", "%8.4g");
-	ivv_errI.print(fdesc, prefix, "abs. err I invV*V  ", "%8.4g");
-	f_blocks.print(fdesc, prefix, "num blocks in F    ", "%d");
-	f_largest.print(fdesc, prefix,"largest block in F ", "%d");
-	f_zeros.print(fdesc, prefix,  "num zeros in F     ", "%d");
-	f_offdiag.print(fdesc, prefix,"num offdiag in F   ", "%d");
-	if (*method == iter) {
-		converged.print(fdesc, prefix,       "converged          ", "%d");
-		convergence_tol.print(fdesc, prefix, "convergence tol.   ", "%8.4g");
-		iter_last_norm.print(fdesc, prefix,  "last norm          ", "%8.4g");
-		max_num_iter.print(fdesc, prefix,    "max num iter       ", "%d");
-		num_iter.print(fdesc, prefix,        "num iter           ", "%d");
-	} else {
-		eig_min.print(fdesc, prefix,         "minimum eigenvalue ", "%8.4g");
-	}
-	mat_err1.print(fdesc, prefix, "rel. matrix norm1  ", "%8.4g");
-	mat_errI.print(fdesc, prefix, "rel. matrix normInf", "%8.4g");
-	mat_errF.print(fdesc, prefix, "rel. matrix normFro", "%8.4g");
-	vec_err1.print(fdesc, prefix, "rel. vector norm1  ", "%8.4g");
-	vec_errI.print(fdesc, prefix, "rel. vector normInf", "%8.4g");
-	cpu_time.print(fdesc, prefix, "time (CPU secs)    ", "%8.4g");
-}
-
-void SylvParams::copy(const SylvParams& p)
-{
-	method = p.method;
-	convergence_tol = p.convergence_tol;
-	max_num_iter = p.max_num_iter;
-	bs_norm = p.bs_norm;
-	want_check = p.want_check;
-	converged = p.converged;
-	iter_last_norm = p.iter_last_norm;
-	num_iter = p.num_iter;
-	f_err1 = p.f_err1;
-	f_errI = p.f_errI;
-	viv_err1 = p.viv_err1;
-	viv_errI = p.viv_errI;
-	ivv_err1 = p.ivv_err1;
-	ivv_errI = p.ivv_errI;
-	f_blocks = p.f_blocks;
-	f_largest = p.f_largest;
-	f_zeros = p.f_zeros;
-	f_offdiag = p.f_offdiag;
-	rcondA1 = p.rcondA1;
-	rcondAI = p.rcondAI;
-	eig_min = p.eig_min;
-	mat_err1 = p.mat_err1;
-	mat_errI = p.mat_errI;
-	mat_errF = p.mat_errF;
-	vec_err1 = p.vec_err1;
-	vec_errI = p.vec_errI;
-	cpu_time = p.cpu_time;
-}
-
-void SylvParams::setArrayNames(int& num, const char** names) const
-{
-	num = 0;
-	if (method.getStatus() != undef)
-		names[num++] = "method";
-	if (convergence_tol.getStatus() != undef)
-		names[num++] = "convergence_tol";
-	if (max_num_iter.getStatus() != undef)
-		names[num++] = "max_num_iter";
-	if (bs_norm.getStatus() != undef)
-		names[num++] = "bs_norm";
-	if (converged.getStatus() != undef)
-		names[num++] = "converged";
-	if (iter_last_norm.getStatus() != undef)
-		names[num++] = "iter_last_norm";
-	if (num_iter.getStatus() != undef)
-		names[num++] = "num_iter";
-	if (f_err1.getStatus() != undef)
-		names[num++] = "f_err1";
-	if (f_errI.getStatus() != undef)
-		names[num++] = "f_errI";
-	if (viv_err1.getStatus() != undef)
-		names[num++] = "viv_err1";
-	if (viv_errI.getStatus() != undef)
-		names[num++] = "viv_errI";
-	if (ivv_err1.getStatus() != undef)
-		names[num++] = "ivv_err1";
-	if (ivv_errI.getStatus() != undef)
-		names[num++] = "ivv_errI";
-	if (f_blocks.getStatus() != undef)
-		names[num++] = "f_blocks";
-	if (f_largest.getStatus() != undef)
-		names[num++] = "f_largest";
-	if (f_zeros.getStatus() != undef)
-		names[num++] = "f_zeros";
-	if (f_offdiag.getStatus() != undef)
-		names[num++] = "f_offdiag";
-	if (rcondA1.getStatus() != undef)
-		names[num++] = "rcondA1";
-	if (rcondAI.getStatus() != undef)
-		names[num++] = "rcondAI";
-	if (eig_min.getStatus() != undef)
-		names[num++] = "eig_min";
-	if (mat_err1.getStatus() != undef)
-		names[num++] = "mat_err1";
-	if (mat_errI.getStatus() != undef)
-		names[num++] = "mat_errI";
-	if (mat_errF.getStatus() != undef)
-		names[num++] = "mat_errF";
-	if (vec_err1.getStatus() != undef)
-		names[num++] = "vec_err1";
-	if (vec_errI.getStatus() != undef)
-		names[num++] = "vec_errI";
-	if (cpu_time.getStatus() != undef)
-		names[num++] = "cpu_time";
-}
-
-#if defined(MATLAB_MEX_FILE) || defined(OCTAVE_MEX_FILE)
-mxArray* SylvParams::DoubleParamItem::createMatlabArray() const
-{
-    return mxCreateDoubleScalar(value);
-}
-
-mxArray* SylvParams::IntParamItem::createMatlabArray() const
-{
-	mxArray* res = mxCreateNumericMatrix(1, 1, mxINT32_CLASS, mxREAL);
-	*((int*)mxGetData(res)) = value;
-	return res;
-}
-
-mxArray* SylvParams::BoolParamItem::createMatlabArray() const
-{
-	if (value)
-		return mxCreateString("true");
-	else
-		return mxCreateString("false");
-}
-
-mxArray* SylvParams::MethodParamItem::createMatlabArray() const
-{
-	if (value == iter)
-		return mxCreateString("iterative");
-	else
-		return mxCreateString("recursive");
-}
-
-mxArray* SylvParams::createStructArray() const
-{
-	const char* names[50];
-	int num;
-	setArrayNames(num, names);
-	const mwSize dims[] = {1, 1};
-	mxArray* const res = mxCreateStructArray(2, dims, num, names);
-
-	int i = 0;
-	if (method.getStatus() != undef)
-		mxSetFieldByNumber(res, 0, i++, method.createMatlabArray());
-	if (convergence_tol.getStatus() != undef)
-		mxSetFieldByNumber(res, 0, i++, convergence_tol.createMatlabArray());
-	if (max_num_iter.getStatus() != undef)
-		mxSetFieldByNumber(res, 0, i++, max_num_iter.createMatlabArray());
-	if (bs_norm.getStatus() != undef)
-		mxSetFieldByNumber(res, 0, i++, bs_norm.createMatlabArray());
-	if (converged.getStatus() != undef)
-		mxSetFieldByNumber(res, 0, i++, converged.createMatlabArray());
-	if (iter_last_norm.getStatus() != undef)
-		mxSetFieldByNumber(res, 0, i++, iter_last_norm.createMatlabArray());
-	if (num_iter.getStatus() != undef)
-		mxSetFieldByNumber(res, 0, i++, num_iter.createMatlabArray());
-	if (f_err1.getStatus() != undef)
-		mxSetFieldByNumber(res, 0, i++, f_err1.createMatlabArray());
-	if (f_errI.getStatus() != undef)
-		mxSetFieldByNumber(res, 0, i++, f_errI.createMatlabArray());
-	if (viv_err1.getStatus() != undef)
-		mxSetFieldByNumber(res, 0, i++, viv_err1.createMatlabArray());
-	if (viv_errI.getStatus() != undef)
-		mxSetFieldByNumber(res, 0, i++, viv_errI.createMatlabArray());
-	if (ivv_err1.getStatus() != undef)
-		mxSetFieldByNumber(res, 0, i++, ivv_err1.createMatlabArray());
-	if (ivv_errI.getStatus() != undef)
-		mxSetFieldByNumber(res, 0, i++, ivv_errI.createMatlabArray());
-	if (f_blocks.getStatus() != undef)
-		mxSetFieldByNumber(res, 0, i++, f_blocks.createMatlabArray());
-	if (f_largest.getStatus() != undef)
-		mxSetFieldByNumber(res, 0, i++, f_largest.createMatlabArray());
-	if (f_zeros.getStatus() != undef)
-		mxSetFieldByNumber(res, 0, i++, f_zeros.createMatlabArray());
-	if (f_offdiag.getStatus() != undef)
-		mxSetFieldByNumber(res, 0, i++, f_offdiag.createMatlabArray());
-	if (rcondA1.getStatus() != undef)
-		mxSetFieldByNumber(res, 0, i++, rcondA1.createMatlabArray());
-	if (rcondAI.getStatus() != undef)
-		mxSetFieldByNumber(res, 0, i++, rcondAI.createMatlabArray());
-	if (eig_min.getStatus() != undef)
-		mxSetFieldByNumber(res, 0, i++, eig_min.createMatlabArray());
-	if (mat_err1.getStatus() != undef)
-		mxSetFieldByNumber(res, 0, i++, mat_err1.createMatlabArray());
-	if (mat_errI.getStatus() != undef)
-		mxSetFieldByNumber(res, 0, i++, mat_errI.createMatlabArray());
-	if (mat_errF.getStatus() != undef)
-		mxSetFieldByNumber(res, 0, i++, mat_errF.createMatlabArray());
-	if (vec_err1.getStatus() != undef)
-		mxSetFieldByNumber(res, 0, i++, vec_err1.createMatlabArray());
-	if (vec_errI.getStatus() != undef)
-		mxSetFieldByNumber(res, 0, i++, vec_errI.createMatlabArray());
-	if (cpu_time.getStatus() != undef)
-		mxSetFieldByNumber(res, 0, i++, cpu_time.createMatlabArray());
-
-	return res;
-}
-#endif
-
-// Local Variables:
-// mode:C++
-// End:
diff --git a/dynare++/sylv/cc/SylvParams.h b/dynare++/sylv/cc/SylvParams.hh
similarity index 100%
rename from dynare++/sylv/cc/SylvParams.h
rename to dynare++/sylv/cc/SylvParams.hh
diff --git a/dynare++/sylv/cc/SylvesterSolver.h b/dynare++/sylv/cc/SylvesterSolver.hh
similarity index 89%
rename from dynare++/sylv/cc/SylvesterSolver.h
rename to dynare++/sylv/cc/SylvesterSolver.hh
index 344abd12740edc668aae6eb132191fe802677a0a..aa61c74244ecdcb7729737ecd4caee08bb3dec99 100644
--- a/dynare++/sylv/cc/SylvesterSolver.h
+++ b/dynare++/sylv/cc/SylvesterSolver.hh
@@ -5,12 +5,12 @@
 #ifndef SYLVESTER_SOLVER_H
 #define SYLVESTER_SOLVER_H
 
-#include "KronVector.h"
-#include "QuasiTriangular.h"
-#include "QuasiTriangularZero.h"
-#include "SimilarityDecomp.h"
-#include "SylvParams.h"
-#include "SchurDecomp.h"
+#include "KronVector.hh"
+#include "QuasiTriangular.hh"
+#include "QuasiTriangularZero.hh"
+#include "SimilarityDecomp.hh"
+#include "SylvParams.hh"
+#include "SchurDecomp.hh"
 
 class SylvesterSolver
 {
diff --git a/dynare++/sylv/cc/SymSchurDecomp.cc b/dynare++/sylv/cc/SymSchurDecomp.cc
new file mode 100644
index 0000000000000000000000000000000000000000..d5df7efb86eb30f389df7b7a2093581337bcee93
--- /dev/null
+++ b/dynare++/sylv/cc/SymSchurDecomp.cc
@@ -0,0 +1,104 @@
+/* $Header$ */
+
+/* Tag $Name$ */
+
+#include "SymSchurDecomp.hh"
+#include "SylvException.hh"
+
+#include <dynlapack.h>
+
+#include <algorithm>
+#include <cmath>
+
+SymSchurDecomp::SymSchurDecomp(const GeneralMatrix &mata)
+  : lambda(mata.numRows()), q(mata.numRows())
+{
+  // check mata is square
+  if (mata.numRows() != mata.numCols())
+    throw SYLV_MES_EXCEPTION("Matrix is not square in SymSchurDecomp constructor");
+
+  // prepare for dsyevr
+  const char *jobz = "V";
+  const char *range = "A";
+  const char *uplo = "U";
+  lapack_int n = mata.numRows();
+  GeneralMatrix tmpa(mata);
+  double *a = tmpa.base();
+  lapack_int lda = tmpa.getLD();
+  double dum;
+  double *vl = &dum;
+  double *vu = &dum;
+  lapack_int idum;
+  lapack_int *il = &idum;
+  lapack_int *iu = &idum;
+  double abstol = 0.0;
+  lapack_int m = n;
+  double *w = lambda.base();
+  double *z = q.base();
+  lapack_int ldz = q.getLD();
+  lapack_int *isuppz = new lapack_int[2*std::max(1, (int) m)];
+  double tmpwork;
+  lapack_int lwork = -1;
+  lapack_int tmpiwork;
+  lapack_int liwork = -1;
+  lapack_int info;
+
+  // query for lwork and liwork
+  dsyevr(jobz, range, uplo, &n, a, &lda, vl, vu, il, iu, &abstol,
+         &m, w, z, &ldz, isuppz, &tmpwork, &lwork, &tmpiwork, &liwork, &info);
+  lwork = (int) tmpwork;
+  liwork = tmpiwork;
+  // allocate work arrays
+  double *work = new double[lwork];
+  lapack_int *iwork = new lapack_int[liwork];
+
+  // do the calculation
+  dsyevr(jobz, range, uplo, &n, a, &lda, vl, vu, il, iu, &abstol,
+         &m, w, z, &ldz, isuppz, work, &lwork, iwork, &liwork, &info);
+
+  if (info < 0)
+    throw SYLV_MES_EXCEPTION("Internal error in SymSchurDecomp constructor");
+  if (info > 0)
+    throw SYLV_MES_EXCEPTION("Internal LAPACK error in DSYEVR");
+
+  delete [] work;
+  delete [] iwork;
+  delete [] isuppz;
+}
+
+void
+SymSchurDecomp::getFactor(GeneralMatrix &f) const
+{
+  if (f.numRows() != q.numRows())
+    throw SYLV_MES_EXCEPTION("Wrong dimension of factor matrix in SymSchurDecomp::getFactor");
+  if (f.numRows() != f.numCols())
+    throw SYLV_MES_EXCEPTION("Factor matrix is not square in SymSchurDecomp::getFactor");
+  if (!isPositiveSemidefinite())
+    throw SYLV_MES_EXCEPTION("Symmetric decomposition not positive semidefinite in SymSchurDecomp::getFactor");
+
+  f = q;
+  for (int i = 0; i < f.numCols(); i++)
+    {
+      Vector fi(f, i);
+      fi.mult(std::sqrt(lambda[i]));
+    }
+}
+
+// LAPACK says that eigenvalues are ordered in ascending order, but we
+// do not rely her on it
+bool
+SymSchurDecomp::isPositiveSemidefinite() const
+{
+  for (int i = 0; i < lambda.length(); i++)
+    if (lambda[i] < 0)
+      return false;
+  return true;
+}
+
+void
+SymSchurDecomp::correctDefinitness(double tol)
+{
+  for (int i = 0; i < lambda.length(); i++)
+    if (lambda[i] < 0 && lambda[i] > -tol)
+      lambda[i] = 0.0;
+}
diff --git a/dynare++/sylv/cc/SymSchurDecomp.cpp b/dynare++/sylv/cc/SymSchurDecomp.cpp
deleted file mode 100644
index 1bedc3b88f4d6a44ad64a5e700db1483d6bf1a18..0000000000000000000000000000000000000000
--- a/dynare++/sylv/cc/SymSchurDecomp.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-/* $Header$ */
-
-/* Tag $Name$ */
-
-#include "SymSchurDecomp.h"
-#include "SylvException.h"
-
-#include <dynlapack.h>
-
-#include <algorithm>
-#include <cmath>
-
-SymSchurDecomp::SymSchurDecomp(const GeneralMatrix& mata)
-	: lambda(mata.numRows()), q(mata.numRows())
-{
-	// check mata is square
-	if (mata.numRows() != mata.numCols())
-		throw SYLV_MES_EXCEPTION("Matrix is not square in SymSchurDecomp constructor");
-
-	// prepare for dsyevr
-	const char* jobz = "V";
-	const char* range = "A";
-	const char* uplo = "U";
-	lapack_int n = mata.numRows();
-	GeneralMatrix tmpa(mata);
-	double* a = tmpa.base();
-	lapack_int lda = tmpa.getLD();
-	double dum;
-	double* vl = &dum;
-	double* vu = &dum;
-	lapack_int idum;
-	lapack_int* il = &idum;
-	lapack_int* iu = &idum;
-	double abstol = 0.0;
-	lapack_int m = n;
-	double* w = lambda.base();
-	double* z = q.base();
-	lapack_int ldz = q.getLD();
-	lapack_int* isuppz = new lapack_int[2*std::max(1,(int) m)];
-	double tmpwork;
-	lapack_int lwork = -1;
-	lapack_int tmpiwork;
-	lapack_int liwork = -1;
-	lapack_int info;
-
-	// query for lwork and liwork
-	dsyevr(jobz, range, uplo, &n, a, &lda, vl, vu, il, iu, &abstol,
-				  &m, w, z, &ldz, isuppz, &tmpwork, &lwork, &tmpiwork, &liwork, &info);
-	lwork = (int)tmpwork;
-	liwork = tmpiwork;
-	// allocate work arrays
-	double* work = new double[lwork];
-	lapack_int* iwork = new lapack_int[liwork];
-	
-	// do the calculation
-	dsyevr(jobz, range, uplo, &n, a, &lda, vl, vu, il, iu, &abstol,
-				  &m, w, z, &ldz, isuppz, work, &lwork, iwork, &liwork, &info);
-
-	if (info < 0)
-		throw SYLV_MES_EXCEPTION("Internal error in SymSchurDecomp constructor");
-	if (info > 0)
-		throw SYLV_MES_EXCEPTION("Internal LAPACK error in DSYEVR");
-
-	delete [] work;
-	delete [] iwork;
-	delete [] isuppz;
-}
-
-void SymSchurDecomp::getFactor(GeneralMatrix& f) const
-{
-	if (f.numRows() != q.numRows())
-		throw SYLV_MES_EXCEPTION("Wrong dimension of factor matrix in SymSchurDecomp::getFactor");
-	if (f.numRows() != f.numCols())
-		throw SYLV_MES_EXCEPTION("Factor matrix is not square in SymSchurDecomp::getFactor");
-	if (! isPositiveSemidefinite())
-		throw SYLV_MES_EXCEPTION("Symmetric decomposition not positive semidefinite in SymSchurDecomp::getFactor");
-
-	f = q;
-	for (int i = 0; i < f.numCols(); i++) {
-		Vector fi(f, i);
-		fi.mult(std::sqrt(lambda[i]));
-	}
-}
-
-
-// LAPACK says that eigenvalues are ordered in ascending order, but we
-// do not rely her on it
-bool SymSchurDecomp::isPositiveSemidefinite() const
-{
-	for (int i = 0; i < lambda.length(); i++)
-		if (lambda[i] < 0)
-			return false;
-	return true;
-}
-
-void SymSchurDecomp::correctDefinitness(double tol)
-{
-	for (int i = 0; i < lambda.length(); i++)
-		if (lambda[i] < 0 && lambda[i] > - tol)
-			lambda[i] = 0.0;
-}
diff --git a/dynare++/sylv/cc/SymSchurDecomp.h b/dynare++/sylv/cc/SymSchurDecomp.hh
similarity index 97%
rename from dynare++/sylv/cc/SymSchurDecomp.h
rename to dynare++/sylv/cc/SymSchurDecomp.hh
index 9b95f36bff767acc212f1a47d3cebd5e9d24488b..4ce35b4c477c695f033930471095ab26396b7726 100644
--- a/dynare++/sylv/cc/SymSchurDecomp.h
+++ b/dynare++/sylv/cc/SymSchurDecomp.hh
@@ -5,7 +5,7 @@
 #ifndef SYM_SCHUR_DECOMP_H
 #define SYM_SCHUR_DECOMP_H
 
-#include "SylvMatrix.h"
+#include "SylvMatrix.hh"
 
 class SymSchurDecomp
 {
diff --git a/dynare++/sylv/cc/TriangularSylvester.cc b/dynare++/sylv/cc/TriangularSylvester.cc
new file mode 100644
index 0000000000000000000000000000000000000000..232a33976532aa43829eeb1f260865da5bbaa539
--- /dev/null
+++ b/dynare++/sylv/cc/TriangularSylvester.cc
@@ -0,0 +1,433 @@
+/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/TriangularSylvester.cpp,v 1.1.1.1 2004/06/04 13:00:59 kamenik Exp $ */
+
+/* Tag $Name:  $ */
+
+#include "TriangularSylvester.hh"
+#include "QuasiTriangularZero.hh"
+#include "KronUtils.hh"
+#include "BlockDiagonal.hh"
+
+#include <cstdio>
+#include <cmath>
+
+double TriangularSylvester::diag_zero = 1.e-15;
+double TriangularSylvester::diag_zero_sq = 1.e-30;
+
+TriangularSylvester::TriangularSylvester(const QuasiTriangular &k,
+                                         const QuasiTriangular &f)
+  : SylvesterSolver(k, f),
+    matrixKK(matrixK->clone(2, *matrixK)),
+    matrixFF(new QuasiTriangular(2, *matrixF))
+{
+}
+
+TriangularSylvester::TriangularSylvester(const SchurDecompZero &kdecomp,
+                                         const SchurDecomp &fdecomp)
+  : SylvesterSolver(kdecomp, fdecomp),
+    matrixKK(matrixK->clone(2, *matrixK)),
+    matrixFF(new QuasiTriangular(2, *matrixF))
+{
+}
+
+TriangularSylvester::TriangularSylvester(const SchurDecompZero &kdecomp,
+                                         const SimilarityDecomp &fdecomp)
+  : SylvesterSolver(kdecomp, fdecomp),
+    matrixKK(matrixK->clone(2, *matrixK)),
+    matrixFF(new BlockDiagonal(2, *matrixF))
+{
+}
+
+TriangularSylvester::~TriangularSylvester()
+{
+  delete matrixKK;
+  delete matrixFF;
+}
+
+void
+TriangularSylvester::print() const
+{
+  printf("matrix K (%d):\n", matrixK->getDiagonal().getSize());
+  matrixK->print();
+  printf("matrix F (%d):\n", matrixF->getDiagonal().getSize());
+  matrixF->print();
+}
+
+void
+TriangularSylvester::solve(SylvParams &pars, KronVector &d) const
+{
+  double eig_min = 1e30;
+  solvi(1., d, eig_min);
+  pars.eig_min = sqrt(eig_min);
+}
+
+void
+TriangularSylvester::solvi(double r, KronVector &d, double &eig_min) const
+{
+  if (d.getDepth() == 0)
+    {
+      QuasiTriangular *t = matrixK->clone(r);
+      t->solvePre(d, eig_min);
+      delete t;
+    }
+  else
+    {
+      for (const_diag_iter di = matrixF->diag_begin();
+           di != matrixF->diag_end();
+           ++di)
+        {
+          if ((*di).isReal())
+            {
+              solviRealAndEliminate(r, di, d, eig_min);
+            }
+          else
+            {
+              solviComplexAndEliminate(r, di, d, eig_min);
+            }
+        }
+    }
+}
+
+void
+TriangularSylvester::solvii(double alpha, double beta1, double beta2,
+                            KronVector &d1, KronVector &d2,
+                            double &eig_min) const
+{
+  KronVector d1tmp(d1);
+  KronVector d2tmp(d2);
+  linEval(alpha, beta1, beta2, d1, d2, d1tmp, d2tmp);
+  solviip(alpha, beta1*beta2, d1, eig_min);
+  solviip(alpha, beta1*beta2, d2, eig_min);
+}
+
+void
+TriangularSylvester::solviip(double alpha, double betas,
+                             KronVector &d, double &eig_min) const
+{
+  // quick exit to solvi if betas is small
+  if (betas < diag_zero_sq)
+    {
+      solvi(alpha, d, eig_min);
+      solvi(alpha, d, eig_min);
+      return;
+    }
+
+  if (d.getDepth() == 0)
+    {
+      double aspbs = alpha*alpha+betas;
+      QuasiTriangular *t = matrixK->clone(2*alpha, aspbs, *matrixKK);
+      t->solvePre(d, eig_min);
+      delete t;
+    }
+  else
+    {
+      const_diag_iter di = matrixF->diag_begin();
+      const_diag_iter dsi = matrixFF->diag_begin();
+      for (; di != matrixF->diag_end(); ++di, ++dsi)
+        {
+          if ((*di).isReal())
+            {
+              solviipRealAndEliminate(alpha, betas, di, dsi, d, eig_min);
+            }
+          else
+            {
+              solviipComplexAndEliminate(alpha, betas, di, dsi, d, eig_min);
+            }
+        }
+    }
+}
+
+void
+TriangularSylvester::solviRealAndEliminate(double r, const_diag_iter di,
+                                           KronVector &d, double &eig_min) const
+{
+  // di is real
+  int jbar = (*di).getIndex();
+  double f = *((*di).getAlpha());
+  KronVector dj(d, jbar);
+  // solve system
+  if (abs(r*f) > diag_zero)
+    {
+      solvi(r*f, dj, eig_min);
+    }
+  // calculate y
+  KronVector y((const KronVector &)dj);
+  KronUtils::multKron(*matrixF, *matrixK, y);
+  y.mult(r);
+  double divisor = 1.0;
+  solviEliminateReal(di, d, y, divisor);
+}
+
+void
+TriangularSylvester::solviEliminateReal(const_diag_iter di, KronVector &d,
+                                        const KronVector &y, double divisor) const
+{
+  for (const_row_iter ri = matrixF->row_begin(*di);
+       ri != matrixF->row_end(*di);
+       ++ri)
+    {
+      KronVector dk(d, ri.getCol());
+      dk.add(-(*ri)/divisor, y);
+    }
+}
+
+void
+TriangularSylvester::solviComplexAndEliminate(double r, const_diag_iter di,
+                                              KronVector &d, double &eig_min) const
+{
+  // di is complex
+  int jbar = (*di).getIndex();
+  // pick data
+  double alpha = *(*di).getAlpha();
+  double beta1 = (*di).getBeta2();
+  double beta2 = -(*di).getBeta1();
+  double aspbs = (*di).getDeterminant();
+  KronVector dj(d, jbar);
+  KronVector djj(d, jbar+1);
+  // solve
+  if (r*r*aspbs > diag_zero_sq)
+    {
+      solvii(r*alpha, r*beta1, r*beta2, dj, djj, eig_min);
+    }
+  KronVector y1(dj);
+  KronVector y2(djj);
+  KronUtils::multKron(*matrixF, *matrixK, y1);
+  KronUtils::multKron(*matrixF, *matrixK, y2);
+  y1.mult(r);
+  y2.mult(r);
+  double divisor = 1.0;
+  solviEliminateComplex(di, d, y1, y2, divisor);
+}
+
+void
+TriangularSylvester::solviEliminateComplex(const_diag_iter di, KronVector &d,
+                                           const KronVector &y1, const KronVector &y2,
+                                           double divisor) const
+{
+  for (const_row_iter ri = matrixF->row_begin(*di);
+       ri != matrixF->row_end(*di);
+       ++ri)
+    {
+      KronVector dk(d, ri.getCol());
+      dk.add(-ri.a()/divisor, y1);
+      dk.add(-ri.b()/divisor, y2);
+    }
+}
+
+void
+TriangularSylvester::solviipRealAndEliminate(double alpha, double betas,
+                                             const_diag_iter di, const_diag_iter dsi,
+                                             KronVector &d, double &eig_min) const
+{
+  // di, and dsi are real
+  int jbar = (*di).getIndex();
+  double aspbs = alpha*alpha+betas;
+  // pick data
+  double f = *((*di).getAlpha());
+  double fs = f*f;
+  KronVector dj(d, jbar);
+  // solve
+  if (fs*aspbs > diag_zero_sq)
+    {
+      solviip(f*alpha, fs*betas, dj, eig_min);
+    }
+  KronVector y1((const KronVector &)dj);
+  KronVector y2((const KronVector &)dj);
+  KronUtils::multKron(*matrixF, *matrixK, y1);
+  y1.mult(2*alpha);
+  KronUtils::multKron(*matrixFF, *matrixKK, y2);
+  y2.mult(aspbs);
+  double divisor = 1.0;
+  double divisor2 = 1.0;
+  solviipEliminateReal(di, dsi, d, y1, y2, divisor, divisor2);
+}
+
+void
+TriangularSylvester::solviipEliminateReal(const_diag_iter di, const_diag_iter dsi,
+                                          KronVector &d,
+                                          const KronVector &y1, const KronVector &y2,
+                                          double divisor, double divisor2) const
+{
+  const_row_iter ri = matrixF->row_begin(*di);
+  const_row_iter rsi = matrixFF->row_begin(*dsi);
+  for (; ri != matrixF->row_end(*di); ++ri, ++rsi)
+    {
+      KronVector dk(d, ri.getCol());
+      dk.add(-(*ri)/divisor, y1);
+      dk.add(-(*rsi)/divisor2, y2);
+    }
+}
+
+void
+TriangularSylvester::solviipComplexAndEliminate(double alpha, double betas,
+                                                const_diag_iter di, const_diag_iter dsi,
+                                                KronVector &d, double &eig_min) const
+{
+  // di, and dsi are complex
+  int jbar = (*di).getIndex();
+  double aspbs = alpha*alpha+betas;
+  // pick data
+  double gamma = *((*di).getAlpha());
+  double delta1 = (*di).getBeta2(); // swap because of transpose
+  double delta2 = -(*di).getBeta1();
+  double gspds = (*di).getDeterminant();
+  KronVector dj(d, jbar);
+  KronVector djj(d, jbar+1);
+  if (gspds*aspbs > diag_zero_sq)
+    {
+      solviipComplex(alpha, betas, gamma, delta1, delta2, dj, djj, eig_min);
+    }
+  // here dj, djj is solution, set y1, y2, y11, y22
+  // y1
+  KronVector y1((const KronVector &)dj);
+  KronUtils::multKron(*matrixF, *matrixK, y1);
+  y1.mult(2*alpha);
+  // y11
+  KronVector y11((const KronVector &)djj);
+  KronUtils::multKron(*matrixF, *matrixK, y11);
+  y11.mult(2*alpha);
+  // y2
+  KronVector y2((const KronVector &)dj);
+  KronUtils::multKron(*matrixFF, *matrixKK, y2);
+  y2.mult(aspbs);
+  // y22
+  KronVector y22((const KronVector &)djj);
+  KronUtils::multKron(*matrixFF, *matrixKK, y22);
+  y22.mult(aspbs);
+
+  double divisor = 1.0;
+  solviipEliminateComplex(di, dsi, d, y1, y11, y2, y22, divisor);
+}
+
+void
+TriangularSylvester::solviipComplex(double alpha, double betas, double gamma,
+                                    double delta1, double delta2,
+                                    KronVector &d1, KronVector &d2,
+                                    double &eig_min) const
+{
+  KronVector d1tmp(d1);
+  KronVector d2tmp(d2);
+  quaEval(alpha, betas, gamma, delta1, delta2,
+          d1, d2, d1tmp, d2tmp);
+  double delta = sqrt(delta1*delta2);
+  double beta = sqrt(betas);
+  double a1 = alpha*gamma - beta*delta;
+  double b1 = alpha*delta + gamma*beta;
+  double a2 = alpha*gamma + beta*delta;
+  double b2 = alpha*delta - gamma*beta;
+  solviip(a2, b2*b2, d1, eig_min);
+  solviip(a1, b1*b1, d1, eig_min);
+  solviip(a2, b2*b2, d2, eig_min);
+  solviip(a1, b1*b1, d2, eig_min);
+}
+
+void
+TriangularSylvester::solviipEliminateComplex(const_diag_iter di, const_diag_iter dsi,
+                                             KronVector &d,
+                                             const KronVector &y1, const KronVector &y11,
+                                             const KronVector &y2, const KronVector &y22,
+                                             double divisor) const
+{
+  const_row_iter ri = matrixF->row_begin(*di);
+  const_row_iter rsi = matrixFF->row_begin(*dsi);
+  for (; ri != matrixF->row_end(*di); ++ri, ++rsi)
+    {
+      KronVector dk(d, ri.getCol());
+      dk.add(-ri.a()/divisor, y1);
+      dk.add(-ri.b()/divisor, y11);
+      dk.add(-rsi.a()/divisor, y2);
+      dk.add(-rsi.b()/divisor, y22);
+    }
+}
+
+void
+TriangularSylvester::linEval(double alpha, double beta1, double beta2,
+                             KronVector &x1, KronVector &x2,
+                             const ConstKronVector &d1, const ConstKronVector &d2) const
+{
+  KronVector d1tmp(d1); // make copy
+  KronVector d2tmp(d2); // make copy
+  KronUtils::multKron(*matrixF, *matrixK, d1tmp);
+  KronUtils::multKron(*matrixF, *matrixK, d2tmp);
+  x1 = d1;
+  x2 = d2;
+  Vector::mult2a(alpha, beta1, -beta2, x1, x2, d1tmp, d2tmp);
+}
+
+void
+TriangularSylvester::quaEval(double alpha, double betas,
+                             double gamma, double delta1, double delta2,
+                             KronVector &x1, KronVector &x2,
+                             const ConstKronVector &d1, const ConstKronVector &d2) const
+{
+  KronVector d1tmp(d1); // make copy
+  KronVector d2tmp(d2); // make copy
+  KronUtils::multKron(*matrixF, *matrixK, d1tmp);
+  KronUtils::multKron(*matrixF, *matrixK, d2tmp);
+  x1 = d1;
+  x2 = d2;
+  Vector::mult2a(2*alpha*gamma, 2*alpha*delta1, -2*alpha*delta2,
+                 x1, x2, d1tmp, d2tmp);
+  d1tmp = d1; // restore to d1
+  d2tmp = d2; // restore to d2
+  KronUtils::multKron(*matrixFF, *matrixKK, d1tmp);
+  KronUtils::multKron(*matrixFF, *matrixKK, d2tmp);
+  double aspbs = alpha*alpha + betas;
+  double gspds = gamma*gamma - delta1*delta2;
+  Vector::mult2a(aspbs*gspds, 2*aspbs*gamma*delta1, -2*aspbs*gamma*delta2,
+                 x1, x2, d1tmp, d2tmp);
+}
+
+double
+TriangularSylvester::getEigSep(int depth) const
+{
+  int f_size = matrixF->getDiagonal().getSize();
+  Vector feig(2*f_size);
+  matrixF->getDiagonal().getEigenValues(feig);
+  int k_size = matrixK->getDiagonal().getSize();
+  Vector keig(2*k_size);
+  matrixK->getDiagonal().getEigenValues(keig);
+
+  KronVector eig(f_size, 2*k_size, depth);
+  multEigVector(eig, feig, keig);
+
+  double min = 1.0e20;
+  for (int i = 0; i < eig.length()/2; i++)
+    {
+      double alpha = eig[2*i];
+      double beta = eig[2*i+1];
+      double ss = (alpha+1)*(alpha+1)+beta*beta;
+      if (min > ss)
+        min = ss;
+    }
+
+  return min;
+}
+
+void
+TriangularSylvester::multEigVector(KronVector &eig, const Vector &feig,
+                                   const Vector &keig)
+{
+  int depth = eig.getDepth();
+  int m = eig.getM();
+  int n = eig.getN();
+
+  if (depth == 0)
+    {
+      eig = keig;
+    }
+  else
+    {
+      KronVector aux(m, n, depth-1);
+      multEigVector(aux, feig, keig);
+      for (int i = 0; i < m; i++)
+        {
+          KronVector eigi(eig, i);
+          eigi.zeros();
+          eigi.add(&feig[2*i], aux);
+        }
+    }
+}
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/dynare++/sylv/cc/TriangularSylvester.cpp b/dynare++/sylv/cc/TriangularSylvester.cpp
deleted file mode 100644
index baf9e45d394940165b29920a845e0968d3d17524..0000000000000000000000000000000000000000
--- a/dynare++/sylv/cc/TriangularSylvester.cpp
+++ /dev/null
@@ -1,392 +0,0 @@
-/* $Header: /var/lib/cvs/dynare_cpp/sylv/cc/TriangularSylvester.cpp,v 1.1.1.1 2004/06/04 13:00:59 kamenik Exp $ */
-
-/* Tag $Name:  $ */
-
-#include "TriangularSylvester.h"
-#include "QuasiTriangularZero.h"
-#include "KronUtils.h"
-#include "BlockDiagonal.h"
-
-#include <cstdio>
-#include <cmath>
-
-double TriangularSylvester::diag_zero = 1.e-15;
-double TriangularSylvester::diag_zero_sq = 1.e-30;
-
-TriangularSylvester::TriangularSylvester(const QuasiTriangular& k,
-										 const QuasiTriangular& f)
-	: SylvesterSolver(k, f),
-	  matrixKK(matrixK->clone(2, *matrixK)),
-	  matrixFF(new QuasiTriangular(2, *matrixF))
-{
-}
-
-TriangularSylvester::TriangularSylvester(const SchurDecompZero& kdecomp,
-										 const SchurDecomp& fdecomp)
-	: SylvesterSolver(kdecomp, fdecomp),
-	  matrixKK(matrixK->clone(2, *matrixK)),
-	  matrixFF(new QuasiTriangular(2, *matrixF))
-{
-}
-
-TriangularSylvester::TriangularSylvester(const SchurDecompZero& kdecomp,
-										 const SimilarityDecomp& fdecomp)
-	: SylvesterSolver(kdecomp, fdecomp),
-	  matrixKK(matrixK->clone(2, *matrixK)),
-	  matrixFF(new BlockDiagonal(2, *matrixF))
-{
-}
-
-TriangularSylvester::~TriangularSylvester()
-{
-	delete matrixKK;
-	delete matrixFF;
-}
-
-void TriangularSylvester::print() const
-{
-	printf("matrix K (%d):\n",matrixK->getDiagonal().getSize());
-	matrixK->print();
-	printf("matrix F (%d):\n",matrixF->getDiagonal().getSize());
-	matrixF->print();
-}
-
-void TriangularSylvester::solve(SylvParams& pars, KronVector& d) const
-{
-	double eig_min = 1e30;
-	solvi(1., d, eig_min);
-	pars.eig_min = sqrt(eig_min);
-}
-
-void TriangularSylvester::solvi(double r, KronVector& d, double& eig_min) const
-{
-	if (d.getDepth() == 0) {
-		QuasiTriangular* t = matrixK->clone(r);
-		t->solvePre(d, eig_min);
-		delete t;
-	} else {
-		for (const_diag_iter di = matrixF->diag_begin();
-			 di != matrixF->diag_end();
-			 ++di) {
-			if ((*di).isReal()) {
-				solviRealAndEliminate(r, di, d, eig_min);
-			} else {
-				solviComplexAndEliminate(r, di, d, eig_min);
-			}
-		}
-	}
-}
-
-
-void TriangularSylvester::solvii(double alpha, double beta1, double beta2,
-								 KronVector& d1, KronVector& d2,
-								 double& eig_min) const
-{
-	KronVector d1tmp(d1);
-	KronVector d2tmp(d2);
-	linEval(alpha, beta1, beta2, d1, d2, d1tmp, d2tmp);
-	solviip(alpha, beta1*beta2, d1, eig_min);
-	solviip(alpha, beta1*beta2, d2, eig_min);
-}
-
-
-void TriangularSylvester::solviip(double alpha, double betas,
-								  KronVector& d, double& eig_min) const
-{
-	// quick exit to solvi if betas is small
-	if (betas < diag_zero_sq) {
-		solvi(alpha, d, eig_min);
-		solvi(alpha, d, eig_min);
-		return;
-	}
-
-	if (d.getDepth() == 0) {
-		double aspbs = alpha*alpha+betas;
-		QuasiTriangular* t= matrixK->clone(2*alpha, aspbs, *matrixKK);
-		t->solvePre(d, eig_min);
-		delete t;
-	} else {
-		const_diag_iter di = matrixF->diag_begin();
-		const_diag_iter dsi = matrixFF->diag_begin();
-		for (; di != matrixF->diag_end(); ++di, ++dsi) {
-			if ((*di).isReal()) {
-				solviipRealAndEliminate(alpha, betas, di, dsi, d, eig_min);
-			} else {
-				solviipComplexAndEliminate(alpha, betas, di, dsi, d, eig_min);
-			}
-		}
-	}
-}
-
-
-void TriangularSylvester::solviRealAndEliminate(double r, const_diag_iter di,
-												KronVector& d, double& eig_min) const
-{
-	// di is real
-	int jbar = (*di).getIndex();
-	double f = *((*di).getAlpha());
-	KronVector dj(d, jbar);
-	// solve system
-	if (abs(r*f) > diag_zero) { 
-		solvi(r*f, dj, eig_min);
-	}
-	// calculate y
-	KronVector y((const KronVector&)dj);
-	KronUtils::multKron(*matrixF, *matrixK, y);
-	y.mult(r);
-	double divisor = 1.0;
-	solviEliminateReal(di, d, y, divisor);
-}
-
-void TriangularSylvester::solviEliminateReal(const_diag_iter di, KronVector& d,
-											 const KronVector& y, double divisor) const
-{
-	for (const_row_iter ri = matrixF->row_begin(*di);
-		 ri != matrixF->row_end(*di);
-		 ++ri) {
-		KronVector dk(d, ri.getCol());
-		dk.add(-(*ri)/divisor, y);
-	}
-}
-
-void TriangularSylvester::solviComplexAndEliminate(double r, const_diag_iter di,
-												   KronVector& d, double& eig_min) const
-{
-	// di is complex
-	int jbar = (*di).getIndex();
-	// pick data
-	double alpha = *(*di).getAlpha();
-	double beta1 = (*di).getBeta2();
-	double beta2 = -(*di).getBeta1();
-	double aspbs = (*di).getDeterminant();
-	KronVector dj(d, jbar);
-	KronVector djj(d, jbar+1);
-	// solve
-	if (r*r*aspbs > diag_zero_sq) { 
-		solvii(r*alpha, r*beta1, r*beta2, dj, djj, eig_min);
-	}
-	KronVector y1(dj);
-	KronVector y2(djj);
-	KronUtils::multKron(*matrixF, *matrixK, y1);
-	KronUtils::multKron(*matrixF, *matrixK, y2);
-	y1.mult(r);
-	y2.mult(r);
-	double divisor = 1.0;
-	solviEliminateComplex(di, d, y1, y2, divisor);
-}
-
-void TriangularSylvester::solviEliminateComplex(const_diag_iter di, KronVector& d,
-												const KronVector& y1, const KronVector& y2,
-												double divisor) const
-{
-	for (const_row_iter ri = matrixF->row_begin(*di);
-		 ri != matrixF->row_end(*di);
-		 ++ri) {
-		KronVector dk(d, ri.getCol());
-		dk.add(-ri.a()/divisor, y1);
-		dk.add(-ri.b()/divisor, y2);
-	}
-}
-
-void TriangularSylvester::solviipRealAndEliminate(double alpha, double betas,
-												  const_diag_iter di, const_diag_iter dsi,
-												  KronVector& d, double& eig_min) const
-{
-	// di, and dsi are real		
-	int jbar = (*di).getIndex();
-	double aspbs = alpha*alpha+betas;
-	// pick data
-	double f = *((*di).getAlpha());
-	double fs = f*f;
-	KronVector dj(d, jbar);
-	// solve
-	if (fs*aspbs > diag_zero_sq) {
-		solviip(f*alpha, fs*betas, dj, eig_min);
-	}
-	KronVector y1((const KronVector&)dj);
-	KronVector y2((const KronVector&)dj);
-	KronUtils::multKron(*matrixF, *matrixK, y1);
-	y1.mult(2*alpha);
-	KronUtils::multKron(*matrixFF, *matrixKK, y2);
-	y2.mult(aspbs);
-	double divisor = 1.0;
-	double divisor2 = 1.0;
-	solviipEliminateReal(di, dsi, d, y1, y2, divisor, divisor2);
-}
-
-void TriangularSylvester::solviipEliminateReal(const_diag_iter di, const_diag_iter dsi,
-											   KronVector& d,
-											   const KronVector& y1, const KronVector& y2,
-											   double divisor, double divisor2) const
-{
-	const_row_iter ri = matrixF->row_begin(*di);
-	const_row_iter rsi = matrixFF->row_begin(*dsi);
-	for (; ri != matrixF->row_end(*di); ++ri, ++rsi) {
-		KronVector dk(d, ri.getCol());
-		dk.add(-(*ri)/divisor, y1);
-		dk.add(-(*rsi)/divisor2, y2);
-	}
-} 
-
-void TriangularSylvester::solviipComplexAndEliminate(double alpha, double betas,
-													 const_diag_iter di, const_diag_iter dsi,
-													 KronVector& d, double& eig_min) const
-{
-	// di, and dsi are complex
-	int jbar = (*di).getIndex();
-	double aspbs = alpha*alpha+betas;
-	// pick data
-	double gamma = *((*di).getAlpha());
-	double delta1 = (*di).getBeta2(); // swap because of transpose
-	double delta2 = -(*di).getBeta1();
-	double gspds = (*di).getDeterminant();
-	KronVector dj(d, jbar);
-	KronVector djj(d, jbar+1);
-	if (gspds*aspbs > diag_zero_sq) {
-		solviipComplex(alpha, betas, gamma, delta1, delta2, dj, djj, eig_min);
-	}
-	// here dj, djj is solution, set y1, y2, y11, y22
-	// y1
-	KronVector y1((const KronVector&) dj);
-	KronUtils::multKron(*matrixF, *matrixK, y1);
-	y1.mult(2*alpha);
-	// y11
-	KronVector y11((const KronVector&) djj);
-	KronUtils::multKron(*matrixF, *matrixK, y11);
-	y11.mult(2*alpha);
-	// y2
-	KronVector y2((const KronVector&) dj);
-	KronUtils::multKron(*matrixFF, *matrixKK, y2);
-	y2.mult(aspbs);
-	// y22
-	KronVector y22((const KronVector&) djj);
-	KronUtils::multKron(*matrixFF, *matrixKK, y22);
-	y22.mult(aspbs);
-
-	double divisor = 1.0;
-	solviipEliminateComplex(di, dsi, d, y1, y11, y2, y22, divisor);
-}
-
-
-void TriangularSylvester::solviipComplex(double alpha, double betas, double gamma,
-										 double delta1, double delta2,
-										 KronVector& d1, KronVector& d2,
-										 double& eig_min) const
-{
-	KronVector d1tmp(d1);
-	KronVector d2tmp(d2);
-	quaEval(alpha, betas, gamma, delta1, delta2,
-			d1, d2, d1tmp, d2tmp);
-	double delta = sqrt(delta1*delta2);
-	double beta = sqrt(betas);
-	double a1 = alpha*gamma - beta*delta;
-	double b1 = alpha*delta + gamma*beta;
-	double a2 = alpha*gamma + beta*delta;
-	double b2 = alpha*delta - gamma*beta;
-	solviip(a2, b2*b2, d1, eig_min);
-	solviip(a1, b1*b1, d1, eig_min);
-	solviip(a2, b2*b2, d2, eig_min);
-	solviip(a1, b1*b1, d2, eig_min);
-}
-
-void TriangularSylvester::solviipEliminateComplex(const_diag_iter di, const_diag_iter dsi,
-												  KronVector& d,
-												  const KronVector& y1, const KronVector& y11,
-												  const KronVector& y2, const KronVector& y22,
-												  double divisor) const
-{
-	const_row_iter ri = matrixF->row_begin(*di);
-	const_row_iter rsi = matrixFF->row_begin(*dsi);
-	for (; ri != matrixF->row_end(*di); ++ri, ++rsi) {
-		KronVector dk(d, ri.getCol());
-		dk.add(-ri.a()/divisor, y1);
-		dk.add(-ri.b()/divisor, y11);
-		dk.add(-rsi.a()/divisor, y2);
-		dk.add(-rsi.b()/divisor, y22);
-	}
-}
-
-void TriangularSylvester::linEval(double alpha, double beta1, double beta2,
-								  KronVector& x1, KronVector& x2,
-								  const ConstKronVector& d1, const ConstKronVector& d2) const
-{
-	KronVector d1tmp(d1); // make copy
-	KronVector d2tmp(d2); // make copy
-	KronUtils::multKron(*matrixF, *matrixK, d1tmp);
-	KronUtils::multKron(*matrixF, *matrixK, d2tmp);
-	x1 = d1;
-	x2 = d2;
-	Vector::mult2a(alpha, beta1, -beta2, x1, x2, d1tmp, d2tmp);
-}
-
-void TriangularSylvester::quaEval(double alpha, double betas,
-								  double gamma, double delta1, double delta2,
-								  KronVector& x1, KronVector& x2,
-								  const ConstKronVector& d1, const ConstKronVector& d2) const
-{
-	KronVector d1tmp(d1); // make copy
-	KronVector d2tmp(d2); // make copy
-	KronUtils::multKron(*matrixF, *matrixK, d1tmp);
-	KronUtils::multKron(*matrixF, *matrixK, d2tmp);
-	x1 = d1;
-	x2 = d2;
-	Vector::mult2a(2*alpha*gamma, 2*alpha*delta1, -2*alpha*delta2,
-				   x1, x2, d1tmp, d2tmp);
-	d1tmp = d1; // restore to d1
-	d2tmp = d2; // restore to d2
-	KronUtils::multKron(*matrixFF, *matrixKK, d1tmp);
-	KronUtils::multKron(*matrixFF, *matrixKK, d2tmp);
-	double aspbs = alpha*alpha + betas;
-	double gspds = gamma*gamma - delta1*delta2;
-	Vector::mult2a(aspbs*gspds, 2*aspbs*gamma*delta1, -2*aspbs*gamma*delta2,
-				   x1, x2, d1tmp, d2tmp);
-}
-
-
-double TriangularSylvester::getEigSep(int depth) const
-{
-	int f_size = matrixF->getDiagonal().getSize();
-	Vector feig(2*f_size);
-	matrixF->getDiagonal().getEigenValues(feig);
-	int k_size = matrixK->getDiagonal().getSize();
-	Vector keig(2*k_size);
-	matrixK->getDiagonal().getEigenValues(keig);
-	
-	KronVector eig(f_size, 2*k_size, depth);
-	multEigVector(eig, feig, keig);
-
-	double min = 1.0e20;
-	for (int i = 0; i < eig.length()/2; i++) {
-		double alpha = eig[2*i];
-		double beta = eig[2*i+1];
-		double ss = (alpha+1)*(alpha+1)+beta*beta;
-		if (min > ss)
-			min = ss;
-	}
-
-	return min;
-}
-
-void TriangularSylvester::multEigVector(KronVector& eig, const Vector& feig,
-										const Vector& keig)
-{
-	int depth = eig.getDepth();
-	int m = eig.getM();
-	int n = eig.getN();
-
-	if (depth == 0) {
-		eig = keig;
-	} else {
-		KronVector aux(m, n, depth-1);
-		multEigVector(aux, feig, keig);
-		for (int i = 0; i < m; i++) {
-			KronVector eigi(eig, i);
-			eigi.zeros();
-			eigi.add(&feig[2*i], aux);
-		}
-	}
-}
-
-// Local Variables:
-// mode:C++
-// End:
diff --git a/dynare++/sylv/cc/TriangularSylvester.h b/dynare++/sylv/cc/TriangularSylvester.hh
similarity index 97%
rename from dynare++/sylv/cc/TriangularSylvester.h
rename to dynare++/sylv/cc/TriangularSylvester.hh
index fa652bc12f70c676e15c68ceb02a0997ee998fc9..b158bbbb3be01aeb66c49c0cc8c3df9643dc8ff6 100644
--- a/dynare++/sylv/cc/TriangularSylvester.h
+++ b/dynare++/sylv/cc/TriangularSylvester.hh
@@ -5,11 +5,11 @@
 #ifndef TRIANGULAR_SYLVESTER_H
 #define TRIANGULAR_SYLVESTER_H
 
-#include "SylvesterSolver.h"
-#include "KronVector.h"
-#include "QuasiTriangular.h"
-#include "QuasiTriangularZero.h"
-#include "SimilarityDecomp.h"
+#include "SylvesterSolver.hh"
+#include "KronVector.hh"
+#include "QuasiTriangular.hh"
+#include "QuasiTriangularZero.hh"
+#include "SimilarityDecomp.hh"
 
 class TriangularSylvester : public SylvesterSolver
 {
diff --git a/dynare++/sylv/cc/Vector.cc b/dynare++/sylv/cc/Vector.cc
new file mode 100644
index 0000000000000000000000000000000000000000..d0722c5dfa74c3fb220c3aafb71ce01784312860
--- /dev/null
+++ b/dynare++/sylv/cc/Vector.cc
@@ -0,0 +1,418 @@
+// Copyright (C) 2004-2011, Ondra Kamenik
+
+#include "Vector.hh"
+#include "GeneralMatrix.hh"
+#include "SylvException.hh"
+
+#include <dynblas.h>
+
+#include <cstdio>
+#include <cstring>
+#include <cstdlib>
+#include <cmath>
+#include <algorithm>
+#include <limits>
+
+using namespace std;
+
+ZeroPad zero_pad;
+
+Vector::Vector(const Vector &v)
+  : len(v.length()), s(1), data(new double[len]), destroy(true)
+{
+  copy(v.base(), v.skip());
+}
+
+Vector::Vector(const ConstVector &v)
+  : len(v.length()), s(1), data(new double[len]), destroy(true)
+{
+  copy(v.base(), v.skip());
+}
+
+const Vector &
+Vector::operator=(const Vector &v)
+{
+  if (this == &v)
+    return *this;
+
+  if (v.length() != length())
+    {
+      throw SYLV_MES_EXCEPTION("Attempt to assign vectors with different lengths.");
+    }
+  if (s == v.s
+      && (data <= v.data && v.data < data+len*s
+          || v.data <= data && data < v.data+v.len*v.s)
+      && (data-v.data) % s == 0)
+    {
+      printf("this destroy=%d, v destroy=%d, data-v.data=%lu, len=%d\n", destroy, v.destroy, (unsigned long) (data-v.data), len);
+      throw SYLV_MES_EXCEPTION("Attempt to assign overlapping vectors.");
+    }
+  copy(v.base(), v.skip());
+  return *this;
+}
+
+const Vector &
+Vector::operator=(const ConstVector &v)
+{
+  if (v.length() != length())
+    {
+      throw SYLV_MES_EXCEPTION("Attempt to assign vectors with different lengths.");
+    }
+  if (v.skip() == 1 && skip() == 1 && (
+                                       (base() < v.base() + v.length() && base() >= v.base())
+                                       || (base() + length() < v.base() + v.length()
+                                           && base() + length() > v.base())))
+    {
+      throw SYLV_MES_EXCEPTION("Attempt to assign overlapping vectors.");
+    }
+  copy(v.base(), v.skip());
+  return *this;
+}
+
+void
+Vector::copy(const double *d, int inc)
+{
+  blas_int n = length();
+  blas_int incy = skip();
+  blas_int inc2 = inc;
+  dcopy(&n, d, &inc2, base(), &incy);
+}
+
+Vector::Vector(Vector &v, int off, int l)
+  : len(l), s(v.skip()), data(v.base()+off*v.skip()), destroy(false)
+{
+  if (off < 0 || off + length() > v.length())
+    throw SYLV_MES_EXCEPTION("Subvector not contained in supvector.");
+}
+
+Vector::Vector(const Vector &v, int off, int l)
+  : len(l), s(1), data(new double[len]), destroy(true)
+{
+  if (off < 0 || off + length() > v.length())
+    throw SYLV_MES_EXCEPTION("Subvector not contained in supvector.");
+  copy(v.base()+off*v.skip(), v.skip());
+}
+
+Vector::Vector(GeneralMatrix &m, int col)
+  : len(m.numRows()), s(1), data(&(m.get(0, col))), destroy(false)
+{
+}
+
+Vector::Vector(int row, GeneralMatrix &m)
+  : len(m.numCols()), s(m.getLD()), data(&(m.get(row, 0))), destroy(false)
+{
+}
+
+bool
+Vector::operator==(const Vector &y) const
+{
+  return ConstVector(*this) == y;
+}
+
+bool
+Vector::operator!=(const Vector &y) const
+{
+  return ConstVector(*this) != y;
+}
+
+bool
+Vector::operator<(const Vector &y) const
+{
+  return ConstVector(*this) < y;
+}
+
+bool
+Vector::operator<=(const Vector &y) const
+{
+  return ConstVector(*this) <= y;
+}
+
+bool
+Vector::operator>(const Vector &y) const
+{
+  return ConstVector(*this) > y;
+}
+
+bool
+Vector::operator>=(const Vector &y) const
+{
+  return ConstVector(*this) >= y;
+}
+
+void
+Vector::zeros()
+{
+  if (skip() == 1)
+    {
+      double *p = base();
+      for (int i = 0; i < length()/ZeroPad::length;
+           i++, p += ZeroPad::length)
+        memcpy(p, zero_pad.getBase(), sizeof(double)*ZeroPad::length);
+      for (; p < base()+length(); p++)
+        *p = 0.0;
+    }
+  else
+    {
+      for (int i = 0; i < length(); i++)
+        operator[](i) = 0.0;
+    }
+}
+
+void
+Vector::nans()
+{
+  for (int i = 0; i < length(); i++)
+    operator[](i) = std::numeric_limits<double>::quiet_NaN();
+}
+
+void
+Vector::infs()
+{
+  for (int i = 0; i < length(); i++)
+    operator[](i) = std::numeric_limits<double>::infinity();
+}
+
+Vector::~Vector()
+{
+  if (destroy)
+    {
+      delete [] data;
+    }
+}
+
+void
+Vector::rotatePair(double alpha, double beta1, double beta2, int i)
+{
+  double tmp = alpha*operator[](i) - beta1*operator[](i+1);
+  operator[](i+1) = alpha*operator[](i+1) - beta2*operator[](i);
+  operator[](i) = tmp;
+}
+
+void
+Vector::add(double r, const Vector &v)
+{
+  add(r, ConstVector(v));
+}
+
+void
+Vector::add(double r, const ConstVector &v)
+{
+  blas_int n = length();
+  blas_int incx = v.skip();
+  blas_int incy = skip();
+  daxpy(&n, &r, v.base(), &incx, base(), &incy);
+}
+
+void
+Vector::add(const double *z, const Vector &v)
+{
+  add(z, ConstVector(v));
+}
+
+void
+Vector::add(const double *z, const ConstVector &v)
+{
+  blas_int n = length()/2;
+  blas_int incx = v.skip();
+  blas_int incy = skip();
+  zaxpy(&n, z, v.base(), &incx, base(), &incy);
+}
+
+void
+Vector::mult(double r)
+{
+  blas_int n = length();
+  blas_int incx = skip();
+  dscal(&n, &r, base(), &incx);
+}
+
+void
+Vector::mult2(double alpha, double beta1, double beta2,
+              Vector &x1, Vector &x2,
+              const Vector &b1, const Vector &b2)
+{
+  x1.zeros();
+  x2.zeros();
+  mult2a(alpha, beta1, beta2, x1, x2, b1, b2);
+}
+
+void
+Vector::mult2a(double alpha, double beta1, double beta2,
+               Vector &x1, Vector &x2,
+               const Vector &b1, const Vector &b2)
+{
+  x1.add(alpha, b1);
+  x1.add(-beta1, b2);
+  x2.add(alpha, b2);
+  x2.add(-beta2, b1);
+}
+
+double
+Vector::getNorm() const
+{
+  ConstVector v(*this);
+  return v.getNorm();
+}
+
+double
+Vector::getMax() const
+{
+  ConstVector v(*this);
+  return v.getMax();
+}
+
+double
+Vector::getNorm1() const
+{
+  ConstVector v(*this);
+  return v.getNorm1();
+}
+
+double
+Vector::dot(const Vector &y) const
+{
+  return ConstVector(*this).dot(ConstVector(y));
+}
+
+bool
+Vector::isFinite() const
+{
+  return (ConstVector(*this)).isFinite();
+}
+
+void
+Vector::print() const
+{
+  for (int i = 0; i < length(); i++)
+    {
+      printf("%d\t%8.4g\n", i, operator[](i));
+    }
+}
+
+ConstVector::ConstVector(const Vector &v, int off, int l)
+  : BaseConstVector(l, v.skip(), v.base() + v.skip()*off)
+{
+  if (off < 0 || off + length() > v.length())
+    {
+      throw SYLV_MES_EXCEPTION("Subvector not contained in supvector.");
+    }
+}
+
+ConstVector::ConstVector(const ConstVector &v, int off, int l)
+  : BaseConstVector(l, v.skip(), v.base() + v.skip()*off)
+{
+  if (off < 0 || off + length() > v.length())
+    {
+      throw SYLV_MES_EXCEPTION("Subvector not contained in supvector.");
+    }
+}
+
+ConstVector::ConstVector(const double *d, int skip, int l)
+  : BaseConstVector(l, skip, d)
+{
+}
+
+ConstVector::ConstVector(const ConstGeneralMatrix &m, int col)
+  : BaseConstVector(m.numRows(), 1, &(m.get(0, col)))
+{
+}
+
+ConstVector::ConstVector(int row, const ConstGeneralMatrix &m)
+  : BaseConstVector(m.numCols(), m.getLD(), &(m.get(row, 0)))
+{
+}
+
+bool
+ConstVector::operator==(const ConstVector &y) const
+{
+  if (length() != y.length())
+    return false;
+  if (length() == 0)
+    return true;
+  int i = 0;
+  while (i < length() && operator[](i) == y[i])
+    i++;
+  return i == length();
+}
+
+bool
+ConstVector::operator<(const ConstVector &y) const
+{
+  int i = std::min(length(), y.length());
+  int ii = 0;
+  while (ii < i && operator[](ii) == y[ii])
+    ii++;
+  if (ii < i)
+    return operator[](ii) < y[ii];
+  else
+    return length() < y.length();
+}
+
+double
+ConstVector::getNorm() const
+{
+  double s = 0;
+  for (int i = 0; i < length(); i++)
+    {
+      s += operator[](i)*operator[](i);
+    }
+  return sqrt(s);
+}
+
+double
+ConstVector::getMax() const
+{
+  double r = 0;
+  for (int i = 0; i < length(); i++)
+    {
+      if (abs(operator[](i)) > r)
+        r = abs(operator[](i));
+    }
+  return r;
+}
+
+double
+ConstVector::getNorm1() const
+{
+  double norm = 0.0;
+  for (int i = 0; i < length(); i++)
+    {
+      norm += abs(operator[](i));
+    }
+  return norm;
+}
+
+double
+ConstVector::dot(const ConstVector &y) const
+{
+  if (length() != y.length())
+    throw SYLV_MES_EXCEPTION("Vector has different length in ConstVector::dot.");
+  blas_int n = length();
+  blas_int incx = skip();
+  blas_int incy = y.skip();
+  return ddot(&n, base(), &incx, y.base(), &incy);
+}
+
+bool
+ConstVector::isFinite() const
+{
+  int i = 0;
+  while (i < length() && isfinite(operator[](i)))
+    i++;
+  return i == length();
+}
+
+void
+ConstVector::print() const
+{
+  for (int i = 0; i < length(); i++)
+    {
+      printf("%d\t%8.4g\n", i, operator[](i));
+    }
+}
+
+ZeroPad::ZeroPad()
+{
+  for (int i = 0; i < length; i++)
+    pad[i] = 0.0;
+}
diff --git a/dynare++/sylv/cc/Vector.cpp b/dynare++/sylv/cc/Vector.cpp
deleted file mode 100644
index 929790ad8c0c68cf07e71bf62cfc8f672f33cb49..0000000000000000000000000000000000000000
--- a/dynare++/sylv/cc/Vector.cpp
+++ /dev/null
@@ -1,371 +0,0 @@
-// Copyright (C) 2004-2011, Ondra Kamenik
-
-#include "Vector.h"
-#include "GeneralMatrix.h"
-#include "SylvException.h"
-
-#include <dynblas.h>
-
-#include <cstdio>
-#include <cstring>
-#include <cstdlib>
-#include <cmath>
-#include <algorithm>
-#include <limits>
-
-using namespace std;
-
-ZeroPad zero_pad;
-
-Vector::Vector(const Vector& v)
-	: len(v.length()), s(1), data(new double[len]), destroy(true)
-{
-	copy(v.base(), v.skip());
-}
-
-Vector::Vector(const ConstVector& v)
-	: len(v.length()), s(1), data(new double[len]), destroy(true)
-{
-	copy(v.base(), v.skip());
-}
-
-const Vector& Vector::operator=(const Vector& v)
-{
-	if (this == &v)
-		return *this;
-
-	if (v.length() != length()) {
-		throw SYLV_MES_EXCEPTION("Attempt to assign vectors with different lengths.");
-	}
-	if (s == v.s &&
-		(data <= v.data && v.data < data+len*s ||
-		 v.data <= data && data < v.data+v.len*v.s) &&
-		(data-v.data) % s == 0) {
-		printf("this destroy=%d, v destroy=%d, data-v.data=%lu, len=%d\n", destroy, v.destroy, (unsigned long) (data-v.data), len);
-		throw SYLV_MES_EXCEPTION("Attempt to assign overlapping vectors.");
-	}
-	copy(v.base(), v.skip());
-	return *this;
-}
-
-const Vector& Vector::operator=(const ConstVector& v)
-{
-	if (v.length() != length()) {
-		throw SYLV_MES_EXCEPTION("Attempt to assign vectors with different lengths.");
-	}
-	if (v.skip() == 1 && skip() == 1 && (
-			(base() < v.base() + v.length() && base() >= v.base()) ||
-			(base() + length() < v.base() + v.length() &&
-			 base() + length() > v.base()))) {
-		throw SYLV_MES_EXCEPTION("Attempt to assign overlapping vectors.");
-	}
-	copy(v.base(), v.skip());
-	return *this;
-}
-
-void Vector::copy(const double* d, int inc)
-{
-	blas_int n = length();
-	blas_int incy = skip();
-	blas_int inc2 = inc;
-	dcopy(&n, d, &inc2, base(), &incy);
-}
-
-Vector::Vector(Vector& v, int off, int l)
-	: len(l), s(v.skip()), data(v.base()+off*v.skip()), destroy(false)
-{
-	if (off < 0 || off + length() > v.length())
-		throw SYLV_MES_EXCEPTION("Subvector not contained in supvector.");
-}
-
-Vector::Vector(const Vector& v, int off, int l)
-	: len(l), s(1), data(new double[len]), destroy(true)
-{
-	if (off < 0 || off + length() > v.length())
-		throw SYLV_MES_EXCEPTION("Subvector not contained in supvector.");
-	copy(v.base()+off*v.skip(), v.skip());
-}
-
-Vector::Vector(GeneralMatrix& m, int col)
-	: len(m.numRows()), s(1), data(&(m.get(0, col))), destroy(false)
-{
-}
-
-Vector::Vector(int row, GeneralMatrix& m)
-	: len(m.numCols()), s(m.getLD()), data(&(m.get(row, 0))), destroy(false)
-{
-}
-
-bool Vector::operator==(const Vector& y) const
-{
-	return ConstVector(*this) == y;
-}
-
-bool Vector::operator!=(const Vector& y) const
-{
-	return ConstVector(*this) != y;
-}
-
-bool Vector::operator<(const Vector& y) const
-{
-	return ConstVector(*this) < y;
-}
-
-bool Vector::operator<=(const Vector& y) const
-{
-	return ConstVector(*this) <= y;
-}
-
-bool Vector::operator>(const Vector& y) const
-{
-	return ConstVector(*this) > y;
-}
-
-bool Vector::operator>=(const Vector& y) const
-{
-	return ConstVector(*this) >= y;
-}
-
-void Vector::zeros()
-{
-	if (skip() == 1) {
-		double* p = base();
-		for (int i = 0; i < length()/ZeroPad::length;
-			 i++, p += ZeroPad::length)
-			memcpy(p, zero_pad.getBase(), sizeof(double)*ZeroPad::length);
-		for ( ; p < base()+length(); p++)
-			*p = 0.0;
-	} else {
-		for (int i = 0; i < length(); i++)
-			operator[](i) = 0.0;
-	}
-}
-
-void Vector::nans()
-{
-	for (int i = 0; i < length(); i++)
-		operator[](i) = std::numeric_limits<double>::quiet_NaN();
-}
-
-void Vector::infs()
-{
-	for (int i = 0; i < length(); i++)
-		operator[](i) = std::numeric_limits<double>::infinity();
-}
-
-Vector::~Vector()
-{
-	if (destroy) {
-		delete [] data;
-	}
-}
-
-void Vector::rotatePair(double alpha, double beta1, double beta2, int i)
-{
-	double tmp = alpha*operator[](i) - beta1*operator[](i+1);
-	operator[](i+1) = alpha*operator[](i+1) - beta2*operator[](i);
-	operator[](i) = tmp;
-}
-
-void Vector::add(double r, const Vector& v)
-{
-	add(r, ConstVector(v));
-}
-
-void Vector::add(double r, const ConstVector& v)
-{
-	blas_int n = length();
-	blas_int incx = v.skip();
-	blas_int incy = skip();
-	daxpy(&n, &r, v.base(), &incx, base(), &incy);
-}
-
-void Vector::add(const double* z, const Vector& v)
-{
-	add(z, ConstVector(v));
-}
-
-void Vector::add(const double* z, const ConstVector& v)
-{
-	blas_int n = length()/2;
-	blas_int incx = v.skip();
-	blas_int incy = skip();
-	zaxpy(&n, z, v.base(), &incx, base(), &incy);
-}
-
-void Vector::mult(double r)
-{
-	blas_int n = length();
-	blas_int incx = skip();
-	dscal(&n, &r, base(), &incx);
-}
-
-void Vector::mult2(double alpha, double beta1, double beta2,
-				   Vector& x1, Vector& x2,
-				   const Vector& b1, const Vector& b2)
-{
-	x1.zeros();
-	x2.zeros();
-	mult2a(alpha, beta1, beta2, x1, x2, b1, b2);
-}
-
-void Vector::mult2a(double alpha, double beta1, double beta2,
-					Vector& x1, Vector& x2,
-					const Vector& b1, const Vector& b2)
-{
-	x1.add(alpha, b1);
-	x1.add(-beta1, b2);
-	x2.add(alpha, b2);
-	x2.add(-beta2, b1);
-}
-
-double Vector::getNorm() const
-{
-	ConstVector v(*this);
-	return v.getNorm();
-}
-
-double Vector::getMax() const
-{
-	ConstVector v(*this);
-	return v.getMax();
-}
-
-double Vector::getNorm1() const
-{
-	ConstVector v(*this);
-	return v.getNorm1();
-}
-
-double Vector::dot(const Vector& y) const
-{
-	return ConstVector(*this).dot(ConstVector(y));
-}
-
-bool Vector::isFinite() const
-{
-	return (ConstVector(*this)).isFinite();
-}
-
-void Vector::print() const
-{
-	for (int i = 0; i < length(); i++) {
-		printf("%d\t%8.4g\n", i, operator[](i));
-	}
-}
-
-
-ConstVector::ConstVector(const Vector& v, int off, int l) 
-	: BaseConstVector(l, v.skip(), v.base() + v.skip()*off)
-{
-	if (off < 0 || off + length() > v.length()) {
-		throw SYLV_MES_EXCEPTION("Subvector not contained in supvector.");
-	}
-}
-
-ConstVector::ConstVector(const ConstVector& v, int off, int l) 
-	: BaseConstVector(l, v.skip(), v.base() + v.skip()*off)
-{
-	if (off < 0 || off + length() > v.length()) {
-		throw SYLV_MES_EXCEPTION("Subvector not contained in supvector.");
-	}
-}
-
-ConstVector::ConstVector(const double* d, int skip, int l)
-	: BaseConstVector(l, skip, d)
-{
-}
-
-ConstVector::ConstVector(const ConstGeneralMatrix& m, int col)
-	: BaseConstVector(m.numRows(), 1, &(m.get(0, col)))
-{
-}
-
-ConstVector::ConstVector(int row, const ConstGeneralMatrix& m)
-	: BaseConstVector(m.numCols(), m.getLD(), &(m.get(row, 0)))
-{
-}
-
-bool ConstVector::operator==(const ConstVector& y) const
-{
-	if (length() != y.length())
-		return false;
-	if (length() == 0)
-		return true;
-	int i = 0;
-	while (i < length() && operator[](i) == y[i])
-		i++;
-	return i == length();
-}
-
-bool ConstVector::operator<(const ConstVector& y) const
-{
-	int i = std::min(length(), y.length());
-	int ii = 0;
-	while (ii < i && operator[](ii) == y[ii])
-		ii++;
-	if (ii < i)
-		return operator[](ii) < y[ii];
-	else
-		return length() < y.length();
-}
-
-double ConstVector::getNorm() const
-{
-	double s = 0;
-	for (int i = 0; i < length(); i++) {
-		s+=operator[](i)*operator[](i);
-	}
-	return sqrt(s);
-}
-
-double ConstVector::getMax() const
-{
-	double r = 0;
-	for (int i = 0; i < length(); i++) {
-		if (abs(operator[](i))>r)
-			r = abs(operator[](i));
-	}
-	return r;
-}
-
-double ConstVector::getNorm1() const
-{
-	double norm = 0.0;
-	for (int i = 0; i < length(); i++) {
-		norm += abs(operator[](i));
-	}
-	return norm;
-}
-
-double ConstVector::dot(const ConstVector& y) const
-{
-	if (length() != y.length())
-		throw SYLV_MES_EXCEPTION("Vector has different length in ConstVector::dot.");
-	blas_int n = length();
-	blas_int incx = skip();
-	blas_int incy = y.skip();
-	return ddot(&n, base(), &incx, y.base(), &incy);
-}
-
-bool ConstVector::isFinite() const
-{
-	int i = 0;
-	while (i < length() && isfinite(operator[](i)))
-		i++;
-	return i == length();
-}
-
-void ConstVector::print() const
-{
-	for (int i = 0; i < length(); i++) {
-		printf("%d\t%8.4g\n", i, operator[](i));
-	}
-}
-
-
-ZeroPad::ZeroPad()
-{
-	for (int i = 0; i < length; i++)
-		pad[i] = 0.0;
-}
diff --git a/dynare++/sylv/cc/Vector.h b/dynare++/sylv/cc/Vector.hh
similarity index 100%
rename from dynare++/sylv/cc/Vector.h
rename to dynare++/sylv/cc/Vector.hh
diff --git a/dynare++/sylv/matlab/gensylv.cc b/dynare++/sylv/matlab/gensylv.cc
new file mode 100644
index 0000000000000000000000000000000000000000..14bebce58229351a5629a7c5aaf6f5f2ab0c5daa
--- /dev/null
+++ b/dynare++/sylv/matlab/gensylv.cc
@@ -0,0 +1,94 @@
+// Copyright (C) 2005-2011, Ondra Kamenik
+
+#include "dynmex.h"
+#include "mex.h"
+
+#include "GeneralSylvester.hh"
+#include "SylvException.hh"
+
+void
+gen_sylv_solve(int order, int n, int m, int zero_cols,
+               const double *A, const double *B,
+               const double *C, double *X)
+{
+  GeneralSylvester s(order, n, m, zero_cols, A, B, C, X, false);
+  s.solve();
+}
+
+void
+gen_sylv_solve_and_check(int order, int n, int m, int zero_cols,
+                         const double *A, const double *B,
+                         const double *C, const double *D,
+                         double *X, mxArray * &p)
+{
+  GeneralSylvester s(order, n, m, zero_cols, A, B, C, X, true);
+  s.solve();
+  s.check(D);
+  p = s.getParams().createStructArray();
+}
+
+extern "C" {
+  void
+  mexFunction(int nlhs, mxArray *plhs[],
+              int nhrs, const mxArray *prhs[])
+  {
+    if (nhrs != 5 || nlhs > 3 || nlhs < 2)
+      DYN_MEX_FUNC_ERR_MSG_TXT("Gensylv: Must have exactly 5 input args and either 2 or 3 output args.");
+
+    int order = (int) mxGetScalar(prhs[0]);
+    const mxArray *const A = prhs[1];
+    const mxArray *const B = prhs[2];
+    const mxArray *const C = prhs[3];
+    const mxArray *const D = prhs[4];
+    const mwSize *const Adims = mxGetDimensions(A);
+    const mwSize *const Bdims = mxGetDimensions(B);
+    const mwSize *const Cdims = mxGetDimensions(C);
+    const mwSize *const Ddims = mxGetDimensions(D);
+
+    if (Adims[0] != Adims[1])
+      DYN_MEX_FUNC_ERR_MSG_TXT("Matrix A must be a square matrix.");
+    if (Adims[0] != Bdims[0])
+      DYN_MEX_FUNC_ERR_MSG_TXT("Matrix A and matrix B must have the same number of rows.");
+    if (Adims[0] != Ddims[0])
+      DYN_MEX_FUNC_ERR_MSG_TXT("Matrix A and matrix B must have the same number of rows.");
+    if (Cdims[0] != Cdims[1])
+      DYN_MEX_FUNC_ERR_MSG_TXT("Matrix C must be square.");
+    if (Bdims[0] < Bdims[1])
+      DYN_MEX_FUNC_ERR_MSG_TXT("Matrix B must not have more columns than rows.");
+    if (Ddims[1] != (mwSize) power(Cdims[0], order))
+      DYN_MEX_FUNC_ERR_MSG_TXT("Matrix D has wrong number of columns.");
+
+    int n = Adims[0];
+    int m = Cdims[0];
+    int zero_cols = Bdims[0] - Bdims[1];
+    mxArray *X = mxCreateDoubleMatrix(Ddims[0], Ddims[1], mxREAL);
+    // copy D to X
+    Vector Xvec((double *)mxGetPr(X), power(m, order)*n);
+    ConstVector Dvec((double *)mxGetPr(D), power(m, order)*n);
+    Xvec = Dvec;
+    // solve (or solve and check)
+    try
+      {
+        if (nlhs == 2)
+          {
+            gen_sylv_solve(order, n, m, zero_cols,
+                           mxGetPr(A), mxGetPr(B), mxGetPr(C),
+                           mxGetPr(X));
+          }
+        else if (nlhs == 3)
+          {
+            gen_sylv_solve_and_check(order, n, m, zero_cols,
+                                     mxGetPr(A), mxGetPr(B), mxGetPr(C),
+                                     mxGetPr(D), mxGetPr(X), plhs[2]);
+          }
+      }
+    catch (const SylvException &e)
+      {
+        char mes[1000];
+        e.printMessage(mes, 999);
+        DYN_MEX_FUNC_ERR_MSG_TXT(mes);
+      }
+    plhs[1] = X;
+    plhs[0] = mxCreateDoubleScalar(0);
+  }
+};
diff --git a/dynare++/sylv/matlab/gensylv.cpp b/dynare++/sylv/matlab/gensylv.cpp
deleted file mode 100644
index b619afda836bbc16047b0ae221be0530e5589952..0000000000000000000000000000000000000000
--- a/dynare++/sylv/matlab/gensylv.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright (C) 2005-2011, Ondra Kamenik
-
-#include "dynmex.h"
-#include "mex.h"
-
-#include "GeneralSylvester.h"
-#include "SylvException.h"
-
-
-void gen_sylv_solve(int order, int n, int m, int zero_cols,
-					const double* A, const double* B,
-					const double* C, double* X)
-{
-		GeneralSylvester s(order, n, m, zero_cols, A, B, C, X, false);
-		s.solve();
-}
-
-void gen_sylv_solve_and_check(int order, int n, int m, int zero_cols,
-							  const double* A, const double* B,
-							  const double* C, const double* D,
-							  double* X, mxArray*& p)
-{
-		GeneralSylvester s(order, n, m, zero_cols, A, B, C, X, true);
-		s.solve();
-		s.check(D);
-		p = s.getParams().createStructArray();
-}
-
-extern "C" {
-	void mexFunction(int nlhs, mxArray* plhs[],
-					 int nhrs, const mxArray* prhs[])
-	{
-		if (nhrs != 5 || nlhs > 3 || nlhs < 2 )
-                  DYN_MEX_FUNC_ERR_MSG_TXT("Gensylv: Must have exactly 5 input args and either 2 or 3 output args.");
-
-		int order = (int)mxGetScalar(prhs[0]);
-		const mxArray* const A = prhs[1];
-		const mxArray* const B = prhs[2];
-		const mxArray* const C = prhs[3];
-		const mxArray* const D = prhs[4];
-		const mwSize* const Adims = mxGetDimensions(A);
-		const mwSize* const Bdims = mxGetDimensions(B);
-		const mwSize* const Cdims = mxGetDimensions(C);
-		const mwSize* const Ddims = mxGetDimensions(D);
-
-                if (Adims[0] != Adims[1])
-                  DYN_MEX_FUNC_ERR_MSG_TXT("Matrix A must be a square matrix.");
-                if (Adims[0] != Bdims[0])
-                  DYN_MEX_FUNC_ERR_MSG_TXT("Matrix A and matrix B must have the same number of rows.");
-                if (Adims[0] != Ddims[0])
-                  DYN_MEX_FUNC_ERR_MSG_TXT("Matrix A and matrix B must have the same number of rows.");
-                if (Cdims[0] != Cdims[1])
-                  DYN_MEX_FUNC_ERR_MSG_TXT("Matrix C must be square.");
-                if (Bdims[0] < Bdims[1])
-                  DYN_MEX_FUNC_ERR_MSG_TXT("Matrix B must not have more columns than rows.");
-                if (Ddims[1] != (mwSize) power(Cdims[0], order))
-                  DYN_MEX_FUNC_ERR_MSG_TXT("Matrix D has wrong number of columns.");
-
-		int n = Adims[0];
-		int m = Cdims[0];
-		int zero_cols = Bdims[0] - Bdims[1];
-		mxArray* X = mxCreateDoubleMatrix(Ddims[0], Ddims[1], mxREAL);
-		// copy D to X
-		Vector Xvec((double*)mxGetPr(X), power(m, order)*n);
-		ConstVector Dvec((double*)mxGetPr(D), power(m, order)*n);
-		Xvec = Dvec;
-		// solve (or solve and check)
-                try
-                  {
-                    if (nlhs == 2) {
-                      gen_sylv_solve(order, n, m, zero_cols,
-						   mxGetPr(A), mxGetPr(B), mxGetPr(C),
-						   mxGetPr(X));
-                    } else if (nlhs == 3) {
-                      gen_sylv_solve_and_check(order, n, m, zero_cols,
-									 mxGetPr(A), mxGetPr(B), mxGetPr(C),
-									 mxGetPr(D), mxGetPr(X), plhs[2]);
-                    }
-                  }
-                catch (const SylvException& e)
-                  {
-                    char mes[1000];
-                    e.printMessage(mes, 999);
-                    DYN_MEX_FUNC_ERR_MSG_TXT(mes);
-                  }
-                plhs[1] = X;
-                plhs[0] = mxCreateDoubleScalar(0);
-	}
-};
diff --git a/dynare++/sylv/testing/MMMatrix.cc b/dynare++/sylv/testing/MMMatrix.cc
new file mode 100644
index 0000000000000000000000000000000000000000..099eb3a5a5ff5a94cf7f6df0b103a816d498eafc
--- /dev/null
+++ b/dynare++/sylv/testing/MMMatrix.cc
@@ -0,0 +1,78 @@
+/* $Header: /var/lib/cvs/dynare_cpp/sylv/testing/MMMatrix.cpp,v 1.1.1.1 2004/06/04 13:01:13 kamenik Exp $ */
+
+/* Tag $Name:  $ */
+
+#include "MMMatrix.hh"
+
+#include <cstdio>
+#include <cstring>
+
+MMMatrixIn::MMMatrixIn(const char *fname)
+{
+  FILE *fd;
+  if (NULL == (fd = fopen(fname, "r")))
+    throw MMException(string("Cannot open file ")+fname+" for reading\n");
+
+  char buffer[1000];
+  // jump over initial comments
+  while (fgets(buffer, 1000, fd) && strncmp(buffer, "%%", 2))
+    {
+    }
+  // read in number of rows and cols
+  if (!fgets(buffer, 1000, fd))
+    throw MMException(string("Cannot read rows and cols while reading ")+fname+"\n");
+  if (2 != sscanf(buffer, "%d %d", &rows, &cols))
+    throw MMException("Couldn't parse rows and cols\n");
+  // read in data
+  data = (double *) operator new[](rows*cols*sizeof(double));
+  int len = rows*cols;
+  int i = 0;
+  while (fgets(buffer, 1000, fd) && i < len)
+    {
+      if (1 != sscanf(buffer, "%lf", &data[i]))
+        throw MMException(string("Couldn't parse float number ")+buffer+"\n");
+      i++;
+    }
+  if (i < len)
+    {
+      char mes[1000];
+      sprintf(mes, "Couldn't read all %d lines, read %d so far\n", len, i);
+      throw MMException(mes);
+    }
+  fclose(fd);
+}
+
+MMMatrixIn::~MMMatrixIn()
+{
+  operator delete [](data);
+}
+
+void
+MMMatrixOut::write(const char *fname, int rows, int cols, const double *data)
+{
+  FILE *fd;
+  if (NULL == (fd = fopen(fname, "w")))
+    throw MMException(string("Cannot open file ")+fname+" for writing\n");
+
+  if (0 > fprintf(fd, "%%%%MatrixMarket matrix array real general\n"))
+    throw MMException(string("Output error when writing file ")+fname);
+  if (0 > fprintf(fd, "%d %d\n", rows, cols))
+    throw MMException(string("Output error when writing file ")+fname);
+  int running = 0;
+  for (int i = 0; i < cols; i++)
+    {
+      for (int j = 0; j < rows; j++)
+        {
+          if (0 > fprintf(fd, "%40.35g\n", data[running]))
+            throw MMException(string("Output error when writing file ")+fname);
+          running++;
+        }
+    }
+  fclose(fd);
+}
+
+void
+MMMatrixOut::write(const char *fname, const GeneralMatrix &m)
+{
+  write(fname, m.numRows(), m.numCols(), m.base());
+}
diff --git a/dynare++/sylv/testing/MMMatrix.cpp b/dynare++/sylv/testing/MMMatrix.cpp
deleted file mode 100644
index 9a503caab5ad2af6b8ead119521a8ec5970887c8..0000000000000000000000000000000000000000
--- a/dynare++/sylv/testing/MMMatrix.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/* $Header: /var/lib/cvs/dynare_cpp/sylv/testing/MMMatrix.cpp,v 1.1.1.1 2004/06/04 13:01:13 kamenik Exp $ */
-
-/* Tag $Name:  $ */
-
-#include "MMMatrix.h"
-
-#include <cstdio>
-#include <cstring>
-
-MMMatrixIn::MMMatrixIn(const char* fname)
-{
-	FILE* fd;
-	if (NULL==(fd = fopen(fname,"r")))
-		throw MMException(string("Cannot open file ")+fname+" for reading\n");
-
-	char buffer[1000];
-	// jump over initial comments
-	while (fgets(buffer, 1000, fd) && strncmp(buffer, "%%", 2)) {}
-	// read in number of rows and cols
-	if (!fgets(buffer, 1000, fd))
-		throw MMException(string("Cannot read rows and cols while reading ")+fname+"\n");
-	if (2 != sscanf(buffer, "%d %d", &rows, &cols))
-		throw MMException("Couldn't parse rows and cols\n");
-	// read in data
-	data = (double*) operator new[](rows*cols*sizeof(double));
-	int len = rows*cols;
-	int i = 0;
-	while (fgets(buffer, 1000, fd) && i < len) {
-		if (1 != sscanf(buffer, "%lf", &data[i]))
-			throw MMException(string("Couldn't parse float number ")+buffer+"\n");
-		i++;
-	}
-	if (i < len) {
-		char mes[1000];
-		sprintf(mes,"Couldn't read all %d lines, read %d so far\n",len,i);
-		throw MMException(mes);
-	}
-	fclose(fd);
-}
-
-MMMatrixIn::~MMMatrixIn()
-{
-	operator delete [](data);
-}
-
-
-void MMMatrixOut::write(const char* fname, int rows, int cols, const double* data)
-{
-	FILE* fd;
-	if (NULL==(fd = fopen(fname,"w")))
-		throw MMException(string("Cannot open file ")+fname+" for writing\n");
-
-	if (0 > fprintf(fd, "%%%%MatrixMarket matrix array real general\n"))
-		throw MMException(string("Output error when writing file ")+fname);
-	if (0 > fprintf(fd, "%d %d\n", rows, cols))
-		throw MMException(string("Output error when writing file ")+fname);
-	int running = 0;
-	for (int i = 0; i < cols; i++) {
-		for (int j = 0 ; j < rows; j++) {
-			if (0 > fprintf(fd, "%40.35g\n", data[running]))
-				throw MMException(string("Output error when writing file ")+fname);
-			running++;
-		}
-	}
-	fclose(fd);
-}
-
-void MMMatrixOut::write(const char* fname, const GeneralMatrix& m)
-{
-	write(fname, m.numRows(), m.numCols(), m.base());
-}
diff --git a/dynare++/sylv/testing/MMMatrix.h b/dynare++/sylv/testing/MMMatrix.hh
similarity index 95%
rename from dynare++/sylv/testing/MMMatrix.h
rename to dynare++/sylv/testing/MMMatrix.hh
index f6afaa30dc2183d32908ea176cf786a8d6d341d8..3cd043804a2a479ce343fec0896430fd76e5402f 100644
--- a/dynare++/sylv/testing/MMMatrix.h
+++ b/dynare++/sylv/testing/MMMatrix.hh
@@ -5,8 +5,8 @@
 #ifndef MM_MATRIX_H
 #define MM_MATRIX_H
 
-#include "GeneralMatrix.h"
-#include "SylvMemory.h"
+#include "GeneralMatrix.hh"
+#include "SylvMemory.hh"
 
 #include <string>
 
diff --git a/dynare++/sylv/testing/Makefile.am b/dynare++/sylv/testing/Makefile.am
index d62d0ef025f3db6fbaff987e16325f6b2790d2a0..d5b54de82e2344b27e989cebf4439dfcdd44c7f9 100644
--- a/dynare++/sylv/testing/Makefile.am
+++ b/dynare++/sylv/testing/Makefile.am
@@ -1,6 +1,6 @@
 check_PROGRAMS = tests
 
-tests_SOURCES = MMMatrix.cpp MMMatrix.h tests.cpp
+tests_SOURCES = MMMatrix.cc MMMatrix.hh tests.cc
 tests_LDADD = ../cc/libsylv.a $(LAPACK_LIBS) $(BLAS_LIBS) $(LIBS) $(FLIBS)
 tests_CPPFLAGS = -I../cc
 
diff --git a/dynare++/sylv/testing/tests.cc b/dynare++/sylv/testing/tests.cc
new file mode 100644
index 0000000000000000000000000000000000000000..ba90ac175ae4c1b07b9cafc05b1255832d8215b7
--- /dev/null
+++ b/dynare++/sylv/testing/tests.cc
@@ -0,0 +1,1226 @@
+/* $Header: /var/lib/cvs/dynare_cpp/sylv/testing/tests.cpp,v 1.2 2004/07/05 19:55:48 kamenik Exp $ */
+
+/* Tag $Name:  $ */
+
+#include "SylvException.hh"
+#include "QuasiTriangular.hh"
+#include "QuasiTriangularZero.hh"
+#include "Vector.hh"
+#include "KronVector.hh"
+#include "KronUtils.hh"
+#include "TriangularSylvester.hh"
+#include "GeneralSylvester.hh"
+#include "SylvMemory.hh"
+#include "SchurDecompEig.hh"
+#include "SimilarityDecomp.hh"
+#include "IterativeSylvester.hh"
+#include "SylvMatrix.hh"
+
+#include "MMMatrix.hh"
+
+#include <cstdio>
+#include <cstring>
+#include <ctime>
+
+#include <cmath>
+
+class TestRunnable : public MallocAllocator
+{
+  char name[100];
+  static double eps_norm;
+public:
+  TestRunnable(const char *n)
+  {
+    strncpy(name, n, 100);
+  }
+  bool test() const;
+  virtual bool run() const = 0;
+  const char *
+  getName() const
+  {
+    return name;
+  }
+protected:
+  // declaration of auxiliary static methods
+  static bool quasi_solve(bool trans, const char *mname, const char *vname);
+  static bool mult_kron(bool trans, const char *mname, const char *vname,
+                        const char *cname, int m, int n, int depth);
+  static bool level_kron(bool trans, const char *mname, const char *vname,
+                         const char *cname, int level, int m, int n, int depth);
+  static bool kron_power(const char *m1name, const char *m2name, const char *vname,
+                         const char *cname, int m, int n, int depth);
+  static bool lin_eval(const char *m1name, const char *m2name, const char *vname,
+                       const char *cname, int m, int n, int depth,
+                       double alpha, double beta1, double beta2);
+  static bool qua_eval(const char *m1name, const char *m2name, const char *vname,
+                       const char *cname, int m, int n, int depth,
+                       double alpha, double betas, double gamma,
+                       double delta1, double delta2);
+  static bool tri_sylv(const char *m1name, const char *m2name, const char *vname,
+                       int m, int n, int depth);
+  static bool gen_sylv(const char *aname, const char *bname, const char *cname,
+                       const char *dname, int m, int n, int order);
+  static bool eig_bubble(const char *aname, int from, int to);
+  static bool block_diag(const char *aname, double log10norm = 3.0);
+  static bool iter_sylv(const char *m1name, const char *m2name, const char *vname,
+                        int m, int n, int depth);
+};
+
+double TestRunnable::eps_norm = 1.0e-10;
+
+bool
+TestRunnable::test() const
+{
+  printf("Running test <%s>\n", name);
+  clock_t start = clock();
+  bool passed = run();
+  clock_t end = clock();
+  printf("CPU time %8.4g (CPU seconds)..................",
+         ((double) (end-start))/CLOCKS_PER_SEC);
+  if (passed)
+    {
+      printf("passed\n\n");
+      return passed;
+    }
+  else
+    {
+      printf("FAILED\n\n");
+      return passed;
+    }
+}
+
+/**********************************************************/
+/*   auxiliary methods                                    */
+/**********************************************************/
+
+bool
+TestRunnable::quasi_solve(bool trans, const char *mname, const char *vname)
+{
+  MMMatrixIn mmt(mname);
+  MMMatrixIn mmv(vname);
+
+  SylvMemoryDriver memdriver(1, mmt.row(), mmt.row(), 1);
+  QuasiTriangular *t;
+  QuasiTriangular *tsave;
+  if (mmt.row() == mmt.col())
+    {
+      t = new QuasiTriangular(mmt.getData(), mmt.row());
+      tsave = new QuasiTriangular(*t);
+    }
+  else if (mmt.row() > mmt.col())
+    {
+      t = new QuasiTriangularZero(mmt.row()-mmt.col(), mmt.getData(), mmt.col());
+      tsave = new QuasiTriangularZero((const QuasiTriangularZero &) *t);
+    }
+  else
+    {
+      printf("  Wrong quasi triangular dimensions, rows must be >= cols.\n");
+      return false;
+    }
+  ConstVector v(mmv.getData(), mmv.row());
+  Vector x(v.length());
+  double eig_min = 1.0e20;
+  if (trans)
+    t->solveTrans(x, v, eig_min);
+  else
+    t->solve(x, v, eig_min);
+  printf("eig_min = %8.4g\n", eig_min);
+  Vector xx(v.length());
+  if (trans)
+    tsave->multVecTrans(xx, ConstVector(x));
+  else
+    tsave->multVec(xx, ConstVector(x));
+  delete tsave;
+  delete t;
+  xx.add(-1.0, v);
+  xx.add(1.0, x);
+  double norm = xx.getNorm();
+  printf("\terror norm = %8.4g\n", norm);
+  return (norm < eps_norm);
+}
+
+bool
+TestRunnable::mult_kron(bool trans, const char *mname, const char *vname,
+                        const char *cname, int m, int n, int depth)
+{
+  MMMatrixIn mmt(mname);
+  MMMatrixIn mmv(vname);
+  MMMatrixIn mmc(cname);
+
+  int length = power(m, depth)*n;
+  if (mmt.row() != m
+      || mmv.row() != length
+      || mmc.row() != length)
+    {
+      printf("  Incompatible sizes for krom mult action, len=%d, matrow=%d, m=%d, vrow=%d, crow=%d \n", length, mmt.row(), m, mmv.row(), mmc.row());
+      return false;
+    }
+
+  SylvMemoryDriver memdriver(1, m, n, depth);
+  QuasiTriangular t(mmt.getData(), mmt.row());
+  Vector vraw(mmv.getData(), mmv.row());
+  KronVector v(vraw, m, n, depth);
+  Vector craw(mmc.getData(), mmc.row());
+  KronVector c(craw, m, n, depth);
+  if (trans)
+    t.multKronTrans(v);
+  else
+    t.multKron(v);
+  c.add(-1.0, v);
+  double norm = c.getNorm();
+  printf("\terror norm = %8.4g\n", norm);
+  return (norm < eps_norm);
+}
+
+bool
+TestRunnable::level_kron(bool trans, const char *mname, const char *vname,
+                         const char *cname, int level, int m, int n, int depth)
+{
+  MMMatrixIn mmt(mname);
+  MMMatrixIn mmv(vname);
+  MMMatrixIn mmc(cname);
+
+  int length = power(m, depth)*n;
+  if (level > 0 && mmt.row() != m
+      || level == 0 && mmt.row() != n
+      || mmv.row() != length
+      || mmc.row() != length)
+    {
+      printf("  Incompatible sizes for krom mult action, len=%d, matrow=%d, m=%d, n=%d, vrow=%d, crow=%d \n", length, mmt.row(), m, n, mmv.row(), mmc.row());
+      return false;
+    }
+
+  SylvMemoryDriver memdriver(1, m, n, depth);
+  QuasiTriangular t(mmt.getData(), mmt.row());
+  Vector vraw(mmv.getData(), mmv.row());
+  ConstKronVector v(vraw, m, n, depth);
+  Vector craw(mmc.getData(), mmc.row());
+  KronVector c(craw, m, n, depth);
+  KronVector x(v);
+  if (trans)
+    KronUtils::multAtLevelTrans(level, t, x);
+  else
+    KronUtils::multAtLevel(level, t, x);
+  x.add(-1, c);
+  double norm = x.getNorm();
+  printf("\terror norm = %8.4g\n", norm);
+  return (norm < eps_norm);
+}
+
+bool
+TestRunnable::kron_power(const char *m1name, const char *m2name, const char *vname,
+                         const char *cname, int m, int n, int depth)
+{
+  MMMatrixIn mmt1(m1name);
+  MMMatrixIn mmt2(m2name);
+  MMMatrixIn mmv(vname);
+  MMMatrixIn mmc(cname);
+
+  int length = power(m, depth)*n;
+  if (mmt1.row() != m
+      || mmt2.row() != n
+      || mmv.row() != length
+      || mmc.row() != length)
+    {
+      printf("  Incompatible sizes for krom power mult action, len=%d, row1=%d, row2=%d, m=%d, n=%d, vrow=%d, crow=%d \n", length, mmt1.row(), mmt2.row(), m, n, mmv.row(), mmc.row());
+      return false;
+    }
+
+  SylvMemoryDriver memdriver(2, m, n, depth);
+  QuasiTriangular t1(mmt1.getData(), mmt1.row());
+  QuasiTriangular t2(mmt2.getData(), mmt2.row());
+  Vector vraw(mmv.getData(), mmv.row());
+  ConstKronVector v(vraw, m, n, depth);
+  Vector craw(mmc.getData(), mmc.row());
+  KronVector c(craw, m, n, depth);
+  KronVector x(v);
+  memdriver.setStackMode(true);
+  KronUtils::multKron(t1, t2, x);
+  memdriver.setStackMode(false);
+  x.add(-1, c);
+  double norm = x.getNorm();
+  printf("\terror norm = %8.4g\n", norm);
+  return (norm < eps_norm);
+}
+
+bool
+TestRunnable::lin_eval(const char *m1name, const char *m2name, const char *vname,
+                       const char *cname, int m, int n, int depth,
+                       double alpha, double beta1, double beta2)
+{
+  MMMatrixIn mmt1(m1name);
+  MMMatrixIn mmt2(m2name);
+  MMMatrixIn mmv(vname);
+  MMMatrixIn mmc(cname);
+
+  int length = power(m, depth)*n;
+  if (mmt1.row() != m
+      || mmt2.row() != n
+      || mmv.row() != 2*length
+      || mmc.row() != 2*length)
+    {
+      printf("  Incompatible sizes for lin eval action, len=%d, row1=%d, row2=%d, m=%d, n=%d, vrow=%d, crow=%d \n", length, mmt1.row(), mmt2.row(), m, n, mmv.row(), mmc.row());
+      return false;
+    }
+
+  SylvMemoryDriver memdriver(1, m, n, depth);
+  QuasiTriangular t1(mmt1.getData(), mmt1.row());
+  QuasiTriangular t2(mmt2.getData(), mmt2.row());
+  TriangularSylvester ts(t2, t1);
+  Vector vraw1(mmv.getData(), length);
+  ConstKronVector v1(vraw1, m, n, depth);
+  Vector vraw2(mmv.getData()+length, length);
+  ConstKronVector v2(vraw2, m, n, depth);
+  Vector craw1(mmc.getData(), length);
+  KronVector c1(craw1, m, n, depth);
+  Vector craw2(mmc.getData()+length, length);
+  KronVector c2(craw2, m, n, depth);
+  KronVector x1(m, n, depth);
+  KronVector x2(m, n, depth);
+  memdriver.setStackMode(true);
+  ts.linEval(alpha, beta1, beta2, x1, x2, v1, v2);
+  memdriver.setStackMode(false);
+  x1.add(-1, c1);
+  x2.add(-1, c2);
+  double norm1 = x1.getNorm();
+  double norm2 = x2.getNorm();
+  printf("\terror norm1 = %8.4g\n\terror norm2 = %8.4g\n", norm1, norm2);
+  return (norm1*norm1+norm2*norm2 < eps_norm*eps_norm);
+}
+
+bool
+TestRunnable::qua_eval(const char *m1name, const char *m2name, const char *vname,
+                       const char *cname, int m, int n, int depth,
+                       double alpha, double betas, double gamma,
+                       double delta1, double delta2)
+{
+  MMMatrixIn mmt1(m1name);
+  MMMatrixIn mmt2(m2name);
+  MMMatrixIn mmv(vname);
+  MMMatrixIn mmc(cname);
+
+  int length = power(m, depth)*n;
+  if (mmt1.row() != m
+      || mmt2.row() != n
+      || mmv.row() != 2*length
+      || mmc.row() != 2*length)
+    {
+      printf("  Incompatible sizes for qua eval action, len=%d, row1=%d, row2=%d, m=%d, n=%d, vrow=%d, crow=%d \n", length, mmt1.row(), mmt2.row(), m, n, mmv.row(), mmc.row());
+      return false;
+    }
+
+  SylvMemoryDriver memdriver(3, m, n, depth);
+  QuasiTriangular t1(mmt1.getData(), mmt1.row());
+  QuasiTriangular t2(mmt2.getData(), mmt2.row());
+  TriangularSylvester ts(t2, t1);
+  Vector vraw1(mmv.getData(), length);
+  ConstKronVector v1(vraw1, m, n, depth);
+  Vector vraw2(mmv.getData()+length, length);
+  ConstKronVector v2(vraw2, m, n, depth);
+  Vector craw1(mmc.getData(), length);
+  KronVector c1(craw1, m, n, depth);
+  Vector craw2(mmc.getData()+length, length);
+  KronVector c2(craw2, m, n, depth);
+  KronVector x1(m, n, depth);
+  KronVector x2(m, n, depth);
+  memdriver.setStackMode(true);
+  ts.quaEval(alpha, betas, gamma, delta1, delta2, x1, x2, v1, v2);
+  memdriver.setStackMode(false);
+  x1.add(-1, c1);
+  x2.add(-1, c2);
+  double norm1 = x1.getNorm();
+  double norm2 = x2.getNorm();
+  printf("\terror norm1 = %8.4g\n\terror norm2 = %8.4g\n", norm1, norm2);
+  return (norm1*norm1+norm2*norm2 < 100*eps_norm*eps_norm); // relax norm
+}
+
+bool
+TestRunnable::tri_sylv(const char *m1name, const char *m2name, const char *vname,
+                       int m, int n, int depth)
+{
+  MMMatrixIn mmt1(m1name);
+  MMMatrixIn mmt2(m2name);
+  MMMatrixIn mmv(vname);
+
+  int length = power(m, depth)*n;
+  if (mmt1.row() != m
+      || mmt2.row() != n
+      || mmv.row() != length)
+    {
+      printf("  Incompatible sizes for triangular sylvester action, len=%d, row1=%d, row2=%d, m=%d, n=%d, vrow=%d\n", length, mmt1.row(), mmt2.row(), m, n, mmv.row());
+      return false;
+    }
+
+  SylvMemoryDriver memdriver(4, m, n, depth); // need extra 2 for checks done via KronUtils::multKron
+  memdriver.setStackMode(true);
+  QuasiTriangular t1(mmt1.getData(), mmt1.row());
+  QuasiTriangular t2(mmt2.getData(), mmt2.row());
+  TriangularSylvester ts(t2, t1);
+  Vector vraw(mmv.getData(), length);
+  ConstKronVector v(vraw, m, n, depth);
+  KronVector d(v); // copy of v
+  SylvParams pars;
+  ts.solve(pars, d);
+  pars.print("\t");
+  KronVector dcheck((const KronVector &)d);
+  KronUtils::multKron(t1, t2, dcheck);
+  dcheck.add(1.0, d);
+  dcheck.add(-1.0, v);
+  double norm = dcheck.getNorm();
+  double xnorm = v.getNorm();
+  printf("\trel. error norm = %8.4g\n", norm/xnorm);
+  double max = dcheck.getMax();
+  double xmax = v.getMax();
+  printf("\trel. error max = %8.4g\n", max/xmax);
+  memdriver.setStackMode(false);
+  return (norm < xnorm*eps_norm);
+}
+
+bool
+TestRunnable::gen_sylv(const char *aname, const char *bname, const char *cname,
+                       const char *dname, int m, int n, int order)
+{
+  MMMatrixIn mma(aname);
+  MMMatrixIn mmb(bname);
+  MMMatrixIn mmc(cname);
+  MMMatrixIn mmd(dname);
+
+  if (m != mmc.row() || m != mmc.col()
+      || n != mma.row() || n != mma.col()
+      || n != mmb.row() || n <  mmb.col()
+      || n != mmd.row() || power(m, order) != mmd.col())
+    {
+      printf("  Incompatible sizes for gen_sylv.\n");
+      return false;
+    }
+
+  SylvParams ps(true);
+  GeneralSylvester gs(order, n, m, n-mmb.col(),
+                      mma.getData(), mmb.getData(),
+                      mmc.getData(), mmd.getData(),
+                      ps);
+  gs.solve();
+  gs.check(mmd.getData());
+  const SylvParams &pars = gs.getParams();
+  pars.print("\t");
+  return (*(pars.mat_err1) < eps_norm && *(pars.mat_errI) < eps_norm
+          && *(pars.mat_errF) < eps_norm && *(pars.vec_err1) < eps_norm
+          && *(pars.vec_errI) < eps_norm);
+}
+
+bool
+TestRunnable::eig_bubble(const char *aname, int from, int to)
+{
+  MMMatrixIn mma(aname);
+
+  if (mma.row() != mma.col())
+    {
+      printf("  Matrix is not square\n");
+      return false;
+    }
+
+  int n = mma.row();
+  SylvMemoryDriver memdriver(3, n, n, 2);
+  QuasiTriangular orig(mma.getData(), n);
+  SchurDecompEig dec((const QuasiTriangular &)orig);
+  QuasiTriangular::diag_iter itf = dec.getT().diag_begin();
+  QuasiTriangular::diag_iter itt = dec.getT().diag_begin();
+  for (int i = 0; i < from; i++)
+    ++itf;
+  for (int i = 0; i < to; i++)
+    ++itt;
+  itt = dec.bubbleEigen(itf, itt);
+  SqSylvMatrix check(dec.getQ(), dec.getT());
+  check.multRightTrans(dec.getQ());
+  check.add(-1, orig);
+  double norm1 = check.getNorm1();
+  double normInf = check.getNormInf();
+  double onorm1 = orig.getNorm1();
+  double onormInf = orig.getNormInf();
+  printf("\tabs. error1 = %8.4g\n", norm1);
+  printf("\tabs. errorI = %8.4g\n", normInf);
+  printf("\trel. error1 = %8.4g\n", norm1/onorm1);
+  printf("\trel. errorI = %8.4g\n", normInf/onormInf);
+  return (norm1 < eps_norm*onorm1 && normInf < eps_norm*onormInf);
+}
+
+bool
+TestRunnable::block_diag(const char *aname, double log10norm)
+{
+  MMMatrixIn mma(aname);
+
+  if (mma.row() != mma.col())
+    {
+      printf("  Matrix is not square\n");
+      return false;
+    }
+
+  int n = mma.row();
+  SylvMemoryDriver memdriver(3, n, n, 2);
+  SqSylvMatrix orig(mma.getData(), n);
+  SimilarityDecomp dec(orig.base(), orig.numRows(), log10norm);
+  dec.getB().printInfo();
+  SqSylvMatrix check(dec.getQ(), dec.getB());
+  check.multRight(dec.getInvQ());
+  check.add(-1, orig);
+  double norm1 = check.getNorm1();
+  double normInf = check.getNormInf();
+  double onorm1 = orig.getNorm1();
+  double onormInf = orig.getNormInf();
+  printf("\terror Q*B*invQ:\n");
+  printf("\tabs. error1 = %8.4g\n", norm1);
+  printf("\tabs. errorI = %8.4g\n", normInf);
+  printf("\trel. error1 = %8.4g\n", norm1/onorm1);
+  printf("\trel. errorI = %8.4g\n", normInf/onormInf);
+  SqSylvMatrix check2(dec.getQ(), dec.getInvQ());
+  SqSylvMatrix in(n);
+  in.setUnit();
+  check2.add(-1, in);
+  double nor1 = check2.getNorm1();
+  double norInf = check2.getNormInf();
+  printf("\terror Q*invQ:\n");
+  printf("\tabs. error1 = %8.4g\n", nor1);
+  printf("\tabs. errorI = %8.4g\n", norInf);
+  return (norm1 < eps_norm*pow(10, log10norm)*onorm1);
+}
+
+bool
+TestRunnable::iter_sylv(const char *m1name, const char *m2name, const char *vname,
+                        int m, int n, int depth)
+{
+  MMMatrixIn mmt1(m1name);
+  MMMatrixIn mmt2(m2name);
+  MMMatrixIn mmv(vname);
+
+  int length = power(m, depth)*n;
+  if (mmt1.row() != m
+      || mmt2.row() != n
+      || mmv.row() != length)
+    {
+      printf("  Incompatible sizes for triangular sylvester iteration, len=%d, row1=%d, row2=%d, m=%d, n=%d, vrow=%d\n", length, mmt1.row(), mmt2.row(), m, n, mmv.row());
+      return false;
+    }
+
+  SylvMemoryDriver memdriver(4, m, n, depth); // need extra 2 for checks done via KronUtils::multKron
+  memdriver.setStackMode(true);
+  QuasiTriangular t1(mmt1.getData(), mmt1.row());
+  QuasiTriangular t2(mmt2.getData(), mmt2.row());
+  IterativeSylvester is(t2, t1);
+  Vector vraw(mmv.getData(), length);
+  ConstKronVector v(vraw, m, n, depth);
+  KronVector d(v); // copy of v
+  SylvParams pars;
+  pars.method = SylvParams::iter;
+  is.solve(pars, d);
+  pars.print("\t");
+  KronVector dcheck((const KronVector &)d);
+  KronUtils::multKron(t1, t2, dcheck);
+  dcheck.add(1.0, d);
+  dcheck.add(-1.0, v);
+  double cnorm = dcheck.getNorm();
+  double xnorm = v.getNorm();
+  printf("\trel. error norm = %8.4g\n", cnorm/xnorm);
+  double max = dcheck.getMax();
+  double xmax = v.getMax();
+  printf("\trel. error max = %8.4g\n", max/xmax);
+  memdriver.setStackMode(false);
+  return (cnorm < xnorm*eps_norm);
+}
+
+/**********************************************************/
+/*   sub classes declarations                             */
+/**********************************************************/
+
+class PureTriangTest : public TestRunnable
+{
+public:
+  PureTriangTest() : TestRunnable("pure triangular solve (5)")
+  {
+  }
+  bool run() const;
+};
+
+class PureTriangTransTest : public TestRunnable
+{
+public:
+  PureTriangTransTest() : TestRunnable("pure triangular solve trans (5)")
+  {
+  }
+  bool run() const;
+};
+
+class PureTrLargeTest : public TestRunnable
+{
+public:
+  PureTrLargeTest() : TestRunnable("pure triangular large solve (300)")
+  {
+  }
+  bool run() const;
+};
+
+class PureTrLargeTransTest : public TestRunnable
+{
+public:
+  PureTrLargeTransTest() : TestRunnable("pure triangular large solve trans (300)")
+  {
+  }
+  bool run() const;
+};
+
+class QuasiTriangTest : public TestRunnable
+{
+public:
+  QuasiTriangTest() : TestRunnable("quasi triangular solve (7)")
+  {
+  }
+  bool run() const;
+};
+
+class QuasiTriangTransTest : public TestRunnable
+{
+public:
+  QuasiTriangTransTest() : TestRunnable("quasi triangular solve trans (7)")
+  {
+  }
+  bool run() const;
+};
+
+class QuasiTrLargeTest : public TestRunnable
+{
+public:
+  QuasiTrLargeTest() : TestRunnable("quasi triangular solve large (250)")
+  {
+  }
+  bool run() const;
+};
+
+class QuasiTrLargeTransTest : public TestRunnable
+{
+public:
+  QuasiTrLargeTransTest() : TestRunnable("quasi triangular solve large trans (250)")
+  {
+  }
+  bool run() const;
+};
+
+class QuasiZeroSmallTest : public TestRunnable
+{
+public:
+  QuasiZeroSmallTest() : TestRunnable("quasi tr. zero small test (2x1)")
+  {
+  }
+  bool run() const;
+};
+
+class MultKronSmallTest : public TestRunnable
+{
+public:
+  MultKronSmallTest() : TestRunnable("kronecker small mult (2=2x1)")
+  {
+  }
+  bool run() const;
+};
+
+class MultKronTest : public TestRunnable
+{
+public:
+  MultKronTest() : TestRunnable("kronecker mult (245=7x7x5)")
+  {
+  }
+  bool run() const;
+};
+
+class MultKronSmallTransTest : public TestRunnable
+{
+public:
+  MultKronSmallTransTest() : TestRunnable("kronecker small trans mult (2=2x1)")
+  {
+  }
+  bool run() const;
+};
+
+class MultKronTransTest : public TestRunnable
+{
+public:
+  MultKronTransTest() : TestRunnable("kronecker trans mult (245=7x7x5)")
+  {
+  }
+  bool run() const;
+};
+
+class LevelKronTest : public TestRunnable
+{
+public:
+  LevelKronTest() : TestRunnable("kronecker level mult (1715=7x[7]x7x5)")
+  {
+  }
+  bool run() const;
+};
+
+class LevelKronTransTest : public TestRunnable
+{
+public:
+  LevelKronTransTest() : TestRunnable("kronecker level trans mult (1715=7x[7]x7x5)")
+  {
+  }
+  bool run() const;
+};
+
+class LevelZeroKronTest : public TestRunnable
+{
+public:
+  LevelZeroKronTest() : TestRunnable("kronecker level mult (1715=7x7x7x[5])")
+  {
+  }
+  bool run() const;
+};
+
+class LevelZeroKronTransTest : public TestRunnable
+{
+public:
+  LevelZeroKronTransTest() : TestRunnable("kronecker level trans mult (1715=7x7x7x[5])")
+  {
+  }
+  bool run() const;
+};
+
+class KronPowerTest : public TestRunnable
+{
+public:
+  KronPowerTest() : TestRunnable("kronecker power mult (1715=7x7x7x5)")
+  {
+  }
+  bool run() const;
+};
+
+class SmallLinEvalTest : public TestRunnable
+{
+public:
+  SmallLinEvalTest() : TestRunnable("lin eval (24=2 x 2x2x3)")
+  {
+  }
+  bool run() const;
+};
+
+class LinEvalTest : public TestRunnable
+{
+public:
+  LinEvalTest() : TestRunnable("lin eval (490=2 x 7x7x5)")
+  {
+  }
+  bool run() const;
+};
+
+class SmallQuaEvalTest : public TestRunnable
+{
+public:
+  SmallQuaEvalTest() : TestRunnable("qua eval (24=2 x 2x2x3)")
+  {
+  }
+  bool run() const;
+};
+
+class QuaEvalTest : public TestRunnable
+{
+public:
+  QuaEvalTest() : TestRunnable("qua eval (490=2 x 7x7x5)")
+  {
+  }
+  bool run() const;
+};
+
+class TriSylvSmallRealTest : public TestRunnable
+{
+public:
+  TriSylvSmallRealTest() : TestRunnable("triangular sylvester small real solve (12=2x2x3)")
+  {
+  }
+  bool run() const;
+};
+
+class TriSylvSmallComplexTest : public TestRunnable
+{
+public:
+  TriSylvSmallComplexTest() : TestRunnable("triangular sylvester small complx solve (12=2x2x3)")
+  {
+  }
+  bool run() const;
+};
+
+class TriSylvTest : public TestRunnable
+{
+public:
+  TriSylvTest() : TestRunnable("triangular sylvester solve (245=7x7x5)")
+  {
+  }
+  bool run() const;
+};
+
+class TriSylvBigTest : public TestRunnable
+{
+public:
+  TriSylvBigTest() : TestRunnable("triangular sylvester big solve (48000=40x40x30)")
+  {
+  }
+  bool run() const;
+};
+
+class TriSylvLargeTest : public TestRunnable
+{
+public:
+  TriSylvLargeTest() : TestRunnable("triangular sylvester large solve (1920000=40x40x40x30)")
+  {
+  }
+  bool run() const;
+};
+
+class IterSylvTest : public TestRunnable
+{
+public:
+  IterSylvTest() : TestRunnable("iterative sylvester solve (245=7x7x5)")
+  {
+  }
+  bool run() const;
+};
+
+class IterSylvLargeTest : public TestRunnable
+{
+public:
+  IterSylvLargeTest() : TestRunnable("iterative sylvester large solve (1920000=40x40x40x30)")
+  {
+  }
+  bool run() const;
+};
+
+class GenSylvSmallTest : public TestRunnable
+{
+public:
+  GenSylvSmallTest() : TestRunnable("general sylvester small solve (18=3x3x2)")
+  {
+  }
+  bool run() const;
+};
+
+class GenSylvTest : public TestRunnable
+{
+public:
+  GenSylvTest() : TestRunnable("general sylvester solve (12000=20x20x30)")
+  {
+  }
+  bool run() const;
+};
+
+class GenSylvSingTest : public TestRunnable
+{
+public:
+  GenSylvSingTest() : TestRunnable("general sylvester solve for sing. C (2500000=50x50x50x20)")
+  {
+  }
+  bool run() const;
+};
+
+class GenSylvLargeTest : public TestRunnable
+{
+public:
+  GenSylvLargeTest() : TestRunnable("general sylvester solve (2500000=50x50x50x20)")
+  {
+  }
+  bool run() const;
+};
+
+class EigBubFrankTest : public TestRunnable
+{
+public:
+  EigBubFrankTest() : TestRunnable("eig. bubble frank test (12x12)")
+  {
+  }
+  bool run() const;
+};
+
+class EigBubSplitTest : public TestRunnable
+{
+  // complex eigenvalue is split by swapping it with real
+public:
+  EigBubSplitTest() : TestRunnable("eig. bubble complex split test (3x3)")
+  {
+  }
+  bool run() const;
+};
+
+class EigBubSameTest : public TestRunnable
+{
+  // complex eigenevalue bypasses the same complex eigenvalue
+public:
+  EigBubSameTest() : TestRunnable("eig. bubble same test (5x5)")
+  {
+  }
+  bool run() const;
+};
+
+class BlockDiagSmallTest : public TestRunnable
+{
+public:
+  BlockDiagSmallTest() : TestRunnable("block diagonalization small test (7x7)")
+  {
+  }
+  bool run() const;
+};
+
+class BlockDiagFrankTest : public TestRunnable
+{
+public:
+  BlockDiagFrankTest() : TestRunnable("block diagonalization of frank (12x12)")
+  {
+  }
+  bool run() const;
+};
+
+class BlockDiagIllCondTest : public TestRunnable
+{
+public:
+  BlockDiagIllCondTest() : TestRunnable("block diagonalization of ill conditioned (15x15)")
+  {
+  }
+  bool run() const;
+};
+
+class BlockDiagBigTest : public TestRunnable
+{
+public:
+  BlockDiagBigTest() : TestRunnable("block diagonalization big test (50x50)")
+  {
+  }
+  bool run() const;
+};
+
+/**********************************************************/
+/*   run methods of sub classes                           */
+/**********************************************************/
+
+bool
+PureTriangTest::run() const
+{
+  return quasi_solve(false, "tr5x5.mm", "v5.mm");
+}
+
+bool
+PureTriangTransTest::run() const
+{
+  return quasi_solve(true, "tr5x5.mm", "v5.mm");
+}
+
+bool
+PureTrLargeTest::run() const
+{
+  return quasi_solve(false, "tr300x300.mm", "v300.mm");
+}
+
+bool
+PureTrLargeTransTest::run() const
+{
+  return quasi_solve(true, "tr300x300.mm", "v300.mm");
+}
+
+bool
+QuasiTriangTest::run() const
+{
+  return quasi_solve(false, "qt7x7.mm", "v7.mm");
+}
+
+bool
+QuasiTriangTransTest::run() const
+{
+  return quasi_solve(true, "qt7x7.mm", "v7.mm");
+}
+
+bool
+QuasiTrLargeTest::run() const
+{
+  return quasi_solve(false, "qt250x250.mm", "v250.mm");
+}
+
+bool
+QuasiTrLargeTransTest::run() const
+{
+  return quasi_solve(true, "qt250x250.mm", "v250.mm");
+}
+
+bool
+QuasiZeroSmallTest::run() const
+{
+  return quasi_solve(false, "b2x1.mm", "v2.mm");
+}
+
+bool
+MultKronSmallTest::run() const
+{
+  return mult_kron(false, "tr2x2.mm", "v2.mm", "vcheck2.mm", 2, 1, 1);
+}
+
+bool
+MultKronTest::run() const
+{
+  return mult_kron(false, "qt7x7.mm", "v245.mm", "vcheck245.mm", 7, 5, 2);
+}
+
+bool
+MultKronSmallTransTest::run() const
+{
+  return mult_kron(true, "tr2x2.mm", "v2.mm", "vcheck2a.mm", 2, 1, 1);
+}
+
+bool
+MultKronTransTest::run() const
+{
+  return mult_kron(true, "qt7x7.mm", "v245.mm", "vcheck245a.mm", 7, 5, 2);
+}
+
+bool
+LevelKronTest::run() const
+{
+  return level_kron(false, "qt7x7.mm", "v1715.mm", "vcheck1715.mm", 2, 7, 5, 3);
+}
+
+bool
+LevelKronTransTest::run() const
+{
+  return level_kron(true, "qt7x7.mm", "v1715.mm", "vcheck1715a.mm", 2, 7, 5, 3);
+}
+
+bool
+LevelZeroKronTest::run() const
+{
+  return level_kron(false, "tr5x5.mm", "v1715.mm", "vcheck1715b.mm", 0, 7, 5, 3);
+}
+
+bool
+LevelZeroKronTransTest::run() const
+{
+  return level_kron(true, "tr5x5.mm", "v1715.mm", "vcheck1715c.mm", 0, 7, 5, 3);
+}
+
+bool
+KronPowerTest::run() const
+{
+  return kron_power("qt7x7.mm", "tr5x5.mm", "v1715.mm", "vcheck1715d.mm", 7, 5, 3);
+}
+
+bool
+SmallLinEvalTest::run() const
+{
+  return lin_eval("qt2x2.mm", "qt3x3.mm", "v24.mm", "vcheck24.mm", 2, 3, 2,
+                  2, 1, 3);
+}
+
+bool
+LinEvalTest::run() const
+{
+  return lin_eval("qt7x7.mm", "tr5x5.mm", "v490.mm", "vcheck490.mm", 7, 5, 2,
+                  2, 1, 3);
+}
+
+bool
+SmallQuaEvalTest::run() const
+{
+  return qua_eval("qt2x2.mm", "qt3x3.mm", "v24.mm", "vcheck24q.mm", 2, 3, 2,
+                  -0.5, 3, 2, 1, 3);
+}
+
+bool
+QuaEvalTest::run() const
+{
+  return qua_eval("qt7x7.mm", "tr5x5.mm", "v490.mm", "vcheck490q.mm", 7, 5, 2,
+                  -0.5, 3, 2, 1, 3);
+}
+
+bool
+TriSylvSmallRealTest::run() const
+{
+  return tri_sylv("tr2x2.mm", "qt3x3.mm", "v12r.mm", 2, 3, 2);
+}
+
+bool
+TriSylvSmallComplexTest::run() const
+{
+  return tri_sylv("qt2x2.mm", "qt3x3.mm", "v12r.mm", 2, 3, 2);
+}
+
+bool
+TriSylvTest::run() const
+{
+  return tri_sylv("qt7x7eig06-09.mm", "tr5x5.mm", "v245r.mm", 7, 5, 2);
+}
+
+bool
+TriSylvBigTest::run() const
+{
+  return tri_sylv("qt40x40.mm", "qt30x30eig011-095.mm", "v48000.mm", 40, 30, 2);
+}
+
+bool
+TriSylvLargeTest::run() const
+{
+  return tri_sylv("qt40x40.mm", "qt30x30eig011-095.mm", "v1920000.mm", 40, 30, 3);
+}
+
+bool
+IterSylvTest::run() const
+{
+  return iter_sylv("qt7x7eig06-09.mm", "qt5x5.mm", "v245r.mm", 7, 5, 2);
+}
+
+bool
+IterSylvLargeTest::run() const
+{
+  return iter_sylv("qt40x40.mm", "qt30x30eig011-095.mm", "v1920000.mm", 40, 30, 3);
+}
+
+bool
+GenSylvSmallTest::run() const
+{
+  return gen_sylv("a2x2.mm", "b2x1.mm", "c3x3.mm", "d2x9.mm", 3, 2, 2);
+}
+
+bool
+GenSylvTest::run() const
+{
+  return gen_sylv("a30x30.mm", "b30x25.mm", "c20x20.mm", "d30x400.mm", 20, 30, 2);
+}
+
+bool
+GenSylvSingTest::run() const
+{
+  return gen_sylv("a20x20.mm", "b20x4.mm", "c50x50sing.mm", "d20x125000.mm", 50, 20, 3);
+}
+
+bool
+GenSylvLargeTest::run() const
+{
+  return gen_sylv("a20x20.mm", "b20x15.mm", "c50x50.mm", "d20x125000.mm", 50, 20, 3);
+}
+
+bool
+EigBubFrankTest::run() const
+{
+  return eig_bubble("qt_frank12x12.mm", 8, 0);
+}
+
+bool
+EigBubSplitTest::run() const
+{
+  return eig_bubble("qt_eps3x3.mm", 1, 0);
+}
+
+bool
+EigBubSameTest::run() const
+{
+  return eig_bubble("qt5x5.mm", 2, 0);
+}
+
+bool
+BlockDiagSmallTest::run() const
+{
+  return block_diag("qt7x7.mm", 0.1);
+}
+
+bool
+BlockDiagFrankTest::run() const
+{
+  return block_diag("qt_frank12x12.mm", 5);
+}
+
+bool
+BlockDiagIllCondTest::run() const
+{
+  return block_diag("ill_cond15x15.mm", 4.14);
+}
+
+bool
+BlockDiagBigTest::run() const
+{
+  return block_diag("c50x50.mm", 1.3);
+}
+
+/**********************************************************/
+/*   main                                                 */
+/**********************************************************/
+
+int
+main()
+{
+  TestRunnable *all_tests[50];
+  // fill in vector of all tests
+  int num_tests = 0;
+  all_tests[num_tests++] = new PureTriangTest();
+  all_tests[num_tests++] = new PureTriangTransTest();
+  all_tests[num_tests++] = new PureTrLargeTest();
+  all_tests[num_tests++] = new PureTrLargeTransTest();
+  all_tests[num_tests++] = new QuasiTriangTest();
+  all_tests[num_tests++] = new QuasiTriangTransTest();
+  all_tests[num_tests++] = new QuasiTrLargeTest();
+  all_tests[num_tests++] = new QuasiTrLargeTransTest();
+  all_tests[num_tests++] = new QuasiZeroSmallTest();
+  all_tests[num_tests++] = new MultKronSmallTest();
+  all_tests[num_tests++] = new MultKronTest();
+  all_tests[num_tests++] = new MultKronSmallTransTest();
+  all_tests[num_tests++] = new MultKronTransTest();
+  all_tests[num_tests++] = new LevelKronTest();
+  all_tests[num_tests++] = new LevelKronTransTest();
+  all_tests[num_tests++] = new LevelZeroKronTest();
+  all_tests[num_tests++] = new LevelZeroKronTransTest();
+  all_tests[num_tests++] = new KronPowerTest();
+  all_tests[num_tests++] = new SmallLinEvalTest();
+  all_tests[num_tests++] = new LinEvalTest();
+  all_tests[num_tests++] = new SmallQuaEvalTest();
+  all_tests[num_tests++] = new QuaEvalTest();
+  all_tests[num_tests++] = new EigBubFrankTest();
+  all_tests[num_tests++] = new EigBubSplitTest();
+  all_tests[num_tests++] = new EigBubSameTest();
+  all_tests[num_tests++] = new BlockDiagSmallTest();
+  all_tests[num_tests++] = new BlockDiagFrankTest();
+  all_tests[num_tests++] = new BlockDiagIllCondTest();
+  all_tests[num_tests++] = new BlockDiagBigTest();
+  all_tests[num_tests++] = new TriSylvSmallRealTest();
+  all_tests[num_tests++] = new TriSylvSmallComplexTest();
+  all_tests[num_tests++] = new TriSylvTest();
+  all_tests[num_tests++] = new TriSylvBigTest();
+  all_tests[num_tests++] = new TriSylvLargeTest();
+  all_tests[num_tests++] = new IterSylvTest();
+  all_tests[num_tests++] = new IterSylvLargeTest();
+  all_tests[num_tests++] = new GenSylvSmallTest();
+  all_tests[num_tests++] = new GenSylvTest();
+  all_tests[num_tests++] = new GenSylvSingTest();
+  all_tests[num_tests++] = new GenSylvLargeTest();
+
+  // launch the tests
+  int success = 0;
+  for (int i = 0; i < num_tests; i++)
+    {
+      try
+        {
+          if (all_tests[i]->test())
+            success++;
+        }
+      catch (const MMException &e)
+        {
+          printf("Caugth MM exception in <%s>:\n%s", all_tests[i]->getName(),
+                 e.getMessage());
+        }
+      catch (SylvException &e)
+        {
+          printf("Caught Sylv exception in %s:\n", all_tests[i]->getName());
+          e.printMessage();
+        }
+    }
+
+  printf("There were %d tests that failed out of %d tests run.\n",
+         num_tests - success, num_tests);
+
+  // destroy
+  for (int i = 0; i < num_tests; i++)
+    {
+      delete all_tests[i];
+    }
+
+  return 0;
+}
diff --git a/dynare++/sylv/testing/tests.cpp b/dynare++/sylv/testing/tests.cpp
deleted file mode 100644
index 5b1cc23389539fe3a37e2739cc3b8205fa4fc7db..0000000000000000000000000000000000000000
--- a/dynare++/sylv/testing/tests.cpp
+++ /dev/null
@@ -1,1022 +0,0 @@
-/* $Header: /var/lib/cvs/dynare_cpp/sylv/testing/tests.cpp,v 1.2 2004/07/05 19:55:48 kamenik Exp $ */
-
-/* Tag $Name:  $ */
-
-#include "SylvException.h"
-#include "QuasiTriangular.h"
-#include "QuasiTriangularZero.h"
-#include "Vector.h"
-#include "KronVector.h"
-#include "KronUtils.h"
-#include "TriangularSylvester.h"
-#include "GeneralSylvester.h"
-#include "SylvMemory.h"
-#include "SchurDecompEig.h"
-#include "SimilarityDecomp.h"
-#include "IterativeSylvester.h"
-#include "SylvMatrix.h"
-
-#include "MMMatrix.h"
-
-#include <cstdio>
-#include <cstring>
-#include <ctime>
-
-#include <cmath>
-
-class TestRunnable : public MallocAllocator {
-	char name[100];
-	static double eps_norm;
-public:
-	TestRunnable(const char* n){strncpy(name, n, 100);}
-	bool test() const;
-	virtual bool run() const =0;
-	const char* getName() const {return name;}
-protected:
-	// declaration of auxiliary static methods
-	static bool quasi_solve(bool trans, const char* mname, const char* vname);
-	static bool mult_kron(bool trans, const char* mname, const char* vname,
-						  const char* cname, int m, int n, int depth);
-	static bool level_kron(bool trans, const char* mname, const char* vname,
-						   const char* cname, int level, int m, int n, int depth);
-	static bool kron_power(const char* m1name, const char* m2name, const char* vname,
-						   const char* cname, int m, int n, int depth);
-	static bool lin_eval(const char* m1name, const char* m2name, const char* vname,
-						 const char* cname, int m, int n, int depth,
-						 double alpha, double beta1, double beta2);
-	static bool qua_eval(const char* m1name, const char* m2name, const char* vname,
-						 const char* cname, int m, int n, int depth,
-						 double alpha, double betas, double gamma,
-						 double delta1, double delta2);
-	static bool tri_sylv(const char* m1name, const char* m2name, const char* vname,
-						 int m, int n, int depth);
-	static bool gen_sylv(const char* aname, const char* bname, const char* cname,
-						 const char* dname, int m, int n, int order);
-	static bool eig_bubble(const char* aname, int from, int to);
-	static bool block_diag(const char* aname, double log10norm = 3.0);
-	static bool iter_sylv(const char* m1name, const char* m2name, const char* vname,
-						  int m, int n, int depth);
-};
-
-double TestRunnable::eps_norm = 1.0e-10;
-
-bool TestRunnable::test() const
-{
-	printf("Running test <%s>\n",name);
-	clock_t start = clock();
-	bool passed = run();
-	clock_t end = clock();
-	printf("CPU time %8.4g (CPU seconds)..................",
-		   ((double)(end-start))/CLOCKS_PER_SEC);
-	if (passed) {
-		printf("passed\n\n");
-		return passed;
-	} else {
-		printf("FAILED\n\n");
-		return passed;
-	}
-}
-
-/**********************************************************/
-/*   auxiliary methods                                    */
-/**********************************************************/
-
-bool TestRunnable::quasi_solve(bool trans, const char* mname, const char* vname)
-{
-	MMMatrixIn mmt(mname);
-	MMMatrixIn mmv(vname);
-
-	SylvMemoryDriver memdriver(1, mmt.row(), mmt.row(), 1);
-	QuasiTriangular* t;
-	QuasiTriangular* tsave;
-	if (mmt.row()==mmt.col()) {
-		t = new QuasiTriangular(mmt.getData(), mmt.row());
-		tsave = new QuasiTriangular(*t);
-	} else if (mmt.row()>mmt.col()) {
-		t = new QuasiTriangularZero(mmt.row()-mmt.col(), mmt.getData(), mmt.col());
-		tsave = new QuasiTriangularZero((const QuasiTriangularZero&)*t);
-	} else {
-		printf("  Wrong quasi triangular dimensions, rows must be >= cols.\n");
-		return false;
-	}
-	ConstVector v(mmv.getData(), mmv.row());
-	Vector x(v.length());
-	double eig_min = 1.0e20;
-	if (trans)
-		t->solveTrans(x, v, eig_min);
-	else
-		t->solve(x, v, eig_min);
-	printf("eig_min = %8.4g\n", eig_min);
-	Vector xx(v.length());
-	if (trans)
-		tsave->multVecTrans(xx, ConstVector(x));
-	else
-		tsave->multVec(xx, ConstVector(x));
-	delete tsave;
-	delete t;
-	xx.add(-1.0, v);
-	xx.add(1.0, x);
-	double norm = xx.getNorm();
-	printf("\terror norm = %8.4g\n",norm);
-	return (norm < eps_norm);
-}
-
-bool TestRunnable::mult_kron(bool trans, const char* mname, const char* vname,
-							 const char* cname, int m, int n, int depth)
-{
-	MMMatrixIn mmt(mname);
-	MMMatrixIn mmv(vname);
-	MMMatrixIn mmc(cname);
-
-	int length = power(m,depth)*n;
-	if (mmt.row() != m ||
-		mmv.row() != length ||
-		mmc.row() != length) {
-		printf("  Incompatible sizes for krom mult action, len=%d, matrow=%d, m=%d, vrow=%d, crow=%d \n",length,mmt.row(), m, mmv.row(), mmc.row());
-		return false;
-	}
-
-	SylvMemoryDriver memdriver(1, m, n, depth);
-	QuasiTriangular t(mmt.getData(), mmt.row());
-	Vector vraw(mmv.getData(), mmv.row());
-	KronVector v(vraw, m, n, depth);
-	Vector craw(mmc.getData(), mmc.row());
-	KronVector c(craw, m, n, depth);
-	if (trans)
-		t.multKronTrans(v);
-	else
-		t.multKron(v);
-	c.add(-1.0, v);
-	double norm = c.getNorm();
-	printf("\terror norm = %8.4g\n",norm);
-	return (norm < eps_norm);
-}
-
-bool TestRunnable::level_kron(bool trans, const char* mname, const char* vname,
-							  const char* cname, int level, int m, int n, int depth)
-{
-	MMMatrixIn mmt(mname);
-	MMMatrixIn mmv(vname);
-	MMMatrixIn mmc(cname);
-
-	int length = power(m,depth)*n;
-	if (level > 0 && mmt.row() != m ||
-		level == 0 && mmt.row() != n ||
-		mmv.row() != length ||
-		mmc.row() != length) {
-		printf("  Incompatible sizes for krom mult action, len=%d, matrow=%d, m=%d, n=%d, vrow=%d, crow=%d \n",length, mmt.row(), m, n, mmv.row(), mmc.row());
-		return false;
-	}
-
-	SylvMemoryDriver memdriver(1, m, n, depth);
-	QuasiTriangular t(mmt.getData(), mmt.row());
-	Vector vraw(mmv.getData(), mmv.row());
-	ConstKronVector v(vraw, m, n, depth);
-	Vector craw(mmc.getData(), mmc.row());
-	KronVector c(craw, m, n, depth);
-	KronVector x(v);
-	if (trans)
-		KronUtils::multAtLevelTrans(level, t, x);
-	else
-		KronUtils::multAtLevel(level, t, x);
-	x.add(-1, c);
-	double norm = x.getNorm();
-	printf("\terror norm = %8.4g\n",norm);
-	return (norm < eps_norm);
-}
-
-bool TestRunnable::kron_power(const char* m1name, const char* m2name, const char* vname,
-							  const char* cname, int m, int n, int depth)
-{
-	MMMatrixIn mmt1(m1name);
-	MMMatrixIn mmt2(m2name);
-	MMMatrixIn mmv(vname);
-	MMMatrixIn mmc(cname);
-
-	int length = power(m,depth)*n;
-	if (mmt1.row() != m ||
-		mmt2.row() != n ||
-		mmv.row() != length ||
-		mmc.row() != length) {
-		printf("  Incompatible sizes for krom power mult action, len=%d, row1=%d, row2=%d, m=%d, n=%d, vrow=%d, crow=%d \n",length,mmt1.row(), mmt2.row(), m, n, mmv.row(), mmc.row());
-		return false;
-	}
-
-	SylvMemoryDriver memdriver(2, m, n, depth);
-	QuasiTriangular t1(mmt1.getData(), mmt1.row());
-	QuasiTriangular t2(mmt2.getData(), mmt2.row());
-	Vector vraw(mmv.getData(), mmv.row());
-	ConstKronVector v(vraw, m, n, depth);
-	Vector craw(mmc.getData(), mmc.row());
-	KronVector c(craw, m, n, depth);
-	KronVector x(v);
-	memdriver.setStackMode(true);
-	KronUtils::multKron(t1, t2, x);
-	memdriver.setStackMode(false);
-	x.add(-1, c);
-	double norm = x.getNorm();
-	printf("\terror norm = %8.4g\n",norm);
-	return (norm < eps_norm);
-}
-
-bool TestRunnable::lin_eval(const char* m1name, const char* m2name, const char* vname,
-							const char* cname, int m, int n, int depth,
-							double alpha, double beta1, double beta2)
-{
-	MMMatrixIn mmt1(m1name);
-	MMMatrixIn mmt2(m2name);
-	MMMatrixIn mmv(vname);
-	MMMatrixIn mmc(cname);
-
-	int length = power(m,depth)*n;
-	if (mmt1.row() != m ||
-		mmt2.row() != n ||
-		mmv.row() != 2*length ||
-		mmc.row() != 2*length) {
-		printf("  Incompatible sizes for lin eval action, len=%d, row1=%d, row2=%d, m=%d, n=%d, vrow=%d, crow=%d \n",length,mmt1.row(), mmt2.row(), m, n, mmv.row(), mmc.row());
-		return false;
-	}
-
-	SylvMemoryDriver memdriver(1, m, n, depth);
-	QuasiTriangular t1(mmt1.getData(), mmt1.row());
-	QuasiTriangular t2(mmt2.getData(), mmt2.row());
-	TriangularSylvester ts(t2, t1);
-	Vector vraw1(mmv.getData(), length);
-	ConstKronVector v1(vraw1, m, n, depth);
-	Vector vraw2(mmv.getData()+length, length);
-	ConstKronVector v2(vraw2, m, n, depth);
-	Vector craw1(mmc.getData(), length);
-	KronVector c1(craw1, m, n, depth);
-	Vector craw2(mmc.getData()+length, length);
-	KronVector c2(craw2, m, n, depth);
-	KronVector x1(m, n, depth);
-	KronVector x2(m, n, depth);
-	memdriver.setStackMode(true);
-	ts.linEval(alpha, beta1, beta2, x1, x2, v1, v2);
-	memdriver.setStackMode(false);
-	x1.add(-1, c1);
-	x2.add(-1, c2);
-	double norm1 = x1.getNorm();
-	double norm2 = x2.getNorm();
-	printf("\terror norm1 = %8.4g\n\terror norm2 = %8.4g\n",norm1,norm2);
-	return (norm1*norm1+norm2*norm2 < eps_norm*eps_norm);
-}
-
-
-bool TestRunnable::qua_eval(const char* m1name, const char* m2name, const char* vname,
-							const char* cname, int m, int n, int depth,
-							double alpha, double betas, double gamma,
-							double delta1, double delta2)
-{
-	MMMatrixIn mmt1(m1name);
-	MMMatrixIn mmt2(m2name);
-	MMMatrixIn mmv(vname);
-	MMMatrixIn mmc(cname);
-
-	int length = power(m,depth)*n;
-	if (mmt1.row() != m ||
-		mmt2.row() != n ||
-		mmv.row() != 2*length ||
-		mmc.row() != 2*length) {
-		printf("  Incompatible sizes for qua eval action, len=%d, row1=%d, row2=%d, m=%d, n=%d, vrow=%d, crow=%d \n",length,mmt1.row(), mmt2.row(), m, n, mmv.row(), mmc.row());
-		return false;
-	}
-
-	SylvMemoryDriver memdriver(3, m, n, depth);
-	QuasiTriangular t1(mmt1.getData(), mmt1.row());
-	QuasiTriangular t2(mmt2.getData(), mmt2.row());
-	TriangularSylvester ts(t2, t1);
-	Vector vraw1(mmv.getData(), length);
-	ConstKronVector v1(vraw1, m, n, depth);
-	Vector vraw2(mmv.getData()+length, length);
-	ConstKronVector v2(vraw2, m, n, depth);
-	Vector craw1(mmc.getData(), length);
-	KronVector c1(craw1, m, n, depth);
-	Vector craw2(mmc.getData()+length, length);
-	KronVector c2(craw2, m, n, depth);
-	KronVector x1(m, n, depth);
-	KronVector x2(m, n, depth);
-	memdriver.setStackMode(true);
-	ts.quaEval(alpha, betas, gamma, delta1, delta2, x1, x2, v1, v2);
-	memdriver.setStackMode(false);
-	x1.add(-1, c1);
-	x2.add(-1, c2);
-	double norm1 = x1.getNorm();
-	double norm2 = x2.getNorm();
-	printf("\terror norm1 = %8.4g\n\terror norm2 = %8.4g\n",norm1,norm2);
-	return (norm1*norm1+norm2*norm2 < 100*eps_norm*eps_norm); // relax norm
-}
-
-bool TestRunnable::tri_sylv(const char* m1name, const char* m2name, const char* vname,
-							int m, int n, int depth)
-{
-	MMMatrixIn mmt1(m1name);
-	MMMatrixIn mmt2(m2name);
-	MMMatrixIn mmv(vname);
-
-	int length = power(m,depth)*n;
-	if (mmt1.row() != m ||
-		mmt2.row() != n ||
-		mmv.row() != length) {
-		printf("  Incompatible sizes for triangular sylvester action, len=%d, row1=%d, row2=%d, m=%d, n=%d, vrow=%d\n",length,mmt1.row(), mmt2.row(), m, n, mmv.row());
-		return false;
-	}
-
-	SylvMemoryDriver memdriver(4, m, n, depth); // need extra 2 for checks done via KronUtils::multKron
-	memdriver.setStackMode(true);
-	QuasiTriangular t1(mmt1.getData(), mmt1.row());
-	QuasiTriangular t2(mmt2.getData(), mmt2.row());
-	TriangularSylvester ts(t2, t1);
-	Vector vraw(mmv.getData(), length);
-	ConstKronVector v(vraw, m, n, depth);
-	KronVector d(v); // copy of v
-	SylvParams pars;
-	ts.solve(pars, d);
-	pars.print("\t");
-	KronVector dcheck((const KronVector&)d);
-	KronUtils::multKron(t1, t2, dcheck);
-	dcheck.add(1.0, d);
-	dcheck.add(-1.0, v);
-	double norm = dcheck.getNorm();
-	double xnorm = v.getNorm();
-	printf("\trel. error norm = %8.4g\n",norm/xnorm);
-	double max = dcheck.getMax();
-	double xmax = v.getMax();
-	printf("\trel. error max = %8.4g\n", max/xmax);
-	memdriver.setStackMode(false);
-	return (norm < xnorm*eps_norm);
-}
-
-bool TestRunnable::gen_sylv(const char* aname, const char* bname, const char* cname,
-							const char* dname, int m, int n, int order)
-{
-	MMMatrixIn mma(aname);
-	MMMatrixIn mmb(bname);
-	MMMatrixIn mmc(cname);
-	MMMatrixIn mmd(dname);
-
-	if (m != mmc.row() || m != mmc.col() ||
-		n != mma.row() || n != mma.col() ||
-		n != mmb.row() || n <  mmb.col() ||
-		n != mmd.row() || power(m, order) != mmd.col()) {
-		printf("  Incompatible sizes for gen_sylv.\n");
-		return false;
-	}
-
-	SylvParams ps(true);
-	GeneralSylvester gs(order, n, m, n-mmb.col(),
-						mma.getData(), mmb.getData(),
-						mmc.getData(), mmd.getData(),
-						ps);
-	gs.solve();
-	gs.check(mmd.getData());
-	const SylvParams& pars = gs.getParams();
-	pars.print("\t");
-	return (*(pars.mat_err1) < eps_norm && *(pars.mat_errI) < eps_norm &&
-			*(pars.mat_errF) < eps_norm && *(pars.vec_err1) < eps_norm &&
-			*(pars.vec_errI) < eps_norm);
-}
-
-bool TestRunnable::eig_bubble(const char* aname, int from, int to)
-{
-	MMMatrixIn mma(aname);
-
-	if (mma.row() != mma.col()) {
-		printf("  Matrix is not square\n");
-		return false;
-	}
-
-	int n = mma.row();
-	SylvMemoryDriver memdriver(3, n, n, 2);
-	QuasiTriangular orig(mma.getData(), n);
-	SchurDecompEig dec((const QuasiTriangular&)orig);
-	QuasiTriangular::diag_iter itf = dec.getT().diag_begin();
-	QuasiTriangular::diag_iter itt = dec.getT().diag_begin();
-	for (int i = 0; i < from; i++)
-		++itf;
-	for (int i = 0; i < to; i++)
-		++itt;
-	itt = dec.bubbleEigen(itf, itt);
-	SqSylvMatrix check(dec.getQ(), dec.getT());
-	check.multRightTrans(dec.getQ());
-	check.add(-1, orig);
-	double norm1 = check.getNorm1();
-	double normInf = check.getNormInf();
-	double onorm1 = orig.getNorm1();
-	double onormInf = orig.getNormInf();
-	printf("\tabs. error1 = %8.4g\n", norm1);
-	printf("\tabs. errorI = %8.4g\n", normInf);
-	printf("\trel. error1 = %8.4g\n", norm1/onorm1);
-	printf("\trel. errorI = %8.4g\n", normInf/onormInf);
-	return (norm1 < eps_norm*onorm1 && normInf < eps_norm*onormInf);
-}
-
-bool TestRunnable::block_diag(const char* aname, double log10norm)
-{
-	MMMatrixIn mma(aname);
-
-	if (mma.row() != mma.col()) {
-		printf("  Matrix is not square\n");
-		return false;
-	}
-
-	int n = mma.row();
-	SylvMemoryDriver memdriver(3, n, n, 2);
-	SqSylvMatrix orig(mma.getData(), n);
-	SimilarityDecomp dec(orig.base(), orig.numRows(), log10norm);
-	dec.getB().printInfo();
-	SqSylvMatrix check(dec.getQ(), dec.getB());
-	check.multRight(dec.getInvQ());
-	check.add(-1, orig);
-	double norm1 = check.getNorm1();
-	double normInf = check.getNormInf();
-	double onorm1 = orig.getNorm1();
-	double onormInf = orig.getNormInf();
-	printf("\terror Q*B*invQ:\n");
-	printf("\tabs. error1 = %8.4g\n", norm1);
-	printf("\tabs. errorI = %8.4g\n", normInf);
-	printf("\trel. error1 = %8.4g\n", norm1/onorm1);
-	printf("\trel. errorI = %8.4g\n", normInf/onormInf);
-	SqSylvMatrix check2(dec.getQ(), dec.getInvQ());
-	SqSylvMatrix in(n);
-	in.setUnit();
-	check2.add(-1, in);
-	double nor1 = check2.getNorm1();
-	double norInf = check2.getNormInf();
-	printf("\terror Q*invQ:\n");
-	printf("\tabs. error1 = %8.4g\n", nor1);
-	printf("\tabs. errorI = %8.4g\n", norInf);
-	return (norm1 < eps_norm*pow(10, log10norm)*onorm1);
-}
-
-bool TestRunnable::iter_sylv(const char* m1name, const char* m2name, const char* vname,
-							 int m, int n, int depth)
-{
-	MMMatrixIn mmt1(m1name);
-	MMMatrixIn mmt2(m2name);
-	MMMatrixIn mmv(vname);
-
-	int length = power(m,depth)*n;
-	if (mmt1.row() != m ||
-		mmt2.row() != n ||
-		mmv.row() != length) {
-		printf("  Incompatible sizes for triangular sylvester iteration, len=%d, row1=%d, row2=%d, m=%d, n=%d, vrow=%d\n",length,mmt1.row(), mmt2.row(), m, n, mmv.row());
-		return false;
-	}
-
-	SylvMemoryDriver memdriver(4, m, n, depth); // need extra 2 for checks done via KronUtils::multKron
-	memdriver.setStackMode(true);
-	QuasiTriangular t1(mmt1.getData(), mmt1.row());
-	QuasiTriangular t2(mmt2.getData(), mmt2.row());
-	IterativeSylvester is(t2, t1);
-	Vector vraw(mmv.getData(), length);
-	ConstKronVector v(vraw, m, n, depth);
-	KronVector d(v); // copy of v
-	SylvParams pars;
-	pars.method = SylvParams::iter;
-	is.solve(pars, d);
-	pars.print("\t");
-	KronVector dcheck((const KronVector&)d);
-	KronUtils::multKron(t1, t2, dcheck);
-	dcheck.add(1.0, d);
-	dcheck.add(-1.0, v);
-	double cnorm = dcheck.getNorm();
-	double xnorm = v.getNorm();
-	printf("\trel. error norm = %8.4g\n",cnorm/xnorm);
-	double max = dcheck.getMax();
-	double xmax = v.getMax();
-	printf("\trel. error max = %8.4g\n", max/xmax);
-	memdriver.setStackMode(false);
-	return (cnorm < xnorm*eps_norm);
-}
-
-/**********************************************************/
-/*   sub classes declarations                             */
-/**********************************************************/
-
-class PureTriangTest : public TestRunnable {
-public:
-	PureTriangTest() : TestRunnable("pure triangular solve (5)") {}
-	bool run() const;
-};
-
-class PureTriangTransTest : public TestRunnable {
-public:
-	PureTriangTransTest() : TestRunnable("pure triangular solve trans (5)") {}
-	bool run() const;
-};
-
-class PureTrLargeTest : public TestRunnable {
-public:
-	PureTrLargeTest() : TestRunnable("pure triangular large solve (300)") {}
-	bool run() const;
-};
-
-class PureTrLargeTransTest : public TestRunnable {
-public:
-	PureTrLargeTransTest() : TestRunnable("pure triangular large solve trans (300)") {}
-	bool run() const;
-};
-
-class QuasiTriangTest : public TestRunnable {
-public:
-	QuasiTriangTest() : TestRunnable("quasi triangular solve (7)") {}
-	bool run() const;
-};
-
-class QuasiTriangTransTest : public TestRunnable {
-public:
-	QuasiTriangTransTest() : TestRunnable("quasi triangular solve trans (7)") {}
-	bool run() const;
-};
-
-class QuasiTrLargeTest : public TestRunnable {
-public:
-	QuasiTrLargeTest() : TestRunnable("quasi triangular solve large (250)") {}
-	bool run() const;
-};
-
-class QuasiTrLargeTransTest : public TestRunnable {
-public:
-	QuasiTrLargeTransTest() : TestRunnable("quasi triangular solve large trans (250)") {}
-	bool run() const;
-};
-
-class QuasiZeroSmallTest : public TestRunnable {
-public:
-	QuasiZeroSmallTest() : TestRunnable("quasi tr. zero small test (2x1)") {}
-	bool run() const;
-};
-
-class MultKronSmallTest : public TestRunnable {
-public:
-	MultKronSmallTest() : TestRunnable("kronecker small mult (2=2x1)") {}
-	bool run() const;
-};
-
-class MultKronTest : public TestRunnable {
-public:
-	MultKronTest() : TestRunnable("kronecker mult (245=7x7x5)") {}
-	bool run() const;
-};
-
-class MultKronSmallTransTest : public TestRunnable {
-public:
-	MultKronSmallTransTest() : TestRunnable("kronecker small trans mult (2=2x1)") {}
-	bool run() const;
-};
-
-class MultKronTransTest : public TestRunnable {
-public:
-	MultKronTransTest() : TestRunnable("kronecker trans mult (245=7x7x5)") {}
-	bool run() const;
-};
-
-class LevelKronTest : public TestRunnable {
-public:
-	LevelKronTest() : TestRunnable("kronecker level mult (1715=7x[7]x7x5)") {}
-	bool run() const;
-};
-
-class LevelKronTransTest : public TestRunnable {
-public:
-	LevelKronTransTest() : TestRunnable("kronecker level trans mult (1715=7x[7]x7x5)") {}
-	bool run() const;
-};
-
-class LevelZeroKronTest : public TestRunnable {
-public:
-	LevelZeroKronTest() : TestRunnable("kronecker level mult (1715=7x7x7x[5])") {}
-	bool run() const;
-};
-
-class LevelZeroKronTransTest : public TestRunnable {
-public:
-	LevelZeroKronTransTest() : TestRunnable("kronecker level trans mult (1715=7x7x7x[5])") {}
-	bool run() const;
-};
-
-class KronPowerTest : public TestRunnable {
-public:
-	KronPowerTest() : TestRunnable("kronecker power mult (1715=7x7x7x5)") {}
-	bool run() const;
-};
-
-class SmallLinEvalTest : public TestRunnable {
-public:
-	SmallLinEvalTest() : TestRunnable("lin eval (24=2 x 2x2x3)") {}
-	bool run() const;
-};
-
-class LinEvalTest : public TestRunnable {
-public:
-	LinEvalTest() : TestRunnable("lin eval (490=2 x 7x7x5)") {}
-	bool run() const;
-};
-
-class SmallQuaEvalTest : public TestRunnable {
-public:
-	SmallQuaEvalTest() : TestRunnable("qua eval (24=2 x 2x2x3)") {}
-	bool run() const;
-};
-
-class QuaEvalTest : public TestRunnable {
-public:
-	QuaEvalTest() : TestRunnable("qua eval (490=2 x 7x7x5)") {}
-	bool run() const;
-};
-
-class TriSylvSmallRealTest : public TestRunnable {
-public:
-	TriSylvSmallRealTest() : TestRunnable("triangular sylvester small real solve (12=2x2x3)") {}
-	bool run() const;
-};
-
-class TriSylvSmallComplexTest : public TestRunnable {
-public:
-	TriSylvSmallComplexTest() : TestRunnable("triangular sylvester small complx solve (12=2x2x3)") {}
-	bool run() const;
-};
-
-class TriSylvTest : public TestRunnable {
-public:
-	TriSylvTest() : TestRunnable("triangular sylvester solve (245=7x7x5)") {}
-	bool run() const;
-};
-
-class TriSylvBigTest : public TestRunnable {
-public:
-	TriSylvBigTest() : TestRunnable("triangular sylvester big solve (48000=40x40x30)") {}
-	bool run() const;
-};
-
-class TriSylvLargeTest : public TestRunnable {
-public:
-	TriSylvLargeTest() : TestRunnable("triangular sylvester large solve (1920000=40x40x40x30)") {}
-	bool run() const;
-};
-
-class IterSylvTest : public TestRunnable {
-public:
-	IterSylvTest() : TestRunnable("iterative sylvester solve (245=7x7x5)") {}
-	bool run() const;
-};
-
-class IterSylvLargeTest : public TestRunnable {
-public:
-	IterSylvLargeTest() : TestRunnable("iterative sylvester large solve (1920000=40x40x40x30)") {}
-	bool run() const;
-};
-
-class GenSylvSmallTest : public TestRunnable {
-public:
-	GenSylvSmallTest() : TestRunnable("general sylvester small solve (18=3x3x2)") {}
-	bool run() const;
-};
-
-class GenSylvTest : public TestRunnable {
-public:
-	GenSylvTest() : TestRunnable("general sylvester solve (12000=20x20x30)") {}
-	bool run() const;
-};
-
-class GenSylvSingTest : public TestRunnable {
-public:
-	GenSylvSingTest() : TestRunnable("general sylvester solve for sing. C (2500000=50x50x50x20)") {}
-	bool run() const;
-};
-
-class GenSylvLargeTest : public TestRunnable {
-public:
-	GenSylvLargeTest() : TestRunnable("general sylvester solve (2500000=50x50x50x20)") {}
-	bool run() const;
-};
-
-class EigBubFrankTest : public TestRunnable {
-public:
-	EigBubFrankTest() : TestRunnable("eig. bubble frank test (12x12)") {}
-	bool run() const;
-};
-
-class EigBubSplitTest : public TestRunnable {
-// complex eigenvalue is split by swapping it with real
-public:
-	EigBubSplitTest() : TestRunnable("eig. bubble complex split test (3x3)") {}
-	bool run() const;
-};
-
-class EigBubSameTest : public TestRunnable {
-// complex eigenevalue bypasses the same complex eigenvalue
-public:
-	EigBubSameTest() : TestRunnable("eig. bubble same test (5x5)") {}
-	bool run() const;
-};
-
-class BlockDiagSmallTest : public TestRunnable {
-public:
-	BlockDiagSmallTest() : TestRunnable("block diagonalization small test (7x7)") {}
-	bool run() const;
-};
-
-class BlockDiagFrankTest : public TestRunnable {
-public:
-	BlockDiagFrankTest() : TestRunnable("block diagonalization of frank (12x12)") {}
-	bool run() const;
-};
-
-class BlockDiagIllCondTest : public TestRunnable {
-public:
-	BlockDiagIllCondTest() : TestRunnable("block diagonalization of ill conditioned (15x15)") {}
-	bool run() const;
-};
-
-class BlockDiagBigTest : public TestRunnable {
-public:
-	BlockDiagBigTest() : TestRunnable("block diagonalization big test (50x50)") {}
-	bool run() const;
-};
-
-/**********************************************************/
-/*   run methods of sub classes                           */
-/**********************************************************/
-
-bool PureTriangTest::run() const
-{
-	return quasi_solve(false, "tr5x5.mm", "v5.mm");
-}
-
-bool PureTriangTransTest::run() const
-{
-	return quasi_solve(true, "tr5x5.mm", "v5.mm");
-}
-
-bool PureTrLargeTest::run() const
-{
-	return quasi_solve(false, "tr300x300.mm", "v300.mm");
-}
-
-bool PureTrLargeTransTest::run() const
-{
-	return quasi_solve(true, "tr300x300.mm", "v300.mm");
-}
-
-bool QuasiTriangTest::run() const
-{
-	return quasi_solve(false, "qt7x7.mm", "v7.mm");
-}
-
-bool QuasiTriangTransTest::run() const
-{
-	return quasi_solve(true, "qt7x7.mm", "v7.mm");
-}
-
-bool QuasiTrLargeTest::run() const
-{
-	return quasi_solve(false, "qt250x250.mm", "v250.mm");
-}
-
-bool QuasiTrLargeTransTest::run() const
-{
-	return quasi_solve(true, "qt250x250.mm", "v250.mm");
-}
-
-bool QuasiZeroSmallTest::run() const
-{
-	return quasi_solve(false, "b2x1.mm", "v2.mm");
-}
-
-bool MultKronSmallTest::run() const
-{
-	return mult_kron(false, "tr2x2.mm", "v2.mm", "vcheck2.mm", 2, 1, 1);
-}
-
-bool MultKronTest::run() const
-{
-	return mult_kron(false, "qt7x7.mm", "v245.mm", "vcheck245.mm", 7, 5, 2);
-}
-
-bool MultKronSmallTransTest::run() const
-{
-	return mult_kron(true, "tr2x2.mm", "v2.mm", "vcheck2a.mm", 2, 1, 1);
-}
-
-bool MultKronTransTest::run() const
-{
-	return mult_kron(true, "qt7x7.mm", "v245.mm", "vcheck245a.mm", 7, 5, 2);
-}
-
-bool LevelKronTest::run() const
-{
-	return level_kron(false, "qt7x7.mm", "v1715.mm", "vcheck1715.mm", 2, 7, 5, 3);
-}
-
-bool LevelKronTransTest::run() const
-{
-	return level_kron(true, "qt7x7.mm", "v1715.mm", "vcheck1715a.mm", 2, 7, 5, 3);
-}
-
-bool LevelZeroKronTest::run() const
-{
-	return level_kron(false, "tr5x5.mm", "v1715.mm", "vcheck1715b.mm", 0, 7, 5, 3);
-}
-
-bool LevelZeroKronTransTest::run() const
-{
-	return level_kron(true, "tr5x5.mm", "v1715.mm", "vcheck1715c.mm", 0, 7, 5, 3);
-}
-
-bool KronPowerTest::run() const
-{
-	return kron_power("qt7x7.mm", "tr5x5.mm", "v1715.mm", "vcheck1715d.mm", 7, 5, 3);
-}
-
-bool SmallLinEvalTest::run() const
-{
-	return lin_eval("qt2x2.mm", "qt3x3.mm", "v24.mm", "vcheck24.mm", 2, 3, 2,
-					 2, 1, 3);
-}
-
-bool LinEvalTest::run() const
-{
-	return lin_eval("qt7x7.mm", "tr5x5.mm", "v490.mm", "vcheck490.mm", 7, 5, 2,
-					 2, 1, 3);
-}
-
-bool SmallQuaEvalTest::run() const
-{
-	return qua_eval("qt2x2.mm", "qt3x3.mm", "v24.mm", "vcheck24q.mm", 2, 3, 2,
-					 -0.5, 3, 2, 1, 3);
-}
-
-bool QuaEvalTest::run() const
-{
-	return qua_eval("qt7x7.mm", "tr5x5.mm", "v490.mm", "vcheck490q.mm", 7, 5, 2,
-					 -0.5, 3, 2, 1, 3);
-}
-
-bool TriSylvSmallRealTest::run() const
-{
-	return tri_sylv("tr2x2.mm", "qt3x3.mm", "v12r.mm", 2, 3, 2);
-}
-
-bool TriSylvSmallComplexTest::run() const
-{
-	return tri_sylv("qt2x2.mm", "qt3x3.mm", "v12r.mm", 2, 3, 2);
-}
-
-bool TriSylvTest::run() const
-{
-	return tri_sylv("qt7x7eig06-09.mm", "tr5x5.mm", "v245r.mm", 7, 5, 2);
-}
-
-bool TriSylvBigTest::run() const
-{
-	return tri_sylv("qt40x40.mm", "qt30x30eig011-095.mm", "v48000.mm", 40, 30, 2);
-}
-
-bool TriSylvLargeTest::run() const
-{
-	return tri_sylv("qt40x40.mm", "qt30x30eig011-095.mm", "v1920000.mm", 40, 30, 3);
-}
-
-bool IterSylvTest::run() const
-{
-	return iter_sylv("qt7x7eig06-09.mm", "qt5x5.mm", "v245r.mm", 7, 5, 2);
-}
-
-bool IterSylvLargeTest::run() const
-{
-	return iter_sylv("qt40x40.mm", "qt30x30eig011-095.mm", "v1920000.mm", 40, 30, 3);
-}
-
-bool GenSylvSmallTest::run() const
-{
-	return gen_sylv("a2x2.mm", "b2x1.mm", "c3x3.mm", "d2x9.mm", 3, 2, 2);
-}
-
-bool GenSylvTest::run() const
-{
-	return gen_sylv("a30x30.mm", "b30x25.mm", "c20x20.mm", "d30x400.mm", 20, 30, 2);
-}
-
-bool GenSylvSingTest::run() const
-{
-	return gen_sylv("a20x20.mm", "b20x4.mm", "c50x50sing.mm", "d20x125000.mm", 50, 20, 3);
-}
-
-bool GenSylvLargeTest::run() const
-{
-	return gen_sylv("a20x20.mm", "b20x15.mm", "c50x50.mm", "d20x125000.mm", 50, 20, 3);
-}
-
-bool EigBubFrankTest::run() const
-{
-	return eig_bubble("qt_frank12x12.mm", 8, 0);
-}
-
-bool EigBubSplitTest::run() const
-{
-	return eig_bubble("qt_eps3x3.mm",1,0);
-}
-
-bool EigBubSameTest::run() const
-{
-	return eig_bubble("qt5x5.mm",2,0);
-}
-
-bool BlockDiagSmallTest::run() const
-{
-	return block_diag("qt7x7.mm", 0.1);
-}
-
-bool BlockDiagFrankTest::run() const
-{
-	return block_diag("qt_frank12x12.mm", 5);
-}
-
-bool BlockDiagIllCondTest::run() const
-{
-	return block_diag("ill_cond15x15.mm", 4.14);
-}
-
-bool BlockDiagBigTest::run() const
-{
-	return block_diag("c50x50.mm", 1.3);
-}
-
-/**********************************************************/
-/*   main                                                 */
-/**********************************************************/
-
-int main()
-{
-	TestRunnable* all_tests[50];
-	// fill in vector of all tests
-	int num_tests = 0;
-	all_tests[num_tests++] = new PureTriangTest();
-	all_tests[num_tests++] = new PureTriangTransTest();
-	all_tests[num_tests++] = new PureTrLargeTest();
-	all_tests[num_tests++] = new PureTrLargeTransTest();
-	all_tests[num_tests++] = new QuasiTriangTest();
-	all_tests[num_tests++] = new QuasiTriangTransTest();
-	all_tests[num_tests++] = new QuasiTrLargeTest();
-	all_tests[num_tests++] = new QuasiTrLargeTransTest();
-	all_tests[num_tests++] = new QuasiZeroSmallTest();
-	all_tests[num_tests++] = new MultKronSmallTest();
-	all_tests[num_tests++] = new MultKronTest();
-	all_tests[num_tests++] = new MultKronSmallTransTest();
-	all_tests[num_tests++] = new MultKronTransTest();
-	all_tests[num_tests++] = new LevelKronTest();
-	all_tests[num_tests++] = new LevelKronTransTest();
-	all_tests[num_tests++] = new LevelZeroKronTest();
-	all_tests[num_tests++] = new LevelZeroKronTransTest();
-	all_tests[num_tests++] = new KronPowerTest();
-	all_tests[num_tests++] = new SmallLinEvalTest();
-	all_tests[num_tests++] = new LinEvalTest();
-	all_tests[num_tests++] = new SmallQuaEvalTest();
-	all_tests[num_tests++] = new QuaEvalTest();
-	all_tests[num_tests++] = new EigBubFrankTest();
-	all_tests[num_tests++] = new EigBubSplitTest();
-	all_tests[num_tests++] = new EigBubSameTest();
-	all_tests[num_tests++] = new BlockDiagSmallTest();
-	all_tests[num_tests++] = new BlockDiagFrankTest();
-	all_tests[num_tests++] = new BlockDiagIllCondTest();
-	all_tests[num_tests++] = new BlockDiagBigTest();
-	all_tests[num_tests++] = new TriSylvSmallRealTest();
-	all_tests[num_tests++] = new TriSylvSmallComplexTest();
-	all_tests[num_tests++] = new TriSylvTest();
-	all_tests[num_tests++] = new TriSylvBigTest();
-	all_tests[num_tests++] = new TriSylvLargeTest();
-	all_tests[num_tests++] = new IterSylvTest();
-	all_tests[num_tests++] = new IterSylvLargeTest();
-	all_tests[num_tests++] = new GenSylvSmallTest();
-	all_tests[num_tests++] = new GenSylvTest();
-	all_tests[num_tests++] = new GenSylvSingTest();
-	all_tests[num_tests++] = new GenSylvLargeTest();
-
-	// launch the tests
-	int success = 0;
-	for (int i = 0; i < num_tests; i++) {
-		try {
-			if (all_tests[i]->test())
-				success++;
-		} catch (const MMException& e) {
-			printf("Caugth MM exception in <%s>:\n%s", all_tests[i]->getName(),
-				   e.getMessage());
-		} catch (SylvException& e) {
-			printf("Caught Sylv exception in %s:\n", all_tests[i]->getName());
-			e.printMessage();
-		}
-	}
-
-	printf("There were %d tests that failed out of %d tests run.\n",
-		   num_tests - success, num_tests);
-
-	// destroy
-	for (int i = 0; i < num_tests; i++) {
-		delete all_tests[i];
-	}
-
-	return 0;
-}
-
diff --git a/dynare++/tl/cc/pyramid_prod2.hh b/dynare++/tl/cc/pyramid_prod2.hh
index 5594cf063227ab01aabc568a612be5d378cf2327..2dce7e1c5ead50f6a882770033c1f4f924f8210a 100644
--- a/dynare++/tl/cc/pyramid_prod2.hh
+++ b/dynare++/tl/cc/pyramid_prod2.hh
@@ -74,7 +74,7 @@
 #include "rfs_tensor.hh"
 #include "stack_container.hh"
 
-#include "Vector.h"
+#include "Vector.hh"
 
 /* First we declare a helper class for the tensor. Its purpose is to
    gather the columns which are going to be Kronecker multiplied. The
diff --git a/dynare++/tl/cc/sparse_tensor.hh b/dynare++/tl/cc/sparse_tensor.hh
index 1b61d7ef856283ab6db2e198d8c7e8ec72762092..deceaace354c26b77ca400e080efc7baa9a172a9 100644
--- a/dynare++/tl/cc/sparse_tensor.hh
+++ b/dynare++/tl/cc/sparse_tensor.hh
@@ -27,7 +27,7 @@
 #include "symmetry.hh"
 #include "tensor.hh"
 #include "gs_tensor.hh"
-#include "Vector.h"
+#include "Vector.hh"
 
 #include <map>
 
diff --git a/dynare++/tl/cc/t_container.hh b/dynare++/tl/cc/t_container.hh
index 07c6e7b98a92cb74ddca36fbd3b784d5b324655c..96aa76194a1d69f9bcacad1d164c4eadc4da93ed 100644
--- a/dynare++/tl/cc/t_container.hh
+++ b/dynare++/tl/cc/t_container.hh
@@ -54,7 +54,7 @@
 #include "sparse_tensor.hh"
 #include "equivalence.hh"
 #include "rfs_tensor.hh"
-#include "Vector.h"
+#include "Vector.hh"
 
 #include <map>
 #include <string>
diff --git a/dynare++/tl/cc/twod_matrix.hh b/dynare++/tl/cc/twod_matrix.hh
index 90d9591d77f6a6fcfb99ebd6cec97fcc63ee5b5c..03b5b659b2751bf33c13d25c0c6490afd27b9e77 100644
--- a/dynare++/tl/cc/twod_matrix.hh
+++ b/dynare++/tl/cc/twod_matrix.hh
@@ -15,7 +15,7 @@
 #ifndef TWOD_MATRIX_H
 #define TWOD_MATRIX_H
 
-#include "GeneralMatrix.h"
+#include "GeneralMatrix.hh"
 
 #include <cstdio>
 #include <matio.h>
diff --git a/dynare++/tl/testing/monoms.hh b/dynare++/tl/testing/monoms.hh
index 86707e3bd47d261a4c081ad5d97afdc0acc10711..684c9d4f6e54f0d38a9d51a44148f85c91ee460e 100644
--- a/dynare++/tl/testing/monoms.hh
+++ b/dynare++/tl/testing/monoms.hh
@@ -8,7 +8,7 @@
 #include "gs_tensor.hh"
 #include "t_container.hh"
 #include "sparse_tensor.hh"
-#include "Vector.h"
+#include "Vector.hh"
 
 class IntGenerator
 {
diff --git a/dynare++/tl/testing/tests.cc b/dynare++/tl/testing/tests.cc
index d989481cb135681833bbe747a0ea1975132ce8ca..9f751ecef84da807c0cbb9f3f62477bc30adee3a 100644
--- a/dynare++/tl/testing/tests.cc
+++ b/dynare++/tl/testing/tests.cc
@@ -1,7 +1,7 @@
 /* $Id: tests.cpp 148 2005-04-19 15:12:26Z kamenik $ */
 /* Copyright 2004, Ondra Kamenik */
 
-#include "SylvException.h"
+#include "SylvException.hh"
 #include "tl_exception.hh"
 #include "gs_tensor.hh"
 #include "factory.hh"
diff --git a/dynare++/utils/cc/Makefile.am b/dynare++/utils/cc/Makefile.am
index 91c1a091db60599e713514eaee70e2eb2e97af87..220db615c8b8cb5aeaec624f3853f256460b0d6c 100644
--- a/dynare++/utils/cc/Makefile.am
+++ b/dynare++/utils/cc/Makefile.am
@@ -1,8 +1,8 @@
 noinst_LIBRARIES = libutils.a
 
 libutils_a_SOURCES = \
-	exception.h \
-	memory_file.cpp \
-	memory_file.h \
-	pascal_triangle.cpp \
-	pascal_triangle.h
+	exception.hh \
+	memory_file.cc \
+	memory_file.hh \
+	pascal_triangle.cc \
+	pascal_triangle.hh
diff --git a/dynare++/utils/cc/exception.h b/dynare++/utils/cc/exception.hh
similarity index 100%
rename from dynare++/utils/cc/exception.h
rename to dynare++/utils/cc/exception.hh
diff --git a/dynare++/utils/cc/memory_file.cc b/dynare++/utils/cc/memory_file.cc
new file mode 100644
index 0000000000000000000000000000000000000000..9c8967ffe71953b685cde0a76967ee27f00f3112
--- /dev/null
+++ b/dynare++/utils/cc/memory_file.cc
@@ -0,0 +1,71 @@
+// Copyright (C) 2005, Ondra Kamenik
+
+// $Id: memory_file.cpp 987 2006-10-17 14:39:19Z kamenik $
+
+#include "memory_file.hh"
+
+#include <cstdio>
+
+using namespace ogu;
+
+int
+ogu::calc_pos_offset(int length, const char *str, int line, int col)
+{
+  int i = 0;
+  int il = 1;
+  int ic = 1;
+  while (i < length && il <= line && ic <= col)
+    {
+      if (str[i] == '\n')
+        {
+          il++;
+          ic = 1;
+        }
+      else
+        {
+          ic++;
+        }
+    }
+  return i;
+}
+
+void
+ogu::calc_pos_line_and_col(int length, const char *str, int offset,
+                           int &line, int &col)
+{
+  line = 1;
+  col = 0;
+  int i = 0;
+  while (i < length && i < offset)
+    {
+      if (str[i] == '\n')
+        {
+          line++;
+          col = 0;
+        }
+      i++;
+      col++;
+    }
+}
+
+MemoryFile::MemoryFile(const char *fname)
+  : len(-1), data(NULL)
+{
+  FILE *fd = fopen(fname, "rb");
+  if (fd)
+    {
+      // get the file size
+      fseek(fd, 0, SEEK_END);
+      len = ftell(fd);
+      // allocate space for the file plus ending '\0' character
+      data = new char[len+1];
+      // read file and set data
+      fseek(fd, 0, SEEK_SET);
+      int i = 0;
+      int c;
+      while (EOF != (c = fgetc(fd)))
+        data[i++] = (unsigned char) c;
+      data[len] = '\0';
+      fclose(fd);
+    }
+}
diff --git a/dynare++/utils/cc/memory_file.cpp b/dynare++/utils/cc/memory_file.cpp
deleted file mode 100644
index 5e147af56fda05dc8ff8dd9f33bdc8b59db7da41..0000000000000000000000000000000000000000
--- a/dynare++/utils/cc/memory_file.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (C) 2005, Ondra Kamenik
-
-// $Id: memory_file.cpp 987 2006-10-17 14:39:19Z kamenik $
-
-#include "memory_file.h"
-
-#include <cstdio>
-
-using namespace ogu;
-
-int ogu::calc_pos_offset(int length, const char* str, int line, int col)
-{
-	int i = 0;
-	int il = 1;
-	int ic = 1;
-	while (i < length && il <= line && ic <= col) {
-		if (str[i] == '\n') {
-			il++;
-			ic = 1;
-		} else {
-			ic++;
-		}
-	}
-	return i;
-}
-
-void ogu::calc_pos_line_and_col(int length, const char* str, int offset,
-						   int& line, int& col)
-{
-	line = 1;
-	col = 0;
-	int i = 0;
-	while (i < length && i < offset) {
-		if (str[i] == '\n') {
-			line++;
-			col = 0;
-		}
-		i++;
-		col++;
-	}
-}
-
-MemoryFile::MemoryFile(const char* fname)
-	: len(-1), data(NULL)
-{
-	FILE* fd = fopen(fname, "rb");
-	if (fd) {
-		// get the file size
-		fseek(fd, 0, SEEK_END);
-		len = ftell(fd);
-		// allocate space for the file plus ending '\0' character
-		data = new char[len+1];
-		// read file and set data
-		fseek(fd, 0, SEEK_SET);
-		int i = 0;
-		int c;
-		while (EOF != (c = fgetc(fd)))
-			data[i++] = (unsigned char)c;
-		data[len] = '\0';
-		fclose(fd);
-	}
-}
diff --git a/dynare++/utils/cc/memory_file.h b/dynare++/utils/cc/memory_file.hh
similarity index 100%
rename from dynare++/utils/cc/memory_file.h
rename to dynare++/utils/cc/memory_file.hh
diff --git a/dynare++/utils/cc/pascal_triangle.cc b/dynare++/utils/cc/pascal_triangle.cc
new file mode 100644
index 0000000000000000000000000000000000000000..c64db047da9ed700ced276e30c67fea310f722ce
--- /dev/null
+++ b/dynare++/utils/cc/pascal_triangle.cc
@@ -0,0 +1,101 @@
+#include "pascal_triangle.hh"
+#include <cstdio>
+
+using namespace ogu;
+
+PascalTriangle ptriang;
+
+void
+PascalRow::setFromPrevious(const PascalRow &prev)
+{
+  k = prev.k + 1;
+  clear();
+  prolong(prev);
+}
+
+/** This prolongs the PascalRow. If it is empty, we set the first item
+ * to k+1, which is noverk(k+1,k) which is the second item in the real
+ * pascal row, which starts from noverk(k,k)=1. Then we calculate
+ * other items from the provided row which must be the one with k-1.*/
+void
+PascalRow::prolong(const PascalRow &prev)
+{
+  if (size() == 0)
+    push_back(k+1);
+  int last = back();
+  for (unsigned int i = size(); i < prev.size(); i++)
+    {
+      last += prev[i];
+      push_back(last);
+    }
+}
+
+void
+PascalRow::prolongFirst(int n)
+{
+  // todo: check n = 1;
+  for (int i = (int) size()+2; i <= n; i++)
+    push_back(i);
+}
+
+void
+PascalRow::print() const
+{
+  printf("k=%d\n", k);
+  for (unsigned int i = 0; i < size(); i++)
+    printf("%d ", operator[](i));
+  printf("\n");
+}
+
+int
+PascalTriangle::max_n() const
+{
+  return (int) (tr[0].size()+1);
+}
+
+int
+PascalTriangle::max_k() const
+{
+  return (int) tr.size();
+}
+
+void
+PascalTriangle::ensure(int n, int k)
+{
+  // add along n
+  if (n > max_n())
+    {
+      tr[0].prolongFirst(n);
+      for (int i = 2; i <= max_k(); i++)
+        tr[i-1].prolong(tr[i-2]);
+    }
+
+  if (k > max_k())
+    {
+      for (int i = max_k()+1; i <= k; i++)
+        {
+          PascalRow r;
+          tr.push_back(r);
+          tr.back().setFromPrevious(tr[i-2]);
+        }
+    }
+}
+
+int
+PascalTriangle::noverk(int n, int k)
+{
+  // todo: rais if out of bounds
+  if (n-k < k)
+    k = n-k;
+  if (k == 0)
+    return 1;
+  ensure(n, k);
+  return (tr[k-1])[n-1-k];
+}
+
+void
+PascalTriangle::print() const
+{
+  for (unsigned int i = 0; i < tr.size(); i++)
+    tr[i].print();
+}
diff --git a/dynare++/utils/cc/pascal_triangle.cpp b/dynare++/utils/cc/pascal_triangle.cpp
deleted file mode 100644
index 1dc4c09d65fa98f1d699e789129360e76f6b8b01..0000000000000000000000000000000000000000
--- a/dynare++/utils/cc/pascal_triangle.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-#include "pascal_triangle.h"
-#include <cstdio>
-
-using namespace ogu;
-
-PascalTriangle ptriang;
-
-void PascalRow::setFromPrevious(const PascalRow& prev)
-{
-	k = prev.k + 1;
-	clear();
-	prolong(prev);
-}
-
-/** This prolongs the PascalRow. If it is empty, we set the first item
- * to k+1, which is noverk(k+1,k) which is the second item in the real
- * pascal row, which starts from noverk(k,k)=1. Then we calculate
- * other items from the provided row which must be the one with k-1.*/
-void PascalRow::prolong(const PascalRow& prev)
-{
-	if (size() == 0)
-		push_back(k+1);
-	int last = back();
-	for (unsigned int i = size(); i < prev.size(); i++) {
-		last += prev[i];
-		push_back(last);
-	}
-}
-
-void PascalRow::prolongFirst(int n)
-{
-	// todo: check n = 1;
-	for (int i = (int)size()+2; i <= n; i++)
-		push_back(i);
-}
-
-void PascalRow::print() const
-{
-	printf("k=%d\n",k);
-	for (unsigned int i = 0; i < size(); i++)
-		printf("%d ",operator[](i));
-	printf("\n");
-}
-
-int PascalTriangle::max_n() const
-{
-	return (int)(tr[0].size()+1);
-}
-
-int PascalTriangle::max_k() const
-{
-	return (int)tr.size();
-}
-
-void PascalTriangle::ensure(int n, int k)
-{
-	// add along n
-	if (n > max_n()) {
-		tr[0].prolongFirst(n);
-		for (int i = 2; i <= max_k(); i++)
-			tr[i-1].prolong(tr[i-2]);
-	}
-
-	if (k > max_k()) {
-		for (int i = max_k()+1; i <= k; i++) {
-			PascalRow r;
-			tr.push_back(r);
-			tr.back().setFromPrevious(tr[i-2]);
-		}
-	}
-}
-
-int PascalTriangle::noverk(int n, int k)
-{
-	// todo: rais if out of bounds
-	if (n-k < k)
-		k = n-k;
-	if (k == 0)
-		return 1;
-	ensure(n, k);
-	return (tr[k-1])[n-1-k];
-}
-
-void PascalTriangle::print() const
-{
-	for (unsigned int i = 0; i < tr.size(); i++)
-		tr[i].print();
-}
diff --git a/dynare++/utils/cc/pascal_triangle.h b/dynare++/utils/cc/pascal_triangle.hh
similarity index 100%
rename from dynare++/utils/cc/pascal_triangle.h
rename to dynare++/utils/cc/pascal_triangle.hh
diff --git a/mex/build/dynare_simul_.am b/mex/build/dynare_simul_.am
index 3d64b6bc4e5679d5a0d123fdbf3bbcb572f1b4d8..05716b9a26fb10cc80565668beecdbc92740fb36 100644
--- a/mex/build/dynare_simul_.am
+++ b/mex/build/dynare_simul_.am
@@ -8,4 +8,4 @@ dynare_simul__CXXFLAGS = $(AM_CXXFLAGS) $(PTHREAD_CFLAGS)
 dynare_simul__LDFLAGS = $(AM_LDFLAGS) $(LDFLAGS_MATIO)
 dynare_simul__LDADD = ../libdynare++/libdynare++.a $(PTHREAD_LIBS) $(LIBADD_MATIO)
 
-nodist_dynare_simul__SOURCES = $(top_srcdir)/../../../dynare++/extern/matlab/dynare_simul.cpp
+nodist_dynare_simul__SOURCES = $(top_srcdir)/../../../dynare++/extern/matlab/dynare_simul.cc
diff --git a/mex/build/gensylv.am b/mex/build/gensylv.am
index 0c20ea7e5ae3dd44414b3d0b4f8fa2be7c7f05d9..ee45a519b3cac51716448bd6a16d12c0a3eeb444 100644
--- a/mex/build/gensylv.am
+++ b/mex/build/gensylv.am
@@ -4,4 +4,4 @@ gensylv_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/../../../dynare++/sylv/cc -I$(
 
 gensylv_LDADD = ../libdynare++/libdynare++.a
 
-nodist_gensylv_SOURCES = $(top_srcdir)/../../../dynare++/sylv/matlab/gensylv.cpp
+nodist_gensylv_SOURCES = $(top_srcdir)/../../../dynare++/sylv/matlab/gensylv.cc
diff --git a/mex/build/libdynare++.am b/mex/build/libdynare++.am
index 0ee183beb1f88df85546bb29af1f5e4dc4f7369f..8c9f87fc5c1c1a5057d139481f56239eb48b66af 100644
--- a/mex/build/libdynare++.am
+++ b/mex/build/libdynare++.am
@@ -33,24 +33,43 @@ KORD_SRCS = \
 	$(TOPDIR)/kord/random.hh
 
 SYLV_SRCS = \
-	$(TOPDIR)/sylv/cc/IterativeSylvester.cpp \
-	$(TOPDIR)/sylv/cc/QuasiTriangular.cpp \
-	$(TOPDIR)/sylv/cc/QuasiTriangularZero.cpp \
-	$(TOPDIR)/sylv/cc/GeneralMatrix.cpp \
-	$(TOPDIR)/sylv/cc/GeneralSylvester.cpp \
-	$(TOPDIR)/sylv/cc/SimilarityDecomp.cpp \
-	$(TOPDIR)/sylv/cc/SylvException.cpp \
-	$(TOPDIR)/sylv/cc/SchurDecompEig.cpp \
-	$(TOPDIR)/sylv/cc/Vector.cpp \
-	$(TOPDIR)/sylv/cc/TriangularSylvester.cpp \
-	$(TOPDIR)/sylv/cc/SylvParams.cpp \
-	$(TOPDIR)/sylv/cc/BlockDiagonal.cpp \
-	$(TOPDIR)/sylv/cc/KronVector.cpp \
-	$(TOPDIR)/sylv/cc/SylvMemory.cpp \
-	$(TOPDIR)/sylv/cc/SymSchurDecomp.cpp \
-	$(TOPDIR)/sylv/cc/SylvMatrix.cpp \
-	$(TOPDIR)/sylv/cc/SchurDecomp.cpp \
-	$(TOPDIR)/sylv/cc/KronUtils.cpp
+	$(TOPDIR)/sylv/cc/BlockDiagonal.cc \
+	$(TOPDIR)/sylv/cc/BlockDiagonal.hh \
+	$(TOPDIR)/sylv/cc/GeneralMatrix.cc \
+	$(TOPDIR)/sylv/cc/GeneralMatrix.hh \
+	$(TOPDIR)/sylv/cc/GeneralSylvester.cc \
+	$(TOPDIR)/sylv/cc/GeneralSylvester.hh \
+	$(TOPDIR)/sylv/cc/IterativeSylvester.cc \
+	$(TOPDIR)/sylv/cc/IterativeSylvester.hh \
+	$(TOPDIR)/sylv/cc/KronUtils.cc \
+	$(TOPDIR)/sylv/cc/KronUtils.hh \
+	$(TOPDIR)/sylv/cc/KronVector.cc \
+	$(TOPDIR)/sylv/cc/KronVector.hh \
+	$(TOPDIR)/sylv/cc/QuasiTriangular.cc \
+	$(TOPDIR)/sylv/cc/QuasiTriangular.hh \
+	$(TOPDIR)/sylv/cc/QuasiTriangularZero.cc \
+	$(TOPDIR)/sylv/cc/QuasiTriangularZero.hh \
+	$(TOPDIR)/sylv/cc/SchurDecomp.cc \
+	$(TOPDIR)/sylv/cc/SchurDecomp.hh \
+	$(TOPDIR)/sylv/cc/SchurDecompEig.cc \
+	$(TOPDIR)/sylv/cc/SchurDecompEig.hh \
+	$(TOPDIR)/sylv/cc/SimilarityDecomp.cc \
+	$(TOPDIR)/sylv/cc/SimilarityDecomp.hh \
+	$(TOPDIR)/sylv/cc/SylvException.cc \
+	$(TOPDIR)/sylv/cc/SylvException.hh \
+	$(TOPDIR)/sylv/cc/SylvMatrix.cc \
+	$(TOPDIR)/sylv/cc/SylvMatrix.hh \
+	$(TOPDIR)/sylv/cc/SylvMemory.cc \
+	$(TOPDIR)/sylv/cc/SylvMemory.hh \
+	$(TOPDIR)/sylv/cc/SylvParams.cc \
+	$(TOPDIR)/sylv/cc/SylvParams.hh \
+	$(TOPDIR)/sylv/cc/SylvesterSolver.hh \
+	$(TOPDIR)/sylv/cc/SymSchurDecomp.cc \
+	$(TOPDIR)/sylv/cc/SymSchurDecomp.hh \
+	$(TOPDIR)/sylv/cc/TriangularSylvester.cc \
+	$(TOPDIR)/sylv/cc/TriangularSylvester.hh \
+	$(TOPDIR)/sylv/cc/Vector.cc \
+	$(TOPDIR)/sylv/cc/Vector.hh
 
 TL_SRCS = \
 	$(TOPDIR)/tl/cc/equivalence.cc \
@@ -114,4 +133,5 @@ nodist_libdynare___a_SOURCES = \
 	$(TL_SRCS) \
 	$(SYLV_SRCS) \
 	$(INTEG_SRCS) \
-	$(TOPDIR)/src/nlsolve.cpp
+	$(TOPDIR)/src/nlsolve.cc \
+	$(TOPDIR)/src/nlsolve.hh
diff --git a/mex/sources/k_order_perturbation/dynamic_dll.hh b/mex/sources/k_order_perturbation/dynamic_dll.hh
index aef34c8872a2a99f25d9fa91092955833565b495..f79aae54cd8305b68725106b38431310817cf69c 100644
--- a/mex/sources/k_order_perturbation/dynamic_dll.hh
+++ b/mex/sources/k_order_perturbation/dynamic_dll.hh
@@ -32,7 +32,7 @@
 #include <string>
 
 #include "dynamic_abstract_class.hh"
-#include "dynare_exception.h"
+#include "dynare_exception.hh"
 
 using dynamic_tt_fct = void (*)(const double *y, const double *x, int nb_row_x, const double *params, const double *steady_state, int it_, double *T);
 using dynamic_resid_fct = void (*) (const double *y, const double *x, int nb_row_x, const double *params, const double *steady_state, int it_, const double *T, double *residual);
diff --git a/mex/sources/k_order_perturbation/k_ord_dynare.cc b/mex/sources/k_order_perturbation/k_ord_dynare.cc
index ab81818e7a2c166dd58e5b994dde7892b4ed2bfe..fa45e8bbfa3b465d4a7f3b5cf850ea5d8348297b 100644
--- a/mex/sources/k_order_perturbation/k_ord_dynare.cc
+++ b/mex/sources/k_order_perturbation/k_ord_dynare.cc
@@ -26,7 +26,7 @@
 #include <cmath>
 #include <sstream>
 
-#include "memory_file.h"
+#include "memory_file.hh"
 
 #include <iostream>
 #include <fstream>
diff --git a/mex/sources/k_order_perturbation/k_ord_dynare.hh b/mex/sources/k_order_perturbation/k_ord_dynare.hh
index 45c94582288504fd4729f42c89520bc4a1601e04..93b1d90b78a6b56ff74d21fe3e37096298aa3ce9 100644
--- a/mex/sources/k_order_perturbation/k_ord_dynare.hh
+++ b/mex/sources/k_order_perturbation/k_ord_dynare.hh
@@ -26,13 +26,13 @@
 #include "decision_rule.hh"
 #include "dynamic_model.hh"
 
-#include "exception.h"
-#include "dynare_exception.h"
+#include "exception.hh"
+#include "dynare_exception.hh"
 #include "fs_tensor.hh"
-#include "SylvException.h"
+#include "SylvException.hh"
 #include "tl_exception.hh"
 #include "kord_exception.hh"
-#include "nlsolve.h"
+#include "nlsolve.hh"
 #include "approximation.hh"
 
 class KordpDynare;