diff --git a/others/cpp/dynare_cpp_driver.cc b/others/cpp/dynare_cpp_driver.cc
index 5d72ee5b45218054844c7c0ba73c9ff93b52af5c..f6701dd4bd37cfd8743dbf1ee8262c9bf13ca283 100644
--- a/others/cpp/dynare_cpp_driver.cc
+++ b/others/cpp/dynare_cpp_driver.cc
@@ -32,23 +32,23 @@ DynareInfo::DynareInfo(map<string, int > exo_names_arg,
                        vector<aux_vars_t> aux_vars_arg,
                        vector<int> predetermined_variables_arg,
                        vector<int> varobs_arg,
-                       vector<vector<int > > lead_lag_incidence_arg,
                        vector<int> NNZDerivatives_arg) :
-  exo_names(exo_names_arg),
-  exo_det_names(exo_det_names_arg),
-  endo_names(endo_names_arg),
-  param_names(param_names_arg),
-  params(params_arg),
-  aux_vars(aux_vars_arg),
-  predetermined_variables(predetermined_variables_arg),
-  varobs(varobs_arg),
-  lead_lag_incidence(lead_lag_incidence_arg),
   NNZDerivatives(NNZDerivatives_arg)
 {
   endo_nbr = endo_names.size();
   exo_nbr = exo_names.size();
   exo_det_nbr = exo_det_names.size();
   param_nbr = param_names.size();
+  
+  exo_names = exo_names_arg;
+  exo_det_names = exo_det_names_arg;
+  endo_names = endo_names_arg;
+  param_names = param_names_arg;
+  params = params_arg;
+  std::cout << params_arg[0] << std::endl;
+  std::cout << params[0] << std::endl;
+  aux_vars = aux_vars_arg;
+  predetermined_variables = predetermined_variables_arg;
 }
 
 DynareInfo::~DynareInfo()
@@ -91,7 +91,6 @@ DynareInfo::~DynareInfo()
   aux_vars.clear();
   predetermined_variables.clear();
   varobs.clear();
-  lead_lag_incidence.clear();
   NNZDerivatives.clear();
 }
 
@@ -181,14 +180,6 @@ DynareInfo::get_param_value_by_index(int index) throw (ValueNotSetException)
   //  throw ValueNotSetException("get_param_value_by_index" + index);
 }
 
-vector<int >
-DynareInfo::get_lead_lag_incidence_for_endo_var_by_index(int index) throw (ValueNotSetException)
-{
-  if (index < lead_lag_incidence.size())
-    return lead_lag_incidence.at(index);
-  throw ValueNotSetException("get_lead_lag_incidence_for_endo_var_by_index" + index);
-}
-
 MarkovSwitching::MarkovSwitching(const int chain_arg,
                                  const int number_of_regimes_arg,
                                  const int number_of_lags_arg,
diff --git a/others/cpp/dynare_cpp_driver.hh b/others/cpp/dynare_cpp_driver.hh
index 3deb23e3e29bbcb243c86092b9924e772bede81d..581cdd6eae7f38d08155081a674516fbcee84b75 100644
--- a/others/cpp/dynare_cpp_driver.hh
+++ b/others/cpp/dynare_cpp_driver.hh
@@ -242,10 +242,11 @@ private:
   vector<aux_vars_t> aux_vars;
   vector<int> predetermined_variables;
   vector<int> varobs;
-  vector<vector<int > >lead_lag_incidence;
+  vector<size_t> zeta_fwrd, zeta_back, zeta_mixed, zeta_static;
   vector<int> NNZDerivatives;
-  int endo_nbr, exo_nbr, exo_det_nbr, param_nbr;
+  int endo_nbr, exo_nbr, exo_det_nbr, param_nbr, nstatic, nfwrd, nback, nmixed;
 public:
+  DynareInfo(void); // this function is automatically written by the Dynare preprocessor
   DynareInfo(map<string, int > exo_names_arg,
              map<string, int > exo_det_names_arg,
              map<string, int > endo_names_arg,
@@ -254,7 +255,6 @@ public:
              vector<aux_vars_t> aux_vars_arg,
              vector<int> predetermined_variables_arg,
              vector<int> varobs_arg,
-             vector< vector<int > > lead_lag_incidence_arg,
              vector<int> NNZDerivatives_arg);
   ~DynareInfo();
 
@@ -303,16 +303,20 @@ public:
   inline map<string, int > get_endo_names() { return endo_names; };
   inline map<string, int > get_param_names() { return param_names; };
   inline vector<double> get_params() { return params; };
+  inline double *get_params_data(void) { return params.data(); };
   inline vector <aux_vars_t> get_aux_vars() { return aux_vars; };
   inline vector <int> get_predetermined_variables() { return predetermined_variables; };
   inline vector <int> get_varobs() { return varobs; };
-  inline vector<vector<int > > get_lead_lag_incidence() { return lead_lag_incidence; };
   inline vector<int> get_NNZDerivatives() { return NNZDerivatives; };
 
   inline int get_endo_nbr(void) { return endo_nbr; };
   inline int get_exo_nbr(void) { return exo_nbr; };
   inline int get_exo_det_nbr(void) { return exo_det_nbr; };
   inline int get_param_nbr(void) { return param_nbr; };
+  inline vector<size_t>  get_zeta_back(void) { return zeta_back; };
+  inline vector<size_t>  get_zeta_fwrd(void) { return zeta_fwrd; };
+  inline vector<size_t>  get_zeta_mixed(void) { return zeta_mixed; };
+  inline vector<size_t>  get_zeta_static(void) { return zeta_static; };
 
   string get_exo_name_by_index(int index) throw (ValueNotSetException);
   int get_exo_index_by_name(string name) throw (ValueNotSetException);
@@ -323,7 +327,7 @@ public:
   string get_param_name_by_index(int index) throw (ValueNotSetException);
   int get_param_index_by_name(string name) throw (ValueNotSetException);
   double get_param_value_by_index(int index) throw (ValueNotSetException);
-  vector<int >get_lead_lag_incidence_for_endo_var_by_index(int index) throw (ValueNotSetException);
+
 };
 
 #endif // ! _DYNARE_CPP_DRIVER_HH
diff --git a/others/cpp/tests/Makefile b/others/cpp/tests/Makefile
index aea41e2ed841a7a798b12c5bf10873e3c624d47f..00d88540033c33fa5c7066d7b2a25e74ff741216 100644
--- a/others/cpp/tests/Makefile
+++ b/others/cpp/tests/Makefile
@@ -1,5 +1,24 @@
 DYNARE=../../../matlab/dynare_m
+am_test_dr_OBJECTS = test_dr-Matrix.$(OBJEXT) test_dr-Vector.$(OBJEXT) \
+	test_dr-QRDecomposition.$(OBJEXT) \
+	test_dr-GeneralizedSchurDecomposition.$(OBJEXT) \
+	test_dr-LUSolver.$(OBJEXT) test_dr-DecisionRules.$(OBJEXT) \
+	test_dr-test-dr.$(OBJEXT)
+
 all: test1
+Matrix.o : ../../../mex/sources/estimation/libmat/Matrix.cc
+	gcc -g -c ../../../mex/sources/estimation/libmat/Matrix.cc -I.. -I../../../mex/sources -I../../../mex/sources/estimation -I../../../mex/sources/estimation/libmat
+Vector.o : ../../../mex/sources/estimation/libmat/Vector.cc
+	gcc -g -c ../../../mex/sources/estimation/libmat/Vector.cc -I.. -I../../../mex/sources -I../../../mex/sources/estimation -I../../../mex/sources/estimation/libmat
+QRDecomposition.o : ../../../mex/sources/estimation/libmat/QRDecomposition.cc
+	gcc -g -c ../../../mex/sources/estimation/libmat/QRDecomposition.cc -I.. -I../../../mex/sources -I../../../mex/sources/estimation -I../../../mex/sources/estimation/libmat
+GeneralizedSchurDecomposition.o : ../../../mex/sources/estimation/libmat/GeneralizedSchurDecomposition.cc
+	gcc -g -c ../../../mex/sources/estimation/libmat/GeneralizedSchurDecomposition.cc -I.. -I../../../mex/sources -I../../../mex/sources/estimation -I../../../mex/sources/estimation/libmat
+LUSolver.o : ../../../mex/sources/estimation/libmat/LUSolver.cc
+	gcc -g -c ../../../mex/sources/estimation/libmat/LUSolver.cc -I.. -I../../../mex/sources -I../../../mex/sources/estimation -I../../../mex/sources/estimation/libmat
+DecisionRules.o : ../../../mex/sources/estimation/DecisionRules.cc
+	gcc -g -c ../../../mex/sources/estimation/DecisionRules.cc -I../../../mex/sources -I../../../mex/sources/estimation -I../../../mex/sources/estimation/libmat
+
 test1.o : test1.cc ../dynare_cpp_driver.hh ../dynare_cpp_driver.cc
 	gcc -g -c test1.cc -I.. -I../../../mex/sources -I../../../mex/sources/estimation -I../../../mex/sources/estimation/libmat
 dynare_cpp_driver.o: ../dynare_cpp_driver.cc ../dynare_cpp_driver.hh
@@ -10,5 +29,11 @@ example1.o: example1.cc
 	gcc -g -c example1.cc -I..
 example1_steadystate.o: example1_steadystate.cc
 	gcc -g -c example1_steadystate.cc
-test1 : test1.o example1.o example1_steadystate.o dynare_cpp_driver.o
-	gcc -g -o test1 test1.o example1.o example1_steadystate.o dynare_cpp_driver.o -lm -lstdc++
+example1_first_derivatives.o: example1_first_derivatives.cc
+	gcc -g -c example1_first_derivatives.cc
+
+test1 : test1.o example1.o example1_steadystate.o example1_first_derivatives.o dynare_cpp_driver.o Matrix.o Vector.o QRDecomposition.o GeneralizedSchurDecomposition.o LUSolver.o DecisionRules.o
+	gcc -g -o test1 test1.o example1.o example1_steadystate.o example1_first_derivatives.o dynare_cpp_driver.o Matrix.o Vector.o QRDecomposition.o GeneralizedSchurDecomposition.o LUSolver.o DecisionRules.o -llapack -lblas -lm -lstdc++
+
+.cc.o:
+	gcc -g -c -o $@ $< -I.. -I../../../mex/sources -I../../../mex/sources/estimation -I../../../mex/sources/estimation/libmat
diff --git a/preprocessor/DynamicModel.cc b/preprocessor/DynamicModel.cc
index 8804551dcc4696aded5b99b97e8cad76de9d4e4b..1a5de8b9b0a63659207474cb8db6609bc9ae9c20 100644
--- a/preprocessor/DynamicModel.cc
+++ b/preprocessor/DynamicModel.cc
@@ -2959,124 +2959,43 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block_de
 void
 DynamicModel::writeCOutput(ostream &output, const string &basename, bool block_decomposition, bool byte_code, bool use_dll, int order, bool estimation_present) const
 {
-  /* Writing initialisation for M_.lead_lag_incidence matrix
-     M_.lead_lag_incidence is a matrix with as many columns as there are
-     endogenous variables and as many rows as there are periods in the
-     models (nbr of rows = M_.max_lag+M_.max_lead+1)
-
-     The matrix elements are equal to zero if a variable isn't present in the
-     model at a given period.
-  */
-
-  vector<int> state_var, state_equ;
-  output << endl
-         << "vector<vector<int > > lead_lag_incidence;" << endl
-         << "vector<int > variable_presence;" << endl;
+  int lag_presence[3];
   // Loop on endogenous variables
-  int nstatic = 0,
-      nfwrd   = 0,
-      npred   = 0,
-      nboth   = 0;
   for (int endoID = 0; endoID < symbol_table.endo_nbr(); endoID++)
     {
-      output << "variable_presence.clear();" << endl;
-      int sstatic = 1,
-          sfwrd   = 0,
-          spred   = 0,
-          sboth   = 0;
+      int varID;
       // Loop on periods
-      for (int lag = -max_endo_lag; lag <= max_endo_lead; lag++)
-        {
-          // Print variableID if exists with current period, otherwise print 0
+      for (int lag = 0; lag <= 2; lag++)
+	{
+	  lag_presence[lag] = 1;
           try
             {
-              int varID = getDerivID(symbol_table.getID(eEndogenous, endoID), lag);
-              output << "variable_presence.push_back(" << getDynJacobianCol(varID) <<  ");" << endl;
-              if (lag == -1)
-                {
-                  sstatic = 0;
-                  spred = 1;
-                }
-              else if (lag == 1)
-                if (spred == 1)
-                  {
-                    sboth = 1;
-                    spred = 0;
-                  }
-                else
-                  {
-                    sstatic = 0;
-                    sfwrd = 1;
-                  }
+              varID = getDerivID(symbol_table.getID(eEndogenous, endoID), lag-1);
             }
           catch (UnknownDerivIDException &e)
             {
-              output << "variable_presence.push_back(0);" << endl;
+	      lag_presence[lag] = 0;
             }
         }
-      nstatic += sstatic;
-      nfwrd   += sfwrd;
-      npred   += spred;
-      nboth   += sboth;
-      output << "lead_lag_incidence.push_back(variable_presence);" << endl;
+      if (lag_presence[0] == 1)
+	if (lag_presence[2] == 1)
+	  output << "zeta_mixed.push_back(" << endoID << ");" << endl;
+	else
+	  output << "zeta_back.push_back(" << endoID << ");" << endl;
+      else if (lag_presence[2] == 1)
+	output << "zeta_fwrd.push_back(" << endoID << ");" << endl;
+      else
+	output << "zeta_static.push_back(" << endoID << ");" << endl;
+      
     }
-  output << "int nstatic = " << nstatic << ";" << endl
-         << "int nfwrd   = " << nfwrd   << ";" << endl
-         << "int npred   = " << npred   << ";" << endl
-         << "int nboth   = " << nboth   << ";" << endl;
-  for (int endoID = 0; endoID < symbol_table.endo_nbr(); endoID++)
-    // Loop on periods
-    for (int lag = -max_endo_lag; lag < 0; lag++)
-      // Print variableID if exists with current period, otherwise print 0
-      try
-        {
-          getDerivID(symbol_table.getID(eEndogenous, variable_reordered[endoID]), lag);
-          if (lag < 0 && find(state_var.begin(), state_var.end(), variable_reordered[endoID]+1) == state_var.end())
-            state_var.push_back(variable_reordered[endoID]);
-        }
-      catch (UnknownDerivIDException &e)
-        {
-        }
-
-  // Writing initialization for some other variables
-  output << endl
-         << "int state_var[" << state_var.size() << "] = {";
-  for (size_t i = 0; i < state_var.size(); i++)
-    if (i+1 == state_var.size())
-      output << state_var[i];
-    else
-      output << state_var[i] << ", ";
-  output << "};" << endl;
-
-  output << endl
-         << "int maximum_lag = " << max_lag << ";" << endl
-         << "int maximum_lead = " << max_lead << ";" << endl;
-
-  if (symbol_table.endo_nbr())
-    output << endl
-           << "int maximum_endo_lag = " << max_endo_lag << ";" << endl
-           << "int maximum_endo_lead = " << max_endo_lead << ";" << endl
-           << "double steady_state[" << symbol_table.endo_nbr() << "];" << endl;
-
-  if (symbol_table.exo_nbr())
-    output << endl
-           << "int maximum_exo_lag = " << max_exo_lag << ";" << endl
-           << "int maximum_exo_lead = " << max_exo_lead << ";" << endl
-           << "double exo_steady_state[" << symbol_table.exo_nbr() << "];" << endl;
-
-  if (symbol_table.exo_det_nbr())
-    output << endl
-           << "int maximum_exo_det_lag = " << max_exo_det_lag << ";" << endl
-           << "int maximum_exo_det_lead = " << max_exo_det_lead << ";" << endl
-           << "double exo_det_steady_state[" << symbol_table.exo_det_nbr() << "];" << endl;
-
-  output << endl
-         << "map<int, double > params;" << endl;
+  output << "nstatic = zeta_static.size();" << endl
+         << "nfwrd   = zeta_fwrd.size();" << endl
+         << "nback   = zeta_back.size();" << endl
+         << "nmixed  = zeta_mixed.size();" << endl;
 
   // Write number of non-zero derivatives
   // Use -1 if the derivatives have not been computed
   output << endl
-         << "vector<double> NNZDerivatives;" << endl
          << "NNZDerivatives.push_back(" << NNZDerivatives[0] << ");" << endl;
   if (order > 1)
     {
diff --git a/preprocessor/ModFile.cc b/preprocessor/ModFile.cc
index 432778b58d2f3d002a305ca2f505c3d603011f47..b58b6e656ee5db33d77a54091ca4748fffa33641 100644
--- a/preprocessor/ModFile.cc
+++ b/preprocessor/ModFile.cc
@@ -826,40 +826,27 @@ ModFile::writeModelCC(const string &basename, bool cuda) const
                << endl
                << "#include \"dynare_cpp_driver.hh\"" << endl
                << endl
-               << "DynareInfo *" << endl
-               << "preprocessorOutput()" << endl
+               << "DynareInfo::DynareInfo(void)" << endl
                << "{" << endl;
 
   // Write basic info
   symbol_table.writeCOutput(mDriverCFile);
 
-  mDriverCFile << "/*" << endl
-               << " * Writing statements" << endl
-               << " */" << endl
-               << "/* prior args*/" << endl
-               << "int index, index1;" << endl
-               << "string shape;" << endl
-               << "double mean, mode, stdev, variance;" << endl
-               << "vector<double> domain;" << endl
-               << "/* markov_switching args*/" << endl
-               << "int chain, number_of_regimes, number_of_lags, number_of_lags_was_passed;" << endl
-               << "vector<int> parameters;" << endl
-               << "vector<double> duration;" << endl
-               << "restriction_map_t restriction_map;" << endl
-               << "/* options args*/" << endl
-               << "double init;" << endl 
-	       << "vector< vector<int> > lead_lag_incidence;" << endl
-	       << "vector<int> NNZDerivatives;" << endl
-	       << "vector<double> params(param_nbr);" << endl << endl;
+  mDriverCFile << endl << "params.resize(param_nbr);" << endl;
+
+  if (dynamic_model.equation_number() > 0)
+    {
+      dynamic_model.writeCOutput(mDriverCFile, basename, block, byte_code, use_dll, mod_file_struct.order_option, mod_file_struct.estimation_present);
+      //      if (!no_static)
+      //        static_model.writeCOutput(mOutputFile, block);
+    }
 
   // Print statements
   for (vector<Statement *>::const_iterator it = statements.begin();
        it != statements.end(); it++)
       (*it)->writeCOutput(mDriverCFile, basename);
 
-  mDriverCFile << "DynareInfo *model_info = new DynareInfo(exo_names, exo_det_names, endo_names, param_names, params, aux_vars, predetermined_variables, varobs, lead_lag_incidence, NNZDerivatives);" << endl
-	       << "return model_info;" << endl
-	       << "}" << endl;
+  mDriverCFile << "}" << endl;
   mDriverCFile.close();
 
   // Write informational m file
diff --git a/preprocessor/SymbolTable.cc b/preprocessor/SymbolTable.cc
index abcd3c6768fa1b0b7b4d1c00871f6f8d8d8bd940..21b406b80f39199e6877e4f4a0eaee84a13a6031 100644
--- a/preprocessor/SymbolTable.cc
+++ b/preprocessor/SymbolTable.cc
@@ -293,23 +293,19 @@ SymbolTable::writeCOutput(ostream &output) const throw (NotYetFrozenException)
     throw NotYetFrozenException();
 
   output << endl
-         << "map<string, int > exo_names, exo_det_names, endo_names, param_names;" << endl;
-
-  output << endl
-         << "int exo_nbr = " << exo_nbr() << ";" << endl;
+         << "exo_nbr = " << exo_nbr() << ";" << endl;
   if (exo_nbr() > 0)
     for (int id = 0; id < exo_nbr(); id++)
       output << "exo_names[\"" << getName(exo_ids[id]) << "\"] = " << id << ";" << endl;
 
   output << endl
-         << "int exo_det_nbr = " << exo_det_nbr() << ";" << endl;
+         << "exo_det_nbr = " << exo_det_nbr() << ";" << endl;
   if (exo_det_nbr() > 0)
     for (int id = 0; id < exo_det_nbr(); id++)
       output << "exo_det_names[\"" << getName(exo_det_ids[id]) << "\"] = " << id << " ;" << endl;
 
   output << endl
-         << "int endo_nbr = " << endo_nbr() << ";" << endl
-         << "int orig_endo_nbr = " << orig_endo_nbr() << ";" << endl;
+         << "endo_nbr = " << endo_nbr() << ";" << endl;
   if (endo_nbr() > 0)
     for (int id = 0; id < endo_nbr(); id++)
       output << "endo_names[\"" << getName(endo_ids[id]) << "\"] = " << id << ";" << endl;
@@ -321,8 +317,6 @@ SymbolTable::writeCOutput(ostream &output) const throw (NotYetFrozenException)
       output << "param_names[\"" << getName(param_ids[id]) << "\"] = " << id << ";" << endl;
 
   // Write the auxiliary variable table
-  output << endl
-         << "vector <aux_vars_t> aux_vars;" << endl;
   if (aux_vars.size() > 0)
     for (int i = 0; i < (int) aux_vars.size(); i++)
       {
@@ -345,8 +339,6 @@ SymbolTable::writeCOutput(ostream &output) const throw (NotYetFrozenException)
         output << "aux_vars.push_back(" << "av" << i << ");" << endl;
       }
 
-  output << endl
-         << "vector <int> predetermined_variables, varobs;" << endl;
   if (predeterminedNbr() > 0)
     for (set<int>::const_iterator it = predetermined_variables.begin();
          it != predetermined_variables.end(); it++)