diff --git a/BlockTriangular.cc b/BlockTriangular.cc
deleted file mode 100644
index ad0dd4711e1659c4af95b63248c489d00bef70fb..0000000000000000000000000000000000000000
--- a/BlockTriangular.cc
+++ /dev/null
@@ -1,1166 +0,0 @@
-/*
- * Copyright (C) 2007-2009 Dynare Team
- *
- * This file is part of Dynare.
- *
- * Dynare is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Dynare is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <iostream>
-#include <sstream>
-#include <fstream>
-#include <cstdlib>
-#include <cstring>
-#include <cmath>
-#include <algorithm>
-#include <functional>
-#include "MinimumFeedbackSet.hh"
-#include <boost/graph/adjacency_list.hpp>
-#include <boost/graph/max_cardinality_matching.hpp>
-#include <boost/graph/strong_components.hpp>
-#include <boost/graph/topological_sort.hpp>
-
-//------------------------------------------------------------------------------
-#include "BlockTriangular.hh"
-//------------------------------------------------------------------------------
-using namespace std;
-using namespace boost;
-using namespace MFS;
-
-BlockTriangular::BlockTriangular(SymbolTable &symbol_table_arg, NumericalConstants &num_const_arg)
-  : symbol_table(symbol_table_arg),
-  //normalization(symbol_table_arg),
-  incidencematrix(symbol_table_arg),
-  num_const(num_const_arg)
-{
-  bt_verbose = 0;
-  ModelBlock = NULL;
-  periods = 0;
-  prologue = epilogue = 0;
-  Normalized_Equation = new DataTree(symbol_table, num_const);
-}
-
-BlockTriangular::~BlockTriangular()
-{
-  delete Normalized_Equation;
-}
-
-//------------------------------------------------------------------------------
-// Find the prologue and the epilogue of the model
-void
-BlockTriangular::Prologue_Epilogue(bool *IM, int &prologue, int &epilogue, int n, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM, bool *IM0)
-{
-  bool modifie = 1;
-  int i, j, k, l = 0;
-  /*Looking for a prologue */
-  prologue = 0;
-  while (modifie)
-    {
-      modifie = 0;
-      for (i = prologue; i < n; i++)
-        {
-          k = 0;
-          for (j = prologue; j < n; j++)
-            {
-              if (IM[i*n + j])
-                {
-                  k++;
-                  l = j;
-                }
-            }
-          if ((k == 1) && IM0[Index_Equ_IM[i]*n + Index_Var_IM[l]])
-            {
-              modifie = 1;
-              incidencematrix.swap_IM_c(IM, prologue, i, l, Index_Var_IM, Index_Equ_IM, n);
-              prologue++;
-            }
-        }
-    }
-  epilogue = 0;
-  modifie = 1;
-  while (modifie)
-    {
-      modifie = 0;
-      for (i = prologue; i < n - epilogue; i++)
-        {
-          k = 0;
-          for (j = prologue; j < n - epilogue; j++)
-            {
-              if (IM[j*n + i])
-                {
-                  k++;
-                  l = j;
-                }
-            }
-          if ((k == 1) && IM0[Index_Equ_IM[l]*n + Index_Var_IM[i]])
-            {
-              modifie = 1;
-              incidencematrix.swap_IM_c(IM, n - (1 + epilogue), l, i, Index_Var_IM, Index_Equ_IM, n);
-              epilogue++;
-            }
-        }
-    }
-}
-
-//------------------------------------------------------------------------------
-// Find a matching between equations and endogenous variables
-bool
-BlockTriangular::Compute_Normalization(bool *IM, int equation_number, int prologue, int epilogue, int verbose, bool *IM0, vector<int> &Index_Equ_IM) const
-{
-  int n = equation_number - prologue - epilogue;
-
-  typedef adjacency_list<vecS, vecS, undirectedS> BipartiteGraph;
-
-
-  if(verbose == 2)
-    cout << "trying to normlized even in singular case\n";
-  /*
-     Vertices 0 to n-1 are for endogenous (using type specific ID)
-     Vertices n to 2*n-1 are for equations (using equation no.)
-   */
-  BipartiteGraph g(2 * n);
-  // Fill in the graph
-  for (int i = 0; i < n; i++)
-    for (int j = 0; j < n; j++)
-      if (IM0[(i+prologue) * equation_number+j+prologue])
-        {
-        	//printf("equation=%3d variable=%3d\n",i,j);
-          add_edge(i + n, j, g);
-        }
-
-  // Compute maximum cardinality matching
-  typedef vector<graph_traits<BipartiteGraph>::vertex_descriptor> mate_map_t;
-  mate_map_t mate_map(2*n);
-
-  bool check = checked_edmonds_maximum_cardinality_matching(g, &mate_map[0]);
-  //cout << "check = " << check << "\n";
-  if (check)
-    {
-      // Check if all variables are normalized
-      mate_map_t::const_iterator it = find(mate_map.begin(), mate_map.begin() + n, graph_traits<BipartiteGraph>::null_vertex());
-      if (it != mate_map.begin() + n)
-        {
-          if (verbose == 1)
-            {
-              cout << "WARNING: Could not normalize dynamic model. Variable "
-                   << symbol_table.getName(symbol_table.getID(eEndogenous, it - mate_map.begin()))
-                   << " is not in the maximum cardinality matching. Trying to find a singular normalization." << endl;
-              //exit(EXIT_FAILURE);
-              return false;
-            }
-          else if (verbose == 2)
-            {
-              cerr << "ERROR: Could not normalize dynamic model (even with a singularity). Variable "
-                   << symbol_table.getName(symbol_table.getID(eEndogenous, it - mate_map.begin()))
-                   << " is not in the maximum cardinality matching." << endl;
-              exit(EXIT_FAILURE);
-            }
-          return false;
-        }
-      vector<int> Index_Equ_IM_tmp(Index_Equ_IM);
-      bool *SIM;
-      SIM = (bool *) malloc(equation_number*equation_number*sizeof(bool));
-      memcpy(SIM, IM, equation_number*equation_number*sizeof(bool));
-      for (int i = 0; i < n; i++)
-        {
-          //printf("match equation %4d with variable %4d \n", mate_map[i] - n, i);
-          Index_Equ_IM[i + prologue] = Index_Equ_IM_tmp[mate_map[i] - n + prologue];
-          for (int k = 0; k < n; k++)
-            IM[(i+prologue)*equation_number+k +prologue] = SIM[(mate_map[i]-n+prologue)*equation_number+k +prologue];
-        }
-      free(SIM);
-    }
-  return check;
-}
-
-
-
-
-t_vtype
-BlockTriangular::Get_Variable_LeadLag_By_Block(vector<int > &components_set, int nb_blck_sim, int prologue, int epilogue, t_vtype &equation_lead_lag) const
-{
-  int nb_endo = symbol_table.endo_nbr();
-  vector<int> variable_blck(nb_endo), equation_blck(nb_endo);
-  t_vtype Variable_Type(nb_endo);
-  for (int i = 0; i < nb_endo; i++)
-    {
-      if (i < prologue)
-        {
-          variable_blck[Index_Var_IM[i]] = i;
-          equation_blck[Index_Equ_IM[i]] = i;
-        }
-      else if (i < (int)components_set.size() + prologue)
-        {
-          variable_blck[Index_Var_IM[i]] = components_set[i-prologue] + prologue;
-          equation_blck[Index_Equ_IM[i]] = components_set[i-prologue] + prologue;
-        }
-      else
-        {
-          variable_blck[Index_Var_IM[i]] = i- (nb_endo - nb_blck_sim - prologue - epilogue);
-          equation_blck[Index_Equ_IM[i]] = i- (nb_endo - nb_blck_sim - prologue - epilogue);
-        }
-      Variable_Type[i] = make_pair(0, 0);
-    }
-  equation_lead_lag = Variable_Type;
-  for (int k = -incidencematrix.Model_Max_Lag_Endo; k <= incidencematrix.Model_Max_Lead_Endo; k++)
-    {
-      bool *Cur_IM = incidencematrix.Get_IM(k, eEndogenous);
-      if (Cur_IM)
-        {
-          for (int i = 0; i < nb_endo; i++)
-            {
-              int i_1 = Index_Var_IM[i];
-              for (int j = 0; j < nb_endo; j++)
-                {
-                  int j_l = Index_Equ_IM[ j];
-                  if (Cur_IM[i_1 + Index_Equ_IM[ j] * nb_endo] and variable_blck[i_1] == equation_blck[j_l])
-                    {
-                      if (k > Variable_Type[i_1].second)
-                        Variable_Type[i_1] = make_pair(Variable_Type[i_1].first, k);
-                      if (k < -Variable_Type[i_1].first)
-                        Variable_Type[i_1] = make_pair(-k, Variable_Type[i_1].second);
-                      if (k > equation_lead_lag[j_l].second)
-                        equation_lead_lag[j_l] = make_pair(equation_lead_lag[j_l].first, k);
-                      if (k < -equation_lead_lag[j_l].first)
-                        equation_lead_lag[j_l] = make_pair(-k, equation_lead_lag[j_l].second);
-                    }
-                }
-            }
-        }
-    }
-  return (Variable_Type);
-}
-
-void
-BlockTriangular::Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Block(bool *IM, int nb_var, int prologue, int epilogue, vector<int> &Index_Equ_IM, vector<int> &Index_Var_IM, vector<pair<int, int> > &blocks, t_etype &Equation_Type, bool verbose_, bool select_feedback_variable, int mfs) const
-{
-  t_vtype V_Variable_Type;
-  int n = nb_var - prologue - epilogue;
-  bool *AMp;
-  AMp = (bool *) malloc(n*n*sizeof(bool));
-  //transforms the incidence matrix of the complet model into an adjancent matrix of the non-recursive part of the model
-  for (int i = prologue; i < nb_var - epilogue; i++)
-    for (int j = prologue; j < nb_var - epilogue; j++)
-      if (j != i)
-        AMp[(i-prologue)*n+j-prologue] = IM[i*nb_var + j];
-      else
-        AMp[(i-prologue)*n+j-prologue] = 0;
-
-  //In a first step we compute the strong components of the graph representation of the static model.
-  // This insures that block are dynamically recursives.
-  GraphvizDigraph G2 = AM_2_GraphvizDigraph(AMp, n);
-  vector<int> endo2block(num_vertices(G2)), discover_time(num_vertices(G2));
-
-  int num = strong_components(G2, &endo2block[0]);
-
-  blocks = vector<pair<int, int> >(num, make_pair(0, 0));
-
-
-
-/*New*/
- // Compute strongly connected components
-  // Create directed acyclic graph associated to the strongly connected components
-  typedef adjacency_list<vecS, vecS, directedS> DirectedGraph;
-  DirectedGraph dag(num);
-  /*graph_traits<DirectedGraph>::edge_iterator ei, ei_end;
-  for(tie(ei, ei_end) = edges(G2); ei != ei_end; ++ei)
-    {
-      int s = endo2block[source(*ei, G2)];
-      int t = endo2block[target(*ei, G2)];
-      if (s != t)
-        add_edge(s, t, dag);
-    }*/
-  for (unsigned int i = 0;i < num_vertices(G2);i++)
-    {
-      GraphvizDigraph::out_edge_iterator it_out, out_end;
-      GraphvizDigraph::vertex_descriptor vi = vertex(i, G2);
-      for (tie(it_out, out_end) = out_edges(vi, G2); it_out != out_end; ++it_out)
-        {
-          int t_b = endo2block[target(*it_out, G2)];
-          int s_b = endo2block[source(*it_out, G2)];
-          if (s_b != t_b)
-            add_edge(s_b, t_b, dag);
-        }
-    }
-  // Compute topological sort of DAG (ordered list of unordered SCC)
-  deque<int> ordered2unordered;
-  topological_sort(dag, front_inserter(ordered2unordered)); // We use a front inserter because topological_sort returns the inverse order
-  // Construct mapping from unordered SCC to ordered SCC
-  vector<int> unordered2ordered(num);
-  for(int i = 0; i < num; i++)
-    unordered2ordered[ordered2unordered[i]] = i;
-/*EndNew*/
-
-
-  //This vector contains for each block:
-  //   - first set = equations belonging to the block,
-  //   - second set = the feeback variables,
-  //   - third vector = the reordered non-feedback variables.
-  vector<pair<set<int>, pair<set<int>, vector<int> > > > components_set(num);
-
-  for (unsigned int i = 0; i < endo2block.size(); i++)
-    {
-      endo2block[i] = unordered2ordered[endo2block[i]];
-      blocks[endo2block[i]].first++;
-      components_set[endo2block[i]].first.insert(i);
-    }
-
-
-  t_vtype equation_lead_lag;
-  V_Variable_Type = Get_Variable_LeadLag_By_Block(endo2block, num, prologue, epilogue, equation_lead_lag);
-
-  vector<int> tmp_Index_Equ_IM(Index_Equ_IM), tmp_Index_Var_IM(Index_Var_IM);
-  int order = prologue;
-  bool *SIM;
-  SIM = (bool *) malloc(nb_var*nb_var*sizeof(bool));
-  memcpy(SIM, IM, nb_var*nb_var*sizeof(bool));
-
-  //Add a loop on vertices which could not be normalized or vertices related to lead variables => force those vertices to belong to the feedback set
-  if(select_feedback_variable)
-    for (int i = 0; i < n; i++)
-      if (Equation_Type[Index_Equ_IM[i+prologue]].first == E_SOLVE or V_Variable_Type[Index_Var_IM[i+prologue]].second > 0 or V_Variable_Type[Index_Var_IM[i+prologue]].first > 0
-                                                               or equation_lead_lag[Index_Equ_IM[i+prologue]].second > 0 or equation_lead_lag[Index_Equ_IM[i+prologue]].first > 0
-                                                               or mfs == 0)
-        add_edge(i, i, G2);
-  else
-    for (int i = 0; i < n; i++)
-      if (Equation_Type[Index_Equ_IM[i+prologue]].first == E_SOLVE or mfs == 0)
-        add_edge(i, i, G2);
-  //For each block, the minimum set of feedback variable is computed
-  // and the non-feedback variables are reordered to get
-  // a sub-recursive block without feedback variables
-  for (int i = 0; i < num; i++)
-    {
-      AdjacencyList_type G = GraphvizDigraph_2_AdjacencyList(G2, components_set[i].first);
-      set<int> feed_back_vertices;
-      //Print(G);
-      AdjacencyList_type G1 = Minimal_set_of_feedback_vertex(feed_back_vertices, G);
-      property_map<AdjacencyList_type, vertex_index_t>::type v_index = get(vertex_index, G);
-      components_set[i].second.first = feed_back_vertices;
-      blocks[i].second = feed_back_vertices.size();
-      vector<int> Reordered_Vertice;
-      Reorder_the_recursive_variables(G, feed_back_vertices, Reordered_Vertice);
-      //First we have the recursive equations conditional on feedback variables
-      for (vector<int>::iterator its = Reordered_Vertice.begin(); its != Reordered_Vertice.end(); its++)
-        {
-          Index_Equ_IM[order] = tmp_Index_Equ_IM[*its+prologue];
-          Index_Var_IM[order] = tmp_Index_Var_IM[*its+prologue];
-          order++;
-        }
-      components_set[i].second.second = Reordered_Vertice;
-      //Second we have the equations related to the feedback variables
-      for (set<int>::iterator its = feed_back_vertices.begin(); its != feed_back_vertices.end(); its++)
-        {
-          Index_Equ_IM[order] = tmp_Index_Equ_IM[v_index[vertex(*its, G)]+prologue];
-          Index_Var_IM[order] = tmp_Index_Var_IM[v_index[vertex(*its, G)]+prologue];
-          order++;
-        }
-
-    }
-  free(AMp);
-  free(SIM);
-}
-
-void
-BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, BlockType type, BlockSimulationType SimType, Model_Block *ModelBlock, t_etype &Equation_Type, int recurs_Size, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM)
-{
-  int i, j, k, l, ls, m, i_1, Lead, Lag, first_count_equ, i1, li;
-  int *tmp_size, *tmp_size_other_endo, *tmp_size_exo, *tmp_var, *tmp_endo, *tmp_other_endo, *tmp_exo, tmp_nb_other_endo, tmp_nb_exo, nb_lead_lag_endo;
-  bool *tmp_variable_evaluated;
-  bool *Cur_IM;
-  bool *IM, OK;
-  int Lag_Endo, Lead_Endo, Lag_Exo, Lead_Exo, Lag_Other_Endo, Lead_Other_Endo;
-  //cout << "block " << count_Block << " size " << size << " SimType=" << BlockSim(SimType) << "\n";
-
-  ModelBlock->Periods = periods;
-  ModelBlock->Block_List[count_Block].is_linear = true;
-  ModelBlock->Block_List[count_Block].Size = size;
-  ModelBlock->Block_List[count_Block].Type = type;
-  ModelBlock->Block_List[count_Block].Nb_Recursives = recurs_Size;
-  ModelBlock->Block_List[count_Block].Temporary_InUse = new temporary_terms_inuse_type();
-  ModelBlock->Block_List[count_Block].Chain_Rule_Derivatives = new chain_rule_derivatives_type();
-  ModelBlock->Block_List[count_Block].Temporary_InUse->clear();
-  ModelBlock->Block_List[count_Block].Simulation_Type = SimType;
-  ModelBlock->Block_List[count_Block].Equation = (int *) malloc(ModelBlock->Block_List[count_Block].Size * sizeof(int));
-  ModelBlock->Block_List[count_Block].Equation_Type = (EquationType *) malloc(ModelBlock->Block_List[count_Block].Size * sizeof(EquationType));
-  ModelBlock->Block_List[count_Block].Equation_Normalized = (NodeID*)malloc(ModelBlock->Block_List[count_Block].Size * sizeof(NodeID));
-  ModelBlock->Block_List[count_Block].Variable = (int *) malloc(ModelBlock->Block_List[count_Block].Size * sizeof(int));
-  ModelBlock->Block_List[count_Block].Temporary_Terms_in_Equation = (temporary_terms_type **) malloc(ModelBlock->Block_List[count_Block].Size * sizeof(temporary_terms_type));
-  ModelBlock->Block_List[count_Block].Own_Derivative = (int *) malloc(ModelBlock->Block_List[count_Block].Size * sizeof(int));
-  Lead = Lag = 0;
-  first_count_equ = *count_Equ;
-  tmp_var = (int *) malloc(size * sizeof(int));
-  tmp_endo = (int *) malloc((incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1) * sizeof(int));
-  tmp_other_endo = (int *) malloc((incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1) * sizeof(int));
-  tmp_size = (int *) malloc((incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1) * sizeof(int));
-  tmp_size_other_endo = (int *) malloc((incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1) * sizeof(int));
-  tmp_size_exo = (int *) malloc((incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1) * sizeof(int));
-  memset(tmp_size_exo, 0, (incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1)*sizeof(int));
-  memset(tmp_size_other_endo, 0, (incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1)*sizeof(int));
-  memset(tmp_size, 0, (incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1)*sizeof(int));
-  memset(tmp_endo, 0, (incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1)*sizeof(int));
-  memset(tmp_other_endo, 0, (incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1)*sizeof(int));
-  nb_lead_lag_endo = 0;
-  Lag_Endo = Lead_Endo = Lag_Other_Endo = Lead_Other_Endo = Lag_Exo = Lead_Exo = 0;
-
-  //Variable by variable looking for all leads and lags its occurence in each equation of the block
-  tmp_variable_evaluated = (bool *) malloc(symbol_table.endo_nbr()*sizeof(bool));
-  memset(tmp_variable_evaluated, 0, symbol_table.endo_nbr()*sizeof(bool));
-  for (i = 0; i < size; i++)
-    {
-      ModelBlock->Block_List[count_Block].Temporary_Terms_in_Equation[i] = new temporary_terms_type();
-      ModelBlock->Block_List[count_Block].Temporary_Terms_in_Equation[i]->clear();
-      ModelBlock->Block_List[count_Block].Equation[i] = Index_Equ_IM[*count_Equ];
-      ModelBlock->Block_List[count_Block].Variable[i] = Index_Var_IM[*count_Equ];
-      ModelBlock->Block_List[count_Block].Equation_Type[i] = Equation_Type[Index_Equ_IM[*count_Equ]].first;
-      ModelBlock->Block_List[count_Block].Equation_Normalized[i] = Equation_Type[Index_Equ_IM[*count_Equ]].second;
-      /*if(Equation_Type[Index_Equ_IM[*count_Equ]].second)
-         {
-          temporary_terms_type temporary_terms;
-          cout << "Equation_Type[Index_Equ_IM[*count_Equ]].second->get_op_code()=" << Equation_Type[Index_Equ_IM[*count_Equ]].second->get_op_code() << "\n";
-          cout << "ModelBlock->Block_List[" << count_Block << "].Equation_Normalized[" << i << "]->get_op_code()=" << ModelBlock->Block_List[count_Block].Equation_Normalized[i]->get_op_code() << "\n";
-          ModelBlock->Block_List[count_Block].Equation_Normalized[i]->writeOutput(cout, oMatlabDynamicModelSparse, temporary_terms);
-         }*/
-      i_1 = Index_Var_IM[*count_Equ];
-      for (k = -incidencematrix.Model_Max_Lag_Endo; k <= incidencematrix.Model_Max_Lead_Endo; k++)
-        {
-          Cur_IM = incidencematrix.Get_IM(k, eEndogenous);
-          if (Cur_IM)
-            {
-              OK = false;
-              if (k >= 0)
-                {
-                  for (j = 0; j < size; j++)
-                    {
-                      if (Cur_IM[i_1 + Index_Equ_IM[first_count_equ + j]*symbol_table.endo_nbr()])
-                        {
-                          tmp_variable_evaluated[i_1] = true;
-                          tmp_size[incidencematrix.Model_Max_Lag_Endo + k]++;
-                          if (!OK)
-                            {
-                              tmp_endo[incidencematrix.Model_Max_Lag + k]++;
-                              nb_lead_lag_endo++;
-                              OK = true;
-                            }
-                          if (k > Lead)
-                            Lead = k;
-                        }
-                    }
-                }
-              else
-                {
-                  for (j = 0; j < size; j++)
-                    {
-                      if (Cur_IM[i_1 + Index_Equ_IM[first_count_equ + j]*symbol_table.endo_nbr()])
-                        {
-                          tmp_variable_evaluated[i_1] = true;
-                          tmp_size[incidencematrix.Model_Max_Lag_Endo + k]++;
-                          if (!OK)
-                            {
-                              tmp_variable_evaluated[i_1] = true;
-                              tmp_endo[incidencematrix.Model_Max_Lag + k]++;
-                              nb_lead_lag_endo++;
-                              OK = true;
-                            }
-                          if (-k > Lag)
-                            Lag = -k;
-                        }
-                    }
-                }
-            }
-        }
-      (*count_Equ)++;
-    }
-  Lag_Endo = Lag;
-  Lead_Endo = Lead;
-
-  tmp_nb_other_endo = 0;
-  for (i = 0; i < size; i++)
-    {
-      for (k = -incidencematrix.Model_Max_Lag_Endo; k <= incidencematrix.Model_Max_Lead_Endo; k++)
-        {
-          Cur_IM = incidencematrix.Get_IM(k, eEndogenous);
-          if (Cur_IM)
-            {
-              i_1 = Index_Equ_IM[first_count_equ+i] * symbol_table.endo_nbr();
-              for (j = 0; j < symbol_table.endo_nbr(); j++)
-                if (Cur_IM[i_1 + j])
-                  {
-                    if (!tmp_variable_evaluated[j])
-                      {
-                      	tmp_other_endo[incidencematrix.Model_Max_Lag + k]++;
-                        tmp_nb_other_endo++;
-                      }
-                    if (k > 0 && k > Lead_Other_Endo)
-                      Lead_Other_Endo = k;
-                    else if (k < 0 && (-k) > Lag_Other_Endo)
-                      Lag_Other_Endo = -k;
-                    if (k > 0 && k > Lead)
-                      Lead = k;
-                    else if (k < 0 && (-k) > Lag)
-                      Lag = -k;
-                    tmp_size_other_endo[k+incidencematrix.Model_Max_Lag_Endo]++;
-                  }
-            }
-        }
-    }
-  ModelBlock->Block_List[count_Block].nb_other_endo = tmp_nb_other_endo;
-  ModelBlock->Block_List[count_Block].Other_Endogenous = (int *) malloc(tmp_nb_other_endo * sizeof(int));
-
-  tmp_exo = (int *) malloc(symbol_table.exo_nbr() * sizeof(int));
-  memset(tmp_exo, 0, symbol_table.exo_nbr() *     sizeof(int));
-  tmp_nb_exo = 0;
-  for (i = 0; i < size; i++)
-    {
-      for (k = -incidencematrix.Model_Max_Lag_Exo; k <= incidencematrix.Model_Max_Lead_Exo; k++)
-        {
-          Cur_IM = incidencematrix.Get_IM(k, eExogenous);
-          if (Cur_IM)
-            {
-              i_1 = Index_Equ_IM[first_count_equ+i] * symbol_table.exo_nbr();
-              for (j = 0; j < symbol_table.exo_nbr(); j++)
-                if (Cur_IM[i_1 + j])
-                  {
-                    if (!tmp_exo[j])
-                      {
-                        tmp_exo[j] = 1;
-                        tmp_nb_exo++;
-                      }
-                    if (k > 0 && k > Lead_Exo)
-                      Lead_Exo = k;
-                    else if (k < 0 && (-k) > Lag_Exo)
-                      Lag_Exo = -k;
-                    if (k > 0 && k > Lead)
-                      Lead = k;
-                    else if (k < 0 && (-k) > Lag)
-                      Lag = -k;
-                    tmp_size_exo[k+incidencematrix.Model_Max_Lag_Exo]++;
-                  }
-            }
-        }
-    }
-
-  ModelBlock->Block_List[count_Block].nb_exo = tmp_nb_exo;
-  ModelBlock->Block_List[count_Block].Exogenous = (int *) malloc(tmp_nb_exo * sizeof(int));
-  k = 0;
-  for (j = 0; j < symbol_table.exo_nbr(); j++)
-    if (tmp_exo[j])
-      {
-        ModelBlock->Block_List[count_Block].Exogenous[k] = j;
-        k++;
-      }
-
-  ModelBlock->Block_List[count_Block].nb_exo_det = 0;
-
-  ModelBlock->Block_List[count_Block].Max_Lag = Lag;
-  ModelBlock->Block_List[count_Block].Max_Lead = Lead;
-  ModelBlock->Block_List[count_Block].Max_Lag_Endo = Lag_Endo;
-  ModelBlock->Block_List[count_Block].Max_Lead_Endo = Lead_Endo;
-  ModelBlock->Block_List[count_Block].Max_Lag_Other_Endo = Lag_Other_Endo;
-  ModelBlock->Block_List[count_Block].Max_Lead_Other_Endo = Lead_Other_Endo;
-  ModelBlock->Block_List[count_Block].Max_Lag_Exo = Lag_Exo;
-  ModelBlock->Block_List[count_Block].Max_Lead_Exo = Lead_Exo;
-  ModelBlock->Block_List[count_Block].IM_lead_lag = (IM_compact *) malloc((Lead + Lag + 1) * sizeof(IM_compact));
-  ls = l = li = size;
-  i1 = 0;
-  ModelBlock->Block_List[count_Block].Nb_Lead_Lag_Endo = nb_lead_lag_endo;
-  for (i = 0; i < Lead + Lag + 1; i++)
-    {
-      if (incidencematrix.Model_Max_Lag_Endo-Lag+i >= 0)
-        {
-          ModelBlock->Block_List[count_Block].IM_lead_lag[i].size = tmp_size[incidencematrix.Model_Max_Lag_Endo - Lag + i];
-          ModelBlock->Block_List[count_Block].IM_lead_lag[i].nb_endo = tmp_endo[incidencematrix.Model_Max_Lag_Endo - Lag + i];
-          ModelBlock->Block_List[count_Block].IM_lead_lag[i].u = (int *) malloc(tmp_size[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int));
-          ModelBlock->Block_List[count_Block].IM_lead_lag[i].us = (int *) malloc(tmp_size[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int));
-          ModelBlock->Block_List[count_Block].IM_lead_lag[i].Var = (int *) malloc(tmp_size[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int));
-          ModelBlock->Block_List[count_Block].IM_lead_lag[i].Equ = (int *) malloc(tmp_size[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int));
-          ModelBlock->Block_List[count_Block].IM_lead_lag[i].Var_Index = (int *) malloc(tmp_size[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int));
-          ModelBlock->Block_List[count_Block].IM_lead_lag[i].Equ_Index = (int *) malloc(tmp_size[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int));
-          ModelBlock->Block_List[count_Block].IM_lead_lag[i].size_other_endo = tmp_size_other_endo[incidencematrix.Model_Max_Lag_Endo - Lag + i];
-          ModelBlock->Block_List[count_Block].IM_lead_lag[i].nb_other_endo = tmp_other_endo[incidencematrix.Model_Max_Lag_Endo - Lag + i];
-          ModelBlock->Block_List[count_Block].IM_lead_lag[i].u_other_endo = (int *) malloc(tmp_size_other_endo[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int));
-          ModelBlock->Block_List[count_Block].IM_lead_lag[i].Var_other_endo = (int *) malloc(tmp_size_other_endo[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int));
-          ModelBlock->Block_List[count_Block].IM_lead_lag[i].Equ_other_endo = (int *) malloc(tmp_size_other_endo[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int));
-          ModelBlock->Block_List[count_Block].IM_lead_lag[i].Var_Index_other_endo = (int *) malloc(tmp_size_other_endo[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int));
-          ModelBlock->Block_List[count_Block].IM_lead_lag[i].Equ_Index_other_endo = (int *) malloc(tmp_size_other_endo[incidencematrix.Model_Max_Lag_Endo - Lag + i] * sizeof(int));
-        }
-      else
-        ModelBlock->Block_List[count_Block].IM_lead_lag[i].size = 0;
-      /*if (incidencematrix.Model_Max_Lag_Exo-Lag+i>=0)
-         {
-          ModelBlock->Block_List[count_Block].IM_lead_lag[i].size_exo = tmp_size_exo[incidencematrix.Model_Max_Lag_Exo - Lag + i];
-          ModelBlock->Block_List[count_Block].IM_lead_lag[i].Exogenous = (int*)malloc(tmp_size_exo[incidencematrix.Model_Max_Lag_Exo - Lag + i] * sizeof(int));
-          ModelBlock->Block_List[count_Block].IM_lead_lag[i].Exogenous_Index = (int*)malloc(tmp_size_exo[incidencematrix.Model_Max_Lag_Exo - Lag + i] * sizeof(int));
-          ModelBlock->Block_List[count_Block].IM_lead_lag[i].Equ_X = (int*)malloc(tmp_size_exo[incidencematrix.Model_Max_Lag_Exo - Lag + i] * sizeof(int));
-          ModelBlock->Block_List[count_Block].IM_lead_lag[i].Equ_X_Index = (int*)malloc(tmp_size_exo[incidencematrix.Model_Max_Lag_Exo - Lag + i] * sizeof(int));
-         }
-         else
-         ModelBlock->Block_List[count_Block].IM_lead_lag[i].size_exo = 0;*/
-      ModelBlock->Block_List[count_Block].IM_lead_lag[i].u_init = l;
-      memset(tmp_variable_evaluated, 0, symbol_table.endo_nbr()*sizeof(bool));
-      IM = incidencematrix.Get_IM(i - Lag, eEndogenous);
-      if (IM)
-        {
-          for (j = first_count_equ; j < size + first_count_equ; j++)
-            {
-              i_1 = Index_Var_IM[j];
-              m = 0;
-              for (k = first_count_equ; k < size + first_count_equ; k++)
-                if (IM[i_1 + Index_Equ_IM[k] * symbol_table.endo_nbr()])
-                  m++;
-              if (m > 0)
-                {
-                  tmp_var[j - first_count_equ] = i1;
-                  i1++;
-                }
-            }
-          m = 0;
-          for (j = first_count_equ; j < size + first_count_equ; j++)
-            {
-              i_1 = Index_Equ_IM[j] * symbol_table.endo_nbr();
-              for (k = first_count_equ; k < size + first_count_equ; k++)
-                if (IM[Index_Var_IM[k] + i_1])
-                  {
-                    if (i == Lag)
-                      {
-                        ModelBlock->Block_List[count_Block].IM_lead_lag[i].us[m] = ls;
-                        ls++;
-                      }
-                    ModelBlock->Block_List[count_Block].IM_lead_lag[i].u[m] = li;
-                    ModelBlock->Block_List[count_Block].IM_lead_lag[i].Equ[m] = j - first_count_equ;
-                    ModelBlock->Block_List[count_Block].IM_lead_lag[i].Var[m] = k - first_count_equ;
-                    ModelBlock->Block_List[count_Block].IM_lead_lag[i].Equ_Index[m] = Index_Equ_IM[j];
-                    ModelBlock->Block_List[count_Block].IM_lead_lag[i].Var_Index[m] = Index_Var_IM[k];
-                    tmp_variable_evaluated[Index_Var_IM[k]] = true;
-                    l++;
-                    m++;
-                    li++;
-                  }
-            }
-          ModelBlock->Block_List[count_Block].IM_lead_lag[i].u_finish = li - 1;
-          m = 0;
-          for (j = first_count_equ; j < size + first_count_equ; j++)
-            {
-              i_1 = Index_Equ_IM[j] * symbol_table.endo_nbr();
-              for (k = 0; k < symbol_table.endo_nbr(); k++)
-                if ((!tmp_variable_evaluated[Index_Var_IM[k]]) && IM[Index_Var_IM[k] + i_1])
-                  {
-                    ModelBlock->Block_List[count_Block].IM_lead_lag[i].u_other_endo[m] = l;
-                    ModelBlock->Block_List[count_Block].IM_lead_lag[i].Equ_other_endo[m] = j - first_count_equ;
-                    ModelBlock->Block_List[count_Block].IM_lead_lag[i].Var_other_endo[m] = k;
-                    ModelBlock->Block_List[count_Block].IM_lead_lag[i].Equ_Index_other_endo[m] = Index_Equ_IM[j];
-                    ModelBlock->Block_List[count_Block].IM_lead_lag[i].Var_Index_other_endo[m] = Index_Var_IM[k];
-                    l++;
-                    m++;
-                  }
-            }
-          ModelBlock->Block_List[count_Block].IM_lead_lag[i].size_other_endo = m;
-        }
-      /*IM = incidencematrix.Get_IM(i - Lag, eExogenous);
-         if (IM)
-         {
-          m = 0;
-          for (j = first_count_equ;j < size + first_count_equ;j++)
-            {
-              i_1 = Index_Equ_IM[j] * symbol_table.exo_nbr();
-              for (k = 0; k<tmp_nb_exo; k++)
-                {
-                  if (IM[ModelBlock->Block_List[count_Block].Exogenous[k]+i_1])
-                    {
-                      ModelBlock->Block_List[count_Block].IM_lead_lag[i].Exogenous[m] = k;
-                      ModelBlock->Block_List[count_Block].IM_lead_lag[i].Exogenous_Index[m] = ModelBlock->Block_List[count_Block].Exogenous[k];
-                      ModelBlock->Block_List[count_Block].IM_lead_lag[i].Equ_X[m] = j - first_count_equ;
-                      ModelBlock->Block_List[count_Block].IM_lead_lag[i].Equ_X_Index[m] = Index_Equ_IM[j];
-                      m++;
-                    }
-                }
-            }
-         }*/
-    }
-  free(tmp_size);
-  free(tmp_size_other_endo);
-  free(tmp_size_exo);
-  free(tmp_endo);
-  free(tmp_other_endo);
-  free(tmp_exo);
-  free(tmp_var);
-  free(tmp_variable_evaluated);
-}
-
-void
-BlockTriangular::Free_Block(Model_Block *ModelBlock) const
-{
-  int blk, i;
-  for (blk = 0; blk < ModelBlock->Size; blk++)
-    {
-      free(ModelBlock->Block_List[blk].Equation);
-      free(ModelBlock->Block_List[blk].Variable);
-      free(ModelBlock->Block_List[blk].Exogenous);
-      free(ModelBlock->Block_List[blk].Own_Derivative);
-      free(ModelBlock->Block_List[blk].Other_Endogenous);
-      free(ModelBlock->Block_List[blk].Equation_Type);
-      free(ModelBlock->Block_List[blk].Equation_Normalized);
-      for (i = 0; i < ModelBlock->Block_List[blk].Max_Lag + ModelBlock->Block_List[blk].Max_Lead + 1; i++)
-        {
-          if (incidencematrix.Model_Max_Lag_Endo-ModelBlock->Block_List[blk].Max_Lag+i >= 0 /*&& ModelBlock->Block_List[blk].IM_lead_lag[i].size*/)
-            {
-              free(ModelBlock->Block_List[blk].IM_lead_lag[i].u);
-              free(ModelBlock->Block_List[blk].IM_lead_lag[i].us);
-              free(ModelBlock->Block_List[blk].IM_lead_lag[i].Equ);
-              free(ModelBlock->Block_List[blk].IM_lead_lag[i].Var);
-              free(ModelBlock->Block_List[blk].IM_lead_lag[i].Equ_Index);
-              free(ModelBlock->Block_List[blk].IM_lead_lag[i].Var_Index);
-              free(ModelBlock->Block_List[blk].IM_lead_lag[i].u_other_endo);
-              free(ModelBlock->Block_List[blk].IM_lead_lag[i].Var_other_endo);
-              free(ModelBlock->Block_List[blk].IM_lead_lag[i].Equ_other_endo);
-              free(ModelBlock->Block_List[blk].IM_lead_lag[i].Var_Index_other_endo);
-              free(ModelBlock->Block_List[blk].IM_lead_lag[i].Equ_Index_other_endo);
-            }
-          /*if (incidencematrix.Model_Max_Lag_Exo-ModelBlock->Block_List[blk].Max_Lag+i>=0 )
-             {
-              free(ModelBlock->Block_List[blk].IM_lead_lag[i].Exogenous);
-              free(ModelBlock->Block_List[blk].IM_lead_lag[i].Exogenous_Index);
-              free(ModelBlock->Block_List[blk].IM_lead_lag[i].Equ_X_Index);
-              free(ModelBlock->Block_List[blk].IM_lead_lag[i].Equ_X);
-             }*/
-        }
-      free(ModelBlock->Block_List[blk].IM_lead_lag);
-      for (i = 0; i < ModelBlock->Block_List[blk].Size; i++)
-        delete ModelBlock->Block_List[blk].Temporary_Terms_in_Equation[i];
-      free(ModelBlock->Block_List[blk].Temporary_Terms_in_Equation);
-      delete (ModelBlock->Block_List[blk].Temporary_InUse);
-      delete ModelBlock->Block_List[blk].Chain_Rule_Derivatives;
-    }
-  free(ModelBlock->Block_List);
-  free(ModelBlock);
-}
-
-t_etype
-BlockTriangular::Equation_Type_determination(vector<BinaryOpNode *> &equations, map<pair<int, pair<int, int> >, NodeID> &first_order_endo_derivatives, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM, int mfs)
-{
-  NodeID lhs, rhs;
-  ostringstream tmp_output;
-  BinaryOpNode *eq_node;
-  ostringstream tmp_s;
-  temporary_terms_type temporary_terms;
-  EquationType Equation_Simulation_Type;
-  t_etype V_Equation_Simulation_Type(equations.size());
-  for (unsigned int i = 0; i < equations.size(); i++)
-    {
-      temporary_terms.clear();
-      int eq = Index_Equ_IM[i];
-      int var = Index_Var_IM[i];
-      eq_node = equations[eq];
-      lhs = eq_node->get_arg1();
-      rhs = eq_node->get_arg2();
-      Equation_Simulation_Type = E_SOLVE;
-      tmp_s.str("");
-      tmp_output.str("");
-      lhs->writeOutput(tmp_output, oMatlabDynamicModelSparse, temporary_terms);
-      tmp_s << "y(it_, " << Index_Var_IM[i]+1 << ")";
-      map<pair<int, pair<int, int> >, NodeID>::iterator derivative = first_order_endo_derivatives.find(make_pair(eq, make_pair(var, 0)));
-      pair<bool, NodeID> res;
-      if(derivative != first_order_endo_derivatives.end())
-        {
-          set<pair<int, int> > result;
-          derivative->second->collectEndogenous(result);
-          set<pair<int, int> >::const_iterator d_endo_variable = result.find(make_pair(var, 0));
-          //Determine whether the equation could be evaluated rather than to be solved
-          ostringstream tt("");
-          derivative->second->writeOutput(tt, oMatlabDynamicModelSparse, temporary_terms);
-          if (tmp_output.str() == tmp_s.str() and tt.str()=="1")
-            {
-              Equation_Simulation_Type = E_EVALUATE;
-            }
-          else
-            {
-        	    vector<pair<int, pair<NodeID, NodeID> > > List_of_Op_RHS;
-              res =  equations[eq]->normalizeEquation(var, List_of_Op_RHS);
-              if(mfs==2)
-                {
-                  if(d_endo_variable == result.end() && res.second)
-                    Equation_Simulation_Type = E_EVALUATE_S;
-                }
-              else if(mfs==3)
-                {
-                  if(res.second) // The equation could be solved analytically
-                    Equation_Simulation_Type = E_EVALUATE_S;
-                }
-            }
-        }
-      V_Equation_Simulation_Type[eq] = make_pair(Equation_Simulation_Type, dynamic_cast<BinaryOpNode *>(res.second));
-    }
-  return (V_Equation_Simulation_Type);
-}
-
-t_type
-BlockTriangular::Reduce_Blocks_and_type_determination(int prologue, int epilogue, vector<pair<int, int> > &blocks, vector<BinaryOpNode *> &equations, t_etype &Equation_Type, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM)
-{
-  int i = 0;
-  int count_equ = 0, blck_count_simult = 0;
-  int Blck_Size, Recurs_Size;
-  int Lead, Lag;
-  t_type Type;
-  bool *Cur_IM;
-  BlockSimulationType Simulation_Type, prev_Type = UNKNOWN;
-  int eq = 0;
-  for (i = 0; i < prologue+(int) blocks.size()+epilogue; i++)
-    {
-      int first_count_equ = count_equ;
-      if (i < prologue)
-        {
-          Blck_Size = 1;
-          Recurs_Size = 0;
-        }
-      else if (i < prologue+(int) blocks.size())
-        {
-          Blck_Size = blocks[blck_count_simult].first;
-          Recurs_Size = Blck_Size - blocks[blck_count_simult].second;
-          blck_count_simult++;
-        }
-      else if (i < prologue+(int) blocks.size()+epilogue)
-        {
-          Blck_Size = 1;
-          Recurs_Size = 0;
-        }
-
-      Lag = Lead = 0;
-      for (count_equ = first_count_equ; count_equ < Blck_Size+first_count_equ; count_equ++)
-        {
-          int i_1 = Index_Var_IM[count_equ];
-          for (int k = -incidencematrix.Model_Max_Lag_Endo; k <= incidencematrix.Model_Max_Lead_Endo; k++)
-            {
-              Cur_IM = incidencematrix.Get_IM(k, eEndogenous);
-              if (Cur_IM)
-                {
-                  for (int j = 0; j < Blck_Size; j++)
-                    {
-                      if (Cur_IM[i_1 + Index_Equ_IM[first_count_equ + j] * symbol_table.endo_nbr()])
-                        {
-                          if (k > Lead)
-                            Lead = k;
-                          else if (-k > Lag)
-                            Lag = -k;
-                        }
-                    }
-                }
-            }
-        }
-      if ((Lag > 0) && (Lead > 0))
-        {
-          if (Blck_Size == 1)
-            Simulation_Type = SOLVE_TWO_BOUNDARIES_SIMPLE;
-          else
-            Simulation_Type = SOLVE_TWO_BOUNDARIES_COMPLETE;
-        }
-      else if (Blck_Size > 1)
-        {
-          if (Lead > 0)
-            Simulation_Type = SOLVE_BACKWARD_COMPLETE;
-          else
-            Simulation_Type = SOLVE_FORWARD_COMPLETE;
-        }
-      else
-        {
-          if (Lead > 0)
-            Simulation_Type = SOLVE_BACKWARD_SIMPLE;
-          else
-            Simulation_Type = SOLVE_FORWARD_SIMPLE;
-        }
-      if (Blck_Size == 1)
-        {
-          if (Equation_Type[Index_Equ_IM[eq]].first == E_EVALUATE /*or Equation_Type[Index_Equ_IM[eq]].first==E_EVALUATE_R*/ or Equation_Type[Index_Equ_IM[eq]].first == E_EVALUATE_S)
-            {
-              if (Simulation_Type == SOLVE_BACKWARD_SIMPLE)
-                Simulation_Type = EVALUATE_BACKWARD;
-              else if (Simulation_Type == SOLVE_FORWARD_SIMPLE)
-                Simulation_Type = EVALUATE_FORWARD;
-            }
-          if (i > 0)
-            {
-              if ((prev_Type ==  EVALUATE_FORWARD and Simulation_Type == EVALUATE_FORWARD)
-                  or (prev_Type ==  EVALUATE_BACKWARD and Simulation_Type == EVALUATE_BACKWARD))
-                {
-                  BlockSimulationType c_Type = (Type[Type.size()-1]).first;
-                  int c_Size = (Type[Type.size()-1]).second.first;
-                  Type[Type.size()-1] = make_pair(c_Type, make_pair(++c_Size, Type[Type.size()-1].second.second));
-                }
-              else
-                Type.push_back(make_pair(Simulation_Type, make_pair(Blck_Size, Recurs_Size)));
-            }
-          else
-            Type.push_back(make_pair(Simulation_Type, make_pair(Blck_Size, Recurs_Size)));
-        }
-      else
-        {
-          Type.push_back(make_pair(Simulation_Type, make_pair(Blck_Size, Recurs_Size)));
-        }
-      prev_Type = Simulation_Type;
-      eq += Blck_Size;
-    }
-  return (Type);
-}
-
-
-map<pair<pair<int, pair<int, int> >, pair<int, int> >, int>
-BlockTriangular::get_Derivatives(Model_Block *ModelBlock, int blck)
-{
-  map<pair<pair<int, pair<int, int> >, pair<int, int> >, int> Derivatives;
-  Derivatives.clear();
-  int nb_endo = symbol_table.endo_nbr();
-  /*ModelBlock.Block_List[Blck].first_order_determinstic_simulation_derivatives = new*/
-  for(int lag = -ModelBlock->Block_List[blck].Max_Lag; lag <= ModelBlock->Block_List[blck].Max_Lead; lag++)
-    {
-      bool *IM=incidencematrix.Get_IM(lag, eEndogenous);
-      if(IM)
-        {
-          for(int eq = 0; eq < ModelBlock->Block_List[blck].Size; eq++)
-            {
-              int eqr = ModelBlock->Block_List[blck].Equation[eq];
-              for(int var = 0; var < ModelBlock->Block_List[blck].Size; var++)
-                {
-                  int varr = ModelBlock->Block_List[blck].Variable[var];
-                  /*cout << "IM=" << IM << "\n";
-                  cout << "varr=" << varr << " eqr=" << eqr << " lag=" << lag << "\n";*/
-                  if(IM[varr+eqr*nb_endo])
-                    {
-                      bool OK = true;
-                      map<pair<pair<int, pair<int, int> >, pair<int, int> >, int>::const_iterator its = Derivatives.find(make_pair(make_pair(lag, make_pair(eq, var)), make_pair(eqr, varr)));
-                      if(its!=Derivatives.end())
-                        {
-                        	if(its->second == 2)
-                        	  OK=false;
-                        }
-
-                      if(OK)
-                        {
-                          if (ModelBlock->Block_List[blck].Equation_Type[eq] == E_EVALUATE_S and eq<ModelBlock->Block_List[blck].Nb_Recursives)
-                            //It's a normalized equation, we have to recompute the derivative using chain rule derivative function*/
-                            Derivatives[make_pair(make_pair(lag, make_pair(eq, var)), make_pair(eqr, varr))] = 1;
-                          else
-                            //It's a feedback equation we can use the derivatives
-                            Derivatives[make_pair(make_pair(lag, make_pair(eq, var)), make_pair(eqr, varr))] = 0;
-                        }
-                      if(var<ModelBlock->Block_List[blck].Nb_Recursives)
-                        {
-                          int eqs = ModelBlock->Block_List[blck].Equation[var];
-                          for(int vars=ModelBlock->Block_List[blck].Nb_Recursives; vars<ModelBlock->Block_List[blck].Size; vars++)
-                            {
-                              int varrs = ModelBlock->Block_List[blck].Variable[vars];
-                              //A new derivative need to be computed using the chain rule derivative function (a feedback variable appear in a recursive equation)
-                              if(Derivatives.find(make_pair(make_pair(lag, make_pair(var, vars)), make_pair(eqs, varrs)))!=Derivatives.end())
-                                Derivatives[make_pair(make_pair(lag, make_pair(eq, vars)), make_pair(eqr, varrs))] = 2;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-	return(Derivatives);
-}
-
-void
-BlockTriangular::Normalize_and_BlockDecompose(bool *IM, Model_Block *ModelBlock, int n, int &prologue, int &epilogue, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM, bool *IM_0, jacob_map &j_m, vector<BinaryOpNode *> &equations, t_etype &V_Equation_Type, map<pair<int, pair<int, int> >, NodeID> &first_order_endo_derivatives, bool dynamic, int mfs, double cutoff)
-{
-  int i, j, Nb_TotalBlocks, Nb_RecursBlocks, Nb_SimulBlocks;
-  BlockType Btype;
-  int count_Block, count_Equ;
-  bool *SIM0, *SIM00;
-
-
-
-  int counted = 0;
-  if (prologue+epilogue < n)
-    {
-      cout << "Normalizing the model ...\n";
-      double *max_val = (double *) malloc(n*sizeof(double));
-      memset(max_val, 0, n*sizeof(double));
-      for (map< pair< int, int >, double >::iterator iter = j_m.begin(); iter != j_m.end(); iter++)
-        {
-          if (fabs(iter->second) > max_val[iter->first.first])
-            max_val[iter->first.first] = fabs(iter->second);
-        }
-      for (map< pair< int, int >, double >::iterator iter = j_m.begin(); iter != j_m.end(); iter++)
-        iter->second /= max_val[iter->first.first];
-      free(max_val);
-      bool OK = false;
-      double bi = 0.99999999;
-      //double bi=1e-13;
-      int suppressed = 0;
-      vector<int> Index_Equ_IM_save(Index_Equ_IM);
-      while (!OK && bi > 1e-19)
-        {
-          int suppress = 0;
-          Index_Equ_IM = Index_Equ_IM_save;
-          SIM0 = (bool *) malloc(n * n * sizeof(bool));
-          memset(SIM0, 0, n*n*sizeof(bool));
-          SIM00 = (bool *) malloc(n * n * sizeof(bool));
-          memset(SIM00, 0, n*n*sizeof(bool));
-          //cout << "---------------------------------\n";
-          for (map< pair< int, int >, double >::iterator iter = j_m.begin(); iter != j_m.end(); iter++)
-            {
-            	//printf("iter->second=% 1.10f iter->first.first=%3d iter->first.second=%3d  bi=%f\n", iter->second, iter->first.first, iter->first.second, bi);
-              if (fabs(iter->second) > max(bi, cutoff))
-                {
-                  SIM0[iter->first.first*n+iter->first.second] = 1;
-                  if (!IM_0[iter->first.first*n+iter->first.second])
-                    {
-                      cout << "Error nothing at IM_0[" << iter->first.first << ", " << iter->first.second << "]=" << IM_0[iter->first.first*n+iter->first.second] << "  " << iter->second << "\n";
-                    }
-                }
-              else
-                suppress++;
-            }
-          for (i = 0; i < n; i++)
-            for (j = 0; j < n; j++)
-              {
-                SIM00[i*n + j] = SIM0[Index_Equ_IM[i] * n + Index_Var_IM[j]];
-              }
-          free(SIM0);
-          if (suppress != suppressed)
-            OK = Compute_Normalization(IM, n, prologue, epilogue, 0, SIM00, Index_Equ_IM);
-          suppressed = suppress;
-          if (!OK)
-            //bi/=1.07;
-            bi /= 2;
-          counted++;
-          if (bi > 1e-19)
-            free(SIM00);
-        }
-      if (!OK)
-        {
-          Compute_Normalization(IM, n, prologue, epilogue, 1, SIM00, Index_Equ_IM);
-          Compute_Normalization(IM, n, prologue, epilogue, 2, IM_0, Index_Equ_IM);
-        }
-    }
-  SIM0 = (bool *) malloc(n * n * sizeof(bool));
-  memcpy(SIM0, IM_0, n*n*sizeof(bool));
-  Prologue_Epilogue(IM, prologue, epilogue, n, Index_Var_IM, Index_Equ_IM, SIM0);
-
-  free(SIM0);
-
-  V_Equation_Type = Equation_Type_determination(equations, first_order_endo_derivatives, Index_Var_IM, Index_Equ_IM, mfs);
-
-  cout << "Finding the optimal block decomposition of the model ...\n";
-  vector<pair<int, int> > blocks;
-  if (prologue+epilogue < n)
-    {
-      if(dynamic)
-        Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Block(IM, n, prologue, epilogue, Index_Equ_IM, Index_Var_IM, blocks, V_Equation_Type, false, true, mfs);
-      else
-        Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Block(IM, n, prologue, epilogue, Index_Equ_IM, Index_Var_IM, blocks, V_Equation_Type, false, false, mfs);
-    }
-
-  t_type  Type = Reduce_Blocks_and_type_determination(prologue, epilogue, blocks, equations, V_Equation_Type, Index_Var_IM, Index_Equ_IM);
-
-  i = 0;
-  j = 0;
-  Nb_SimulBlocks = 0;
-  int Nb_feedback_variable = 0;
-  for (t_type::const_iterator it = Type.begin(); it != Type.end(); it++)
-    {
-      if (it->first == SOLVE_FORWARD_COMPLETE || it->first == SOLVE_BACKWARD_COMPLETE || it->first == SOLVE_TWO_BOUNDARIES_COMPLETE)
-        {
-          Nb_SimulBlocks++;
-          if (it->second.first > j)
-            {
-              j = it->second.first;
-              Nb_feedback_variable = blocks[Nb_SimulBlocks-1].second;
-            }
-        }
-    }
-
-  Nb_TotalBlocks = Type.size();
-  Nb_RecursBlocks = Nb_TotalBlocks - Nb_SimulBlocks;
-  cout << Nb_TotalBlocks << " block(s) found:\n";
-  cout << "  " << Nb_RecursBlocks << " recursive block(s) and " << blocks.size() << " simultaneous block(s). \n";
-  cout << "  the largest simultaneous block has " << j     << " equation(s)\n"
-       <<"                                 and " << Nb_feedback_variable << " feedback variable(s).\n";
-
-  ModelBlock->Size = Nb_TotalBlocks;
-  ModelBlock->Periods = periods;
-  ModelBlock->Block_List = (Block *) malloc(sizeof(ModelBlock->Block_List[0]) * Nb_TotalBlocks);
-
-  count_Equ = count_Block = 0;
-
-
-
-  for (t_type::const_iterator it = Type.begin(); it != Type.end(); it++)
-    {
-      if (count_Equ < prologue)
-        Btype = PROLOGUE;
-      else if (count_Equ < n-epilogue)
-        if (it->second.first == 1)
-          Btype = PROLOGUE;
-        else
-          {
-            Btype = SIMULTANS;
-          }
-      else
-        Btype = EPILOGUE;
-      Allocate_Block(it->second.first, &count_Equ, count_Block++, Btype, it->first, ModelBlock, V_Equation_Type, it->second.second, Index_Var_IM, Index_Equ_IM);
-    }
-}
-
-//------------------------------------------------------------------------------
-// normalize each equation of the dynamic model
-// and find the optimal block triangular decomposition of the static model
-void
-BlockTriangular::Normalize_and_BlockDecompose_Static_0_Model(jacob_map &j_m, vector<BinaryOpNode *> &equations, t_etype &equation_simulation_type, map<pair<int, pair<int, int> >, NodeID> &first_order_endo_derivatives, int mfs, double cutoff)
-{
-  bool *SIM, *SIM_0;
-  bool *Cur_IM;
-  int i, k, size;
-  //First create a static model incidence matrix
-  size = symbol_table.endo_nbr() * symbol_table.endo_nbr() * sizeof(*SIM);
-  SIM = (bool *) malloc(size);
-  for (i = 0; i < symbol_table.endo_nbr() * symbol_table.endo_nbr(); i++) SIM[i] = 0;
-  for (k = -incidencematrix.Model_Max_Lag_Endo; k <= incidencematrix.Model_Max_Lead_Endo; k++)
-    {
-      Cur_IM = incidencematrix.Get_IM(k, eEndogenous);
-      if (Cur_IM)
-        {
-          for (i = 0; i < symbol_table.endo_nbr()*symbol_table.endo_nbr(); i++)
-            {
-              SIM[i] = (SIM[i]) || (Cur_IM[i]);
-            }
-        }
-    }
-  if (bt_verbose)
-    {
-      cout << "incidence matrix for the static model (unsorted) \n";
-      incidencematrix.Print_SIM(SIM, eEndogenous);
-    }
-  Index_Equ_IM = vector<int>(symbol_table.endo_nbr());
-  for (i = 0; i < symbol_table.endo_nbr(); i++)
-    {
-      Index_Equ_IM[i] = i;
-    }
-  Index_Var_IM = vector<int>(symbol_table.endo_nbr());
-  for (i = 0; i < symbol_table.endo_nbr(); i++)
-    {
-      Index_Var_IM[i] = i;
-    }
-  if (ModelBlock != NULL)
-    Free_Block(ModelBlock);
-  ModelBlock = (Model_Block *) malloc(sizeof(*ModelBlock));
-  Cur_IM = incidencematrix.Get_IM(0, eEndogenous);
-  SIM_0 = (bool *) malloc(symbol_table.endo_nbr() * symbol_table.endo_nbr() * sizeof(*SIM_0));
-  for (i = 0; i < symbol_table.endo_nbr()*symbol_table.endo_nbr(); i++)
-    SIM_0[i] = Cur_IM[i];
-  Normalize_and_BlockDecompose(SIM, ModelBlock, symbol_table.endo_nbr(), prologue, epilogue, Index_Var_IM, Index_Equ_IM, SIM_0, j_m, equations, equation_simulation_type, first_order_endo_derivatives, true, mfs, cutoff);
-  free(SIM_0);
-  free(SIM);
-}
diff --git a/BlockTriangular.hh b/BlockTriangular.hh
deleted file mode 100644
index c0ebfb4bb2cb96126c81ba6e7b9513a5ea633e31..0000000000000000000000000000000000000000
--- a/BlockTriangular.hh
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2007-2008 Dynare Team
- *
- * This file is part of Dynare.
- *
- * Dynare is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Dynare is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _BLOCKTRIANGULAR_HH
-#define _BLOCKTRIANGULAR_HH
-
-#include <string>
-#include "CodeInterpreter.hh"
-#include "ExprNode.hh"
-#include "SymbolTable.hh"
-//#include "ModelNormalization.hh"
-//#include "ModelBlocks.hh"
-#include "IncidenceMatrix.hh"
-#include "ModelTree.hh"
-
-
-
-//! Sparse matrix of double to store the values of the Jacobian
-typedef map<pair<int ,int >,double> jacob_map;
-
-typedef vector<pair<BlockSimulationType, pair<int, int> > > t_type;
-
-//! Vector describing equations: BlockSimulationType, if BlockSimulationType == EVALUATE_s then a NodeID on the new normalized equation
-typedef vector<pair<EquationType, NodeID > > t_etype;
-
-//! Vector describing variables: max_lag in the block, max_lead in the block
-typedef vector<pair< int, int> > t_vtype;
-
-typedef set<int> temporary_terms_inuse_type;
-
-typedef vector<pair< pair<int, pair<int, int> >, pair<int, int> > > chain_rule_derivatives_type;
-
-//! For one lead/lag of one block, stores mapping of information between original model and block-decomposed model
-struct IM_compact
-{
-  int size, u_init, u_finish, nb_endo, nb_other_endo, size_exo, size_other_endo;
-  int *u, *us, *Var, *Equ, *Var_Index, *Equ_Index, *Exogenous, *Exogenous_Index, *Equ_X, *Equ_X_Index;
-  int *u_other_endo, *Var_other_endo, *Equ_other_endo, *Var_Index_other_endo, *Equ_Index_other_endo;
-};
-
-//! One block of the model
-struct Block
-{
-  int Size, Sized, nb_exo, nb_exo_det, nb_other_endo, Nb_Recursives;
-  BlockType Type;
-  BlockSimulationType Simulation_Type;
-  int Max_Lead, Max_Lag, Nb_Lead_Lag_Endo;
-  int Max_Lag_Endo, Max_Lead_Endo;
-  int Max_Lag_Other_Endo, Max_Lead_Other_Endo;
-  int Max_Lag_Exo, Max_Lead_Exo;
-  bool is_linear;
-  int *Equation, *Own_Derivative;
-  EquationType *Equation_Type;
-  NodeID *Equation_Normalized;
-  int *Variable, *Other_Endogenous, *Exogenous;
-  temporary_terms_type **Temporary_Terms_in_Equation;
-  //temporary_terms_type *Temporary_terms;
-  temporary_terms_inuse_type *Temporary_InUse;
-  IM_compact *IM_lead_lag;
-	chain_rule_derivatives_type *Chain_Rule_Derivatives;
-  int Code_Start, Code_Length;
-};
-
-
-
-//! The set of all blocks of the model
-struct Model_Block
-{
-  int Size, Periods;
-  Block* Block_List;
-  //int *in_Block_Equ, *in_Block_Var, *in_Equ_of_Block, *in_Var_of_Block;
-};
-
-
-//! Creates the incidence matrix, computes prologue & epilogue, normalizes the model and computes the block decomposition
-class BlockTriangular
-{
-private:
-  //! Find equations and endogenous variables belonging to the prologue and epilogue of the model
-  void Prologue_Epilogue(bool* IM, int &prologue, int &epilogue, int n, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM, bool* IM0);
-  //! Allocates and fills the Model structure describing the content of each block
-  void Allocate_Block(int size, int *count_Equ, int count_Block, BlockType type, BlockSimulationType SimType, Model_Block *ModelBlock, t_etype &Equation_Type, int recurs_Size, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM);
-  //! Finds a matching between equations and endogenous variables
-  bool Compute_Normalization(bool *IM, int equation_number, int prologue, int epilogue, int verbose, bool *IM0, vector<int> &Index_Var_IM) const;
-  //! Decomposes into recurive blocks the non purely recursive equations and determines for each block the minimum feedback variables
-  void Compute_Block_Decomposition_and_Feedback_Variables_For_Each_Block(bool *IM, int nb_var, int prologue, int epilogue, vector<int> &Index_Equ_IM, vector<int> &Index_Var_IM, vector<pair<int, int> > &blocks, t_etype &Equation_Type, bool verbose_, bool select_feedback_variable, int mfs) const;
-  //! determines the type of each equation of the model (could be evaluated or need to be solved)
-  t_etype Equation_Type_determination(vector<BinaryOpNode *> &equations, map<pair<int, pair<int, int> >, NodeID> &first_order_endo_derivatives, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM, int mfs);
-  //! Tries to merge the consecutive blocks in a single block and determine the type of each block: recursive, simultaneous, ...
-  t_type Reduce_Blocks_and_type_determination(int prologue, int epilogue, vector<pair<int, int> > &blocks, vector<BinaryOpNode *> &equations, t_etype &Equation_Type, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM);
-  //! Compute for each variable its maximum lead and lag in its block
-  t_vtype Get_Variable_LeadLag_By_Block(vector<int > &components_set, int nb_blck_sim, int prologue, int epilogue, t_vtype &equation_lead_lag) const;
-public:
-  SymbolTable &symbol_table;
-  /*Blocks blocks;
-  Normalization normalization;*/
-  IncidenceMatrix incidencematrix;
-  NumericalConstants &num_const;
-  DataTree *Normalized_Equation;
-  BlockTriangular(SymbolTable &symbol_table_arg, NumericalConstants &num_const_arg);
-  ~BlockTriangular();
-  //! Frees the Model structure describing the content of each block
-  void Free_Block(Model_Block* ModelBlock) const;
-
-  map<pair<pair<int, pair<int, int> >, pair<int, int> >, int> get_Derivatives(Model_Block *ModelBlock, int Blck);
-
-
-  void Normalize_and_BlockDecompose_Static_0_Model(jacob_map &j_m, vector<BinaryOpNode *> &equations, t_etype &V_Equation_Type, map<pair<int, pair<int, int> >, NodeID> &first_order_endo_derivatives, int mfs, double cutoff);
-  void Normalize_and_BlockDecompose(bool* IM, Model_Block* ModelBlock, int n, int &prologue, int &epilogue, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM, bool* IM_0 , jacob_map &j_m, vector<BinaryOpNode *> &equations, t_etype &equation_simulation_type, map<pair<int, pair<int, int> >, NodeID> &first_order_endo_derivatives, bool dynamic, int mfs, double cutoff);
-  vector<int> Index_Equ_IM;
-  vector<int> Index_Var_IM;
-  int prologue, epilogue;
-  bool bt_verbose;
-  Model_Block* ModelBlock;
-  int periods;
-  inline static std::string BlockType0(int type)
-  {
-    switch (type)
-      {
-      case 0:
-        return ("SIMULTANEOUS TIME SEPARABLE  ");
-        break;
-      case 1:
-        return ("PROLOGUE                     ");
-        break;
-      case 2:
-        return ("EPILOGUE                     ");
-        break;
-      case 3:
-        return ("SIMULTANEOUS TIME UNSEPARABLE");
-        break;
-      default:
-        return ("UNKNOWN                      ");
-        break;
-      }
-  };
-  inline static std::string BlockSim(int type)
-  {
-    switch (type)
-      {
-      case EVALUATE_FORWARD:
-      //case EVALUATE_FORWARD_R:
-        return ("EVALUATE FORWARD             ");
-        break;
-      case EVALUATE_BACKWARD:
-      //case EVALUATE_BACKWARD_R:
-        return ("EVALUATE BACKWARD            ");
-        break;
-      case SOLVE_FORWARD_SIMPLE:
-        return ("SOLVE FORWARD SIMPLE         ");
-        break;
-      case SOLVE_BACKWARD_SIMPLE:
-        return ("SOLVE BACKWARD SIMPLE        ");
-        break;
-      case SOLVE_TWO_BOUNDARIES_SIMPLE:
-        return ("SOLVE TWO BOUNDARIES SIMPLE  ");
-        break;
-      case SOLVE_FORWARD_COMPLETE:
-        return ("SOLVE FORWARD COMPLETE       ");
-        break;
-      case SOLVE_BACKWARD_COMPLETE:
-        return ("SOLVE BACKWARD COMPLETE      ");
-        break;
-      case SOLVE_TWO_BOUNDARIES_COMPLETE:
-        return ("SOLVE TWO BOUNDARIES COMPLETE");
-        break;
-      default:
-        return ("UNKNOWN                      ");
-        break;
-      }
-  };
-  inline static std::string c_Equation_Type(int type)
-  {
-    char c_Equation_Type[4][13]=
-    {
-    "E_UNKNOWN   ",
-    "E_EVALUATE  ",
-    "E_EVALUATE_S",
-    "E_SOLVE     "
-    };
-    return(c_Equation_Type[type]);
-  };
-};
-#endif
diff --git a/CodeInterpreter.hh b/CodeInterpreter.hh
index abfa44d1f9bf55acdefe9826632ff16a4cc238af..ae9251588fd7dc6e5ff534043e1b0a62d66f4159 100644
--- a/CodeInterpreter.hh
+++ b/CodeInterpreter.hh
@@ -100,10 +100,10 @@ enum Tags
 
 enum BlockType
   {
-    SIMULTANS = 0, //!< Simultaneous time separable block
-    PROLOGUE = 1,  //!< Prologue block (one equation at the beginning, later merged)
-    EPILOGUE = 2,  //!< Epilogue block (one equation at the beginning, later merged)
-    SIMULTAN = 3   //!< Simultaneous time unseparable block
+    SIMULTANS,  //!< Simultaneous time separable block
+    PROLOGUE,   //!< Prologue block (one equation at the beginning, later merged)
+    EPILOGUE,   //!< Epilogue block (one equation at the beginning, later merged)
+    SIMULTAN    //!< Simultaneous time unseparable block
   };
 
 enum EquationType
@@ -126,7 +126,7 @@ enum BlockSimulationType
     SOLVE_TWO_BOUNDARIES_SIMPLE,  //!< Block of one equation, newton solver needed, forward & ackward
     SOLVE_FORWARD_COMPLETE,       //!< Block of several equations, newton solver needed, forward
     SOLVE_BACKWARD_COMPLETE,      //!< Block of several equations, newton solver needed, backward
-    SOLVE_TWO_BOUNDARIES_COMPLETE,//!< Block of several equations, newton solver needed, forward and backwar
+    SOLVE_TWO_BOUNDARIES_COMPLETE //!< Block of several equations, newton solver needed, forward and backwar
   };
 
 //! Enumeration of possible symbol types
@@ -475,9 +475,8 @@ private:
   uint8_t op_code;
   int size;
   uint8_t type;
-  int *variable;
-  int *equation;
-  int *own_derivatives;
+  vector<int> variable;
+  vector<int> equation;
   bool is_linear;
   vector<Block_contain_type> Block_Contain_;
   int endo_nbr;
@@ -485,11 +484,14 @@ private:
   int Max_Lead;
   int u_count_int;
 public:
-  inline FBEGINBLOCK_(){ op_code = FBEGINBLOCK; size = 0; type = UNKNOWN; variable = NULL; equation = NULL; own_derivatives = NULL;
+  inline FBEGINBLOCK_(){ op_code = FBEGINBLOCK; size = 0; type = UNKNOWN; /*variable = NULL; equation = NULL;*/
            is_linear = false; endo_nbr = 0; Max_Lag = 0; Max_Lead = 0; u_count_int = 0;};
-  inline FBEGINBLOCK_(const int size_arg, const BlockSimulationType type_arg, int *variable_arg, int *equation_arg, int *own_derivatives_arg,
-                      bool is_linear_arg, int endo_nbr_arg, int Max_Lag_arg, int Max_Lead_arg, int u_count_int_arg)
-         { op_code = FBEGINBLOCK; size = size_arg; type = type_arg; variable = variable_arg; equation = equation_arg; own_derivatives = own_derivatives_arg;
+  inline FBEGINBLOCK_(unsigned int &size_arg, BlockSimulationType &type_arg, int unsigned first_element, int unsigned &block_size,
+                      const vector<int> &variable_arg, const vector<int> &equation_arg,
+                      bool is_linear_arg, int endo_nbr_arg, int Max_Lag_arg, int Max_Lead_arg, int &u_count_int_arg)
+         { op_code = FBEGINBLOCK; size = size_arg; type = type_arg;
+           variable = vector<int>(variable_arg.begin()+first_element, variable_arg.begin()+(first_element+block_size));
+           equation = vector<int>(equation_arg.begin()+first_element, equation_arg.begin()+(first_element+block_size));
            is_linear = is_linear_arg; endo_nbr = endo_nbr_arg; Max_Lag = Max_Lag_arg; Max_Lead = Max_Lead_arg; u_count_int = u_count_int_arg;/*Block_Contain.clear();*/};
   inline unsigned int get_size() { return size;};
   inline uint8_t get_type() { return type;};
@@ -508,7 +510,6 @@ public:
        {
          CompileCode.write(reinterpret_cast<char *>(&variable[i]), sizeof(variable[0]));
          CompileCode.write(reinterpret_cast<char *>(&equation[i]), sizeof(equation[0]));
-         CompileCode.write(reinterpret_cast<char *>(&own_derivatives[i]), sizeof(own_derivatives[0]));
        }
      if (type==SOLVE_TWO_BOUNDARIES_SIMPLE || type==SOLVE_TWO_BOUNDARIES_COMPLETE ||
          type==SOLVE_BACKWARD_COMPLETE || type==SOLVE_FORWARD_COMPLETE)
@@ -532,7 +533,6 @@ public:
           Block_contain_type bc;
           memcpy(&bc.Variable, code, sizeof(bc.Variable)); code += sizeof(bc.Variable);
           memcpy(&bc.Equation, code, sizeof(bc.Equation)); code += sizeof(bc.Equation);
-          memcpy(&bc.Own_Derivative, code, sizeof(bc.Own_Derivative)); code += sizeof(bc.Own_Derivative);
           Block_Contain_.push_back(bc);
         }
        if (type==SOLVE_TWO_BOUNDARIES_SIMPLE || type==SOLVE_TWO_BOUNDARIES_COMPLETE ||
diff --git a/ComputingTasks.cc b/ComputingTasks.cc
index dc109d5cb0f5eb60dff999a96a4e043e21690edc..949c21f093b12f1e6632c3d542c7389232dfed72 100644
--- a/ComputingTasks.cc
+++ b/ComputingTasks.cc
@@ -876,13 +876,13 @@ PlannerObjectiveStatement::checkPass(ModFileStructure &mod_file_struct)
 void
 PlannerObjectiveStatement::computingPass()
 {
-  model_tree->computingPass(false, true, false);
+  model_tree->computingPass(eval_context_type(), false, true, false);
 }
 
 void
 PlannerObjectiveStatement::writeOutput(ostream &output, const string &basename) const
 {
-  model_tree->writeStaticFile(basename + "_objective", false);
+  model_tree->writeStaticFile(basename + "_objective", false, false);
 }
 
 BVARDensityStatement::BVARDensityStatement(int maxnlags_arg, const OptionsList &options_list_arg) :
diff --git a/DynamicModel.cc b/DynamicModel.cc
index ce95029dbd6535176e9e9788f8b748ac2427a5b2..90f3d22959e89f360d3fc563c53c3f7a2a846882 100644
--- a/DynamicModel.cc
+++ b/DynamicModel.cc
@@ -23,6 +23,7 @@
 #include <cassert>
 #include <cstdio>
 #include <cerrno>
+#include <algorithm>
 #include "DynamicModel.hh"
 
 // For mkdir() and chdir()
@@ -42,9 +43,9 @@ DynamicModel::DynamicModel(SymbolTable &symbol_table_arg,
     max_exo_lag(0), max_exo_lead(0),
     max_exo_det_lag(0), max_exo_det_lead(0),
     dynJacobianColsNbr(0),
+    global_temporary_terms(true),
     cutoff(1e-15),
-    mfs(0),
-    block_triangular(symbol_table_arg, num_constants_arg)
+    mfs(0)
 {
 }
 
@@ -57,12 +58,10 @@ DynamicModel::AddVariable(int symb_id, int lag)
 void
 DynamicModel::compileDerivative(ofstream &code_file, int eq, int symb_id, int lag, map_idx_type &map_idx) const
   {
-    //first_derivatives_type::const_iterator it = first_derivatives.find(make_pair(eq, getDerivID(symb_id, lag)));
     first_derivatives_type::const_iterator it = first_derivatives.find(make_pair(eq, getDerivID(symbol_table.getID(eEndogenous, symb_id), lag)));
     if (it != first_derivatives.end())
       (it->second)->compile(code_file, false, temporary_terms, map_idx, true, false);
     else
-      /*code_file.write(&FLDZ, sizeof(FLDZ));*/
       {
         FLDZ_ fldz;
         fldz.write(code_file);
@@ -81,240 +80,178 @@ DynamicModel::compileChainRuleDerivative(ofstream &code_file, int eqr, int varr,
       FLDZ_ fldz;
       fldz.write(code_file);
     }
-    //code_file.write(&FLDZ, sizeof(FLDZ));
 }
 
 
 void
-DynamicModel::BuildIncidenceMatrix()
-{
-  set<pair<int, int> > endogenous, exogenous;
-  for (int eq = 0; eq < (int) equations.size(); eq++)
-    {
-      BinaryOpNode *eq_node = equations[eq];
-      endogenous.clear();
-      NodeID Id = eq_node->get_arg1();
-      Id->collectEndogenous(endogenous);
-      Id = eq_node->get_arg2();
-      Id->collectEndogenous(endogenous);
-      for (set<pair<int, int> >::iterator it_endogenous=endogenous.begin();it_endogenous!=endogenous.end();it_endogenous++)
-        {
-          block_triangular.incidencematrix.fill_IM(eq, it_endogenous->first, it_endogenous->second, eEndogenous);
-        }
-      exogenous.clear();
-      Id = eq_node->get_arg1();
-      Id->collectExogenous(exogenous);
-      Id = eq_node->get_arg2();
-      Id->collectExogenous(exogenous);
-      for (set<pair<int, int> >::iterator it_exogenous=exogenous.begin();it_exogenous!=exogenous.end();it_exogenous++)
-        {
-          block_triangular.incidencematrix.fill_IM(eq, it_exogenous->first, it_exogenous->second, eExogenous);
-        }
-    }
-}
-
-void
-DynamicModel::computeTemporaryTermsOrdered(Model_Block *ModelBlock)
+DynamicModel::computeTemporaryTermsOrdered()
 {
   map<NodeID, pair<int, int> > first_occurence;
   map<NodeID, int> reference_count;
-  int i, j, m, eq, var, eqr, varr, lag;
-  temporary_terms_type vect;
-  ostringstream tmp_output;
   BinaryOpNode *eq_node;
   first_derivatives_type::const_iterator it;
   first_chain_rule_derivatives_type::const_iterator it_chr;
   ostringstream tmp_s;
+  v_temporary_terms.clear();
+  map_idx.clear();
 
+  unsigned int nb_blocks = getNbBlocks();
+  v_temporary_terms = vector<vector<temporary_terms_type> >(nb_blocks);
+  v_temporary_terms_inuse = vector<temporary_terms_inuse_type> (nb_blocks);
   temporary_terms.clear();
-  map_idx.clear();
-  for (j = 0;j < ModelBlock->Size;j++)
-    {
-      // Compute the temporary terms reordered
-      for (i = 0;i < ModelBlock->Block_List[j].Size;i++)
-        {
-          if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE_S && i<ModelBlock->Block_List[j].Nb_Recursives && ModelBlock->Block_List[j].Equation_Normalized[i])
-              ModelBlock->Block_List[j].Equation_Normalized[i]->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, j, ModelBlock, i, map_idx);
-          else
-            {
-              eq_node = equations[ModelBlock->Block_List[j].Equation[i]];
-              eq_node->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, j, ModelBlock, i, map_idx);
-            }
-        }
-      for(i=0; i<(int)ModelBlock->Block_List[j].Chain_Rule_Derivatives->size();i++)
-        {
-          pair< pair<int, pair<int, int> >, pair<int, int> > it = ModelBlock->Block_List[j].Chain_Rule_Derivatives->at(i);
-          lag=it.first.first;
-          int eqr=it.second.first;
-          int varr=it.second.second;
-          it_chr=first_chain_rule_derivatives.find(make_pair(eqr, make_pair( varr, lag)));
-          it_chr->second->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, j, ModelBlock, ModelBlock->Block_List[j].Size-1, map_idx);
-        }
 
-      for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++)
-        {
-          lag=m-ModelBlock->Block_List[j].Max_Lag;
-          for (i=0;i<ModelBlock->Block_List[j].IM_lead_lag[m].size;i++)
-            {
-              eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_Index[i];
-              var=ModelBlock->Block_List[j].IM_lead_lag[m].Var_Index[i];
-              it=first_derivatives.find(make_pair(eq,getDerivID(symbol_table.getID(eEndogenous, var), lag)));
-              it->second->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, j, ModelBlock, ModelBlock->Block_List[j].Size-1, map_idx);
-            }
-        }
-      /*for(i=0; i<(int)ModelBlock->Block_List[j].Chain_Rule_Derivatives->size();i++)
-        {
-          pair< pair<int, pair<int, int> >, pair<int, int> > it = ModelBlock->Block_List[j].Chain_Rule_Derivatives->at(i);
-          lag=it.first.first;
-          eqr=it.second.first;
-          varr=it.second.second;
-          it_chr=first_chain_rule_derivatives.find(make_pair(eqr, make_pair( varr, lag)));
-          it_chr->second->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, j, ModelBlock, ModelBlock->Block_List[j].Size-1, map_idx);
-        }*/
-      /*for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++)
-        {
-          lag=m-ModelBlock->Block_List[j].Max_Lag;
-          for (i=0;i<ModelBlock->Block_List[j].IM_lead_lag[m].size_exo;i++)
-            {
-              eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_X_Index[i];
-              var=ModelBlock->Block_List[j].IM_lead_lag[m].Exogenous_Index[i];
-              it=first_derivatives.find(make_pair(eq,getDerivID(symbol_table.getID(eExogenous, var), lag)));
-              it->second->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, j, ModelBlock, ModelBlock->Block_List[j].Size-1, map_idx);
-            }
-        }*/
-      //jacobian_max_exo_col=(variable_table.max_exo_lag+variable_table.max_exo_lead+1)*symbol_table.exo_nbr;
-      for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++)
+  if(!global_temporary_terms)
+    {
+      for (unsigned int block = 0; block < nb_blocks; block++)
         {
-          lag=m-ModelBlock->Block_List[j].Max_Lag;
-          if (block_triangular.incidencematrix.Model_Max_Lag_Endo - ModelBlock->Block_List[j].Max_Lag +m >=0)
+          reference_count.clear();
+          temporary_terms.clear();
+          unsigned int block_size = getBlockSize(block);
+          unsigned int block_nb_mfs = getBlockMfs(block);
+          unsigned int block_nb_recursives = block_size - block_nb_mfs;
+          v_temporary_terms[block] = vector<temporary_terms_type>(block_size);
+          for (unsigned int i = 0; i < block_size; i++)
             {
-              for (i=0;i<ModelBlock->Block_List[j].IM_lead_lag[m].size_other_endo;i++)
+              if (i<block_nb_recursives && isBlockEquationRenormalized( block, i))
+                getBlockEquationRenormalizedNodeID( block, i)->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, block, v_temporary_terms,  i);
+              else
                 {
-                  eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_Index_other_endo[i];
-                  var=ModelBlock->Block_List[j].IM_lead_lag[m].Var_Index_other_endo[i];
-                  it=first_derivatives.find(make_pair(eq,getDerivID(symbol_table.getID(eEndogenous, var), lag)));
-                  it->second->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, j, ModelBlock, ModelBlock->Block_List[j].Size-1, map_idx);
+                  eq_node = (BinaryOpNode*)getBlockEquationNodeID(block, i);
+                  eq_node->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, block, v_temporary_terms,  i);
                 }
             }
+          for (t_block_derivatives_equation_variable_laglead_nodeid::const_iterator it = blocks_derivatives[block].begin(); it != (blocks_derivatives[block]).end(); it++)
+            {
+              NodeID id=it->second.second;
+              id->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, block, v_temporary_terms,  block_size-1);
+            }
+          for (t_derivative::const_iterator it = derivative_endo[block].begin(); it != derivative_endo[block].end(); it++)
+            it->second->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, block, v_temporary_terms,  block_size-1);
+          for (t_derivative::const_iterator it = derivative_other_endo[block].begin(); it != derivative_other_endo[block].end(); it++)
+            it->second->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, block, v_temporary_terms,  block_size-1);
+
+          set<int> temporary_terms_in_use;
+          temporary_terms_in_use.clear();
+          v_temporary_terms_inuse[block] = temporary_terms_in_use;
         }
     }
-  for (j = 0;j < ModelBlock->Size;j++)
+  else
     {
-      // Collecte the temporary terms reordered
-      for (i = 0;i < ModelBlock->Block_List[j].Size;i++)
+      for (unsigned int block = 0; block < nb_blocks; block++)
         {
-          if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE_S && i<ModelBlock->Block_List[j].Nb_Recursives && ModelBlock->Block_List[j].Equation_Normalized[i])
-              ModelBlock->Block_List[j].Equation_Normalized[i]->collectTemporary_terms(temporary_terms, ModelBlock, j);
-          else
+          // Compute the temporary terms reordered
+          unsigned int block_size = getBlockSize(block);
+          unsigned int block_nb_mfs = getBlockMfs(block);
+          unsigned int block_nb_recursives = block_size - block_nb_mfs;
+          v_temporary_terms[block] = vector<temporary_terms_type>(block_size);
+          for (unsigned int i = 0; i < block_size; i++)
             {
-              eq_node = equations[ModelBlock->Block_List[j].Equation[i]];
-              eq_node->collectTemporary_terms(temporary_terms, ModelBlock, j);
+              if (i<block_nb_recursives && isBlockEquationRenormalized( block, i))
+                getBlockEquationRenormalizedNodeID( block, i)->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, block, v_temporary_terms,  i);
+              else
+                {
+                  eq_node = (BinaryOpNode*)getBlockEquationNodeID(block, i);
+                  eq_node->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, block, v_temporary_terms, i);
+                }
             }
-
-          /*eq_node = equations[ModelBlock->Block_List[j].Equation[i]];
-          eq_node->collectTemporary_terms(temporary_terms, ModelBlock, j);
-          if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE_S)
-            if(ModelBlock->Block_List[j].Equation_Normalized[i])
-              ModelBlock->Block_List[j].Equation_Normalized[i]->collectTemporary_terms(temporary_terms, ModelBlock, j);
-          for(temporary_terms_type::const_iterator it = ModelBlock->Block_List[j].Temporary_Terms_in_Equation[i]->begin(); it!= ModelBlock->Block_List[j].Temporary_Terms_in_Equation[i]->end(); it++)
-            (*it)->collectTemporary_terms(temporary_terms, ModelBlock, j);*/
-        }
-      for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++)
-        {
-          lag=m-ModelBlock->Block_List[j].Max_Lag;
-          for (i=0;i<ModelBlock->Block_List[j].IM_lead_lag[m].size;i++)
+          for (t_block_derivatives_equation_variable_laglead_nodeid::const_iterator it = blocks_derivatives[block].begin(); it != (blocks_derivatives[block]).end(); it++)
             {
-              eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_Index[i];
-              var=ModelBlock->Block_List[j].IM_lead_lag[m].Var_Index[i];
-              it=first_derivatives.find(make_pair(eq,getDerivID(symbol_table.getID(eEndogenous, var), lag)));
-              //it=first_derivatives.find(make_pair(eq,variable_table.getID(var, lag)));
-              //if(it!=first_derivatives.end())
-              it->second->collectTemporary_terms(temporary_terms, ModelBlock, j);
+              NodeID id=it->second.second;
+              id->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, block, v_temporary_terms, block_size-1);
             }
+          for (t_derivative::const_iterator it = derivative_endo[block].begin(); it != derivative_endo[block].end(); it++)
+            it->second->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, block, v_temporary_terms, block_size-1);
+          for (t_derivative::const_iterator it = derivative_other_endo[block].begin(); it != derivative_other_endo[block].end(); it++)
+            it->second->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, block, v_temporary_terms, block_size-1);
         }
-      for(i=0; i<(int)ModelBlock->Block_List[j].Chain_Rule_Derivatives->size();i++)
+      for (unsigned int block = 0; block < nb_blocks; block++)
         {
-          pair< pair<int, pair<int, int> >, pair<int, int> > it = ModelBlock->Block_List[j].Chain_Rule_Derivatives->at(i);
-          lag=it.first.first;
-          eqr=it.second.first;
-          varr=it.second.second;
-          it_chr=first_chain_rule_derivatives.find(make_pair(eqr, make_pair( varr, lag)));
-          it_chr->second->collectTemporary_terms(temporary_terms, ModelBlock, j);
-        }
-      /*for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++)
-        {
-          lag=m-ModelBlock->Block_List[j].Max_Lag;
-          for (i=0;i<ModelBlock->Block_List[j].IM_lead_lag[m].size_exo;i++)
+          // Collect the temporary terms reordered
+          unsigned int block_size = getBlockSize(block);
+          unsigned int block_nb_mfs = getBlockMfs(block);
+          unsigned int block_nb_recursives = block_size - block_nb_mfs;
+          set<int> temporary_terms_in_use;
+          for (unsigned int i = 0; i < block_size; i++)
             {
-              eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_X_Index[i];
-              var=ModelBlock->Block_List[j].IM_lead_lag[m].Exogenous_Index[i];
-              it=first_derivatives.find(make_pair(eq,getDerivID(symbol_table.getID(eExogenous, var), lag)));
-              //it=first_derivatives.find(make_pair(eq,variable_table.getID(var, lag)));
-              it->second->collectTemporary_terms(temporary_terms, ModelBlock, j);
-            }
-        }*/
-      //jacobian_max_exo_col=(variable_table.max_exo_lag+variable_table.max_exo_lead+1)*symbol_table.exo_nbr;
-      for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++)
-        {
-          lag=m-ModelBlock->Block_List[j].Max_Lag;
-          if (block_triangular.incidencematrix.Model_Max_Lag_Endo - ModelBlock->Block_List[j].Max_Lag +m >=0)
-            {
-              for (i=0;i<ModelBlock->Block_List[j].IM_lead_lag[m].size_other_endo;i++)
+              if (i<block_nb_recursives && isBlockEquationRenormalized( block, i))
+                  getBlockEquationRenormalizedNodeID( block, i)->collectTemporary_terms(temporary_terms, temporary_terms_in_use, block);
+              else
                 {
-                  eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_Index_other_endo[i];
-                  var=ModelBlock->Block_List[j].IM_lead_lag[m].Var_Index_other_endo[i];
-                  it=first_derivatives.find(make_pair(eq,getDerivID(symbol_table.getID(eEndogenous, var), lag)));
-                  //it=first_derivatives.find(make_pair(eq,variable_table.getID(var, lag)));
-                  //if(it!=first_derivatives.end())
-                  it->second->collectTemporary_terms(temporary_terms, ModelBlock, j);
+                  eq_node = (BinaryOpNode*)getBlockEquationNodeID(block, i);
+                  eq_node->collectTemporary_terms(temporary_terms, temporary_terms_in_use, block);
                 }
             }
+          for (t_block_derivatives_equation_variable_laglead_nodeid::const_iterator it = blocks_derivatives[block].begin(); it != (blocks_derivatives[block]).end(); it++)
+            {
+              NodeID id=it->second.second;
+              id->collectTemporary_terms(temporary_terms, temporary_terms_in_use, block);
+            }
+          for (t_derivative::const_iterator it = derivative_endo[block].begin(); it != derivative_endo[block].end(); it++)
+            it->second->collectTemporary_terms(temporary_terms, temporary_terms_in_use, block);
+          for (t_derivative::const_iterator it = derivative_other_endo[block].begin(); it != derivative_other_endo[block].end(); it++)
+            it->second->collectTemporary_terms(temporary_terms, temporary_terms_in_use, block);
+          v_temporary_terms_inuse[block] = temporary_terms_in_use;
         }
+      // Add a mapping form node ID to temporary terms order
+      int j=0;
+      for (temporary_terms_type::const_iterator it = temporary_terms.begin();
+           it != temporary_terms.end(); it++)
+        map_idx[(*it)->idx]=j++;
     }
-  // Add a mapping form node ID to temporary terms order
-  j=0;
-  for (temporary_terms_type::const_iterator it = temporary_terms.begin();
-       it != temporary_terms.end(); it++)
-    map_idx[(*it)->idx]=j++;
 }
 
 void
-DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const string &dynamic_basename) const
+DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const
   {
-    int i,j,k,m;
     string tmp_s, sps;
     ostringstream tmp_output, tmp1_output, global_output;
     NodeID lhs=NULL, rhs=NULL;
     BinaryOpNode *eq_node;
     ostringstream Uf[symbol_table.endo_nbr()];
     map<NodeID, int> reference_count;
-    //int prev_Simulation_Type=-1, count_derivates=0;
-    int jacobian_max_endo_col;
+    temporary_terms_type local_temporary_terms;
     ofstream  output;
-    //temporary_terms_type::const_iterator it_temp=temporary_terms.begin();
     int nze, nze_exo, nze_other_endo;
-    //map<int, NodeID> recursive_variables;
     vector<int> feedback_variables;
+    ExprNodeOutputType local_output_type;
+
+    if(global_temporary_terms)
+      {
+        local_output_type = oMatlabDynamicModelSparse;
+        local_temporary_terms = temporary_terms;
+      }
+    else
+      local_output_type = oMatlabDynamicModelSparseLocalTemporaryTerms;
+
     //----------------------------------------------------------------------
     //For each block
-    for (j = 0;j < ModelBlock->Size;j++)
+    for (unsigned int block = 0; block < getNbBlocks(); block++)
       {
+
         //recursive_variables.clear();
         feedback_variables.clear();
         //For a block composed of a single equation determines wether we have to evaluate or to solve the equation
-        nze = nze_exo = nze_other_endo = 0;
-        for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++)
-          nze+=ModelBlock->Block_List[j].IM_lead_lag[m].size;
-        /*for (m=0;m<=ModelBlock->Block_List[j].Max_Lead_Exo+ModelBlock->Block_List[j].Max_Lag_Exo;m++)
-          nze_exo+=ModelBlock->Block_List[j].IM_lead_lag[m].size_exo;*/
-        for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++)
+        nze = derivative_endo[block].size();
+        nze_other_endo = derivative_other_endo[block].size();
+        nze_exo = derivative_exo[block].size();
+        BlockSimulationType simulation_type = getBlockSimulationType(block);
+        unsigned int block_size = getBlockSize(block);
+        unsigned int block_mfs = getBlockMfs(block);
+        unsigned int block_recursive = block_size - block_mfs;
+        unsigned int block_exo_size = exo_block[block].size();
+        unsigned int block_exo_det_size = exo_det_block[block].size();
+        unsigned int block_other_endo_size = other_endo_block[block].size();
+        int block_max_lag=max_leadlag_block[block].first;
+        if(global_temporary_terms)
           {
-            k=m-ModelBlock->Block_List[j].Max_Lag;
-            if (block_triangular.incidencematrix.Model_Max_Lag_Endo - ModelBlock->Block_List[j].Max_Lag +m >=0)
-              nze_other_endo+=ModelBlock->Block_List[j].IM_lead_lag[m].size_other_endo;
+            local_output_type = oMatlabDynamicModelSparse;
+            local_temporary_terms = temporary_terms;
           }
+        else
+          local_output_type = oMatlabDynamicModelSparseLocalTemporaryTerms;
+
         tmp1_output.str("");
-        tmp1_output << dynamic_basename << "_" << j+1 << ".m";
+        tmp1_output << dynamic_basename << "_" << block+1 << ".m";
         output.open(tmp1_output.str().c_str(), ios::out | ios::binary);
         output << "%\n";
         output << "% " << tmp1_output.str() << " : Computes dynamic model for Dynare\n";
@@ -322,183 +259,196 @@ DynamicModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const strin
         output << "% Warning : this file is generated automatically by Dynare\n";
         output << "%           from model file (.mod)\n\n";
         output << "%/\n";
-        if (ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD
-            ||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD
-            /*||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD_R
-            ||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD_R*/)
+        if (simulation_type ==EVALUATE_BACKWARD || simulation_type ==EVALUATE_FORWARD)
           {
-            output << "function [y, g1, g2, g3, varargout] = " << dynamic_basename << "_" << j+1 << "(y, x, params, jacobian_eval, y_kmin, periods)\n";
+            output << "function [y, g1, g2, g3, varargout] = " << dynamic_basename << "_" << block+1 << "(y, x, params, jacobian_eval, y_kmin, periods)\n";
           }
-        else if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_FORWARD_COMPLETE
-                 ||   ModelBlock->Block_List[j].Simulation_Type==SOLVE_BACKWARD_COMPLETE)
-          output << "function [residual, y, g1, g2, g3, varargout] = " << dynamic_basename << "_" << j+1 << "(y, x, params, it_, jacobian_eval)\n";
-        else if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_BACKWARD_SIMPLE
-                 ||   ModelBlock->Block_List[j].Simulation_Type==SOLVE_FORWARD_SIMPLE)
-          output << "function [residual, y, g1, g2, g3, varargout] = " << dynamic_basename << "_" << j+1 << "(y, x, params, it_, jacobian_eval)\n";
+        else if (simulation_type ==SOLVE_FORWARD_COMPLETE || simulation_type ==SOLVE_BACKWARD_COMPLETE)
+          output << "function [residual, y, g1, g2, g3, varargout] = " << dynamic_basename << "_" << block+1 << "(y, x, params, it_, jacobian_eval)\n";
+        else if (simulation_type ==SOLVE_BACKWARD_SIMPLE || simulation_type ==SOLVE_FORWARD_SIMPLE)
+          output << "function [residual, y, g1, g2, g3, varargout] = " << dynamic_basename << "_" << block+1 << "(y, x, params, it_, jacobian_eval)\n";
+        else
+          output << "function [residual, y, g1, g2, g3, b, varargout] = " << dynamic_basename << "_" << block+1 << "(y, x, params, periods, jacobian_eval, y_kmin, y_size)\n";
+        BlockType block_type;
+        if(simulation_type == SOLVE_TWO_BOUNDARIES_COMPLETE ||simulation_type == SOLVE_TWO_BOUNDARIES_SIMPLE)
+          block_type = SIMULTAN;
+        else if(simulation_type == SOLVE_FORWARD_COMPLETE ||simulation_type == SOLVE_BACKWARD_COMPLETE)
+          block_type = SIMULTANS;
+        else if((simulation_type == SOLVE_FORWARD_SIMPLE ||simulation_type == SOLVE_BACKWARD_SIMPLE ||
+                 simulation_type == EVALUATE_BACKWARD    || simulation_type == EVALUATE_FORWARD)
+                && getBlockFirstEquation(block) < prologue)
+          block_type = PROLOGUE;
+        else if((simulation_type == SOLVE_FORWARD_SIMPLE ||simulation_type == SOLVE_BACKWARD_SIMPLE ||
+                 simulation_type == EVALUATE_BACKWARD    || simulation_type == EVALUATE_FORWARD)
+                && getBlockFirstEquation(block) >= equations.size() - epilogue)
+          block_type = EPILOGUE;
         else
-          output << "function [residual, y, g1, g2, g3, b, varargout] = " << dynamic_basename << "_" << j+1 << "(y, x, params, periods, jacobian_eval, y_kmin, y_size)\n";
+          block_type = SIMULTANS;
         output << "  % ////////////////////////////////////////////////////////////////////////" << endl
-        << "  % //" << string("                     Block ").substr(int(log10(j + 1))) << j + 1 << " " << BlockTriangular::BlockType0(ModelBlock->Block_List[j].Type)
+        << "  % //" << string("                     Block ").substr(int(log10(block + 1))) << block + 1 << " " << BlockType0(block_type)
         << "          //" << endl
         << "  % //                     Simulation type "
-        << BlockTriangular::BlockSim(ModelBlock->Block_List[j].Simulation_Type) << "  //" << endl
+        << BlockSim(simulation_type) << "  //" << endl
         << "  % ////////////////////////////////////////////////////////////////////////" << endl;
         output << "  global options_;" << endl;
         //The Temporary terms
-        //output << "  relax = 1;\n";
-        if (ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD
-            ||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD)
+        if (simulation_type ==EVALUATE_BACKWARD || simulation_type ==EVALUATE_FORWARD)
           {
             output << "  if(jacobian_eval)\n";
-            output << "    g1 = spalloc(" << ModelBlock->Block_List[j].Size-ModelBlock->Block_List[j].Nb_Recursives
-            << ", " << (ModelBlock->Block_List[j].Size-ModelBlock->Block_List[j].Nb_Recursives)*(1+ModelBlock->Block_List[j].Max_Lag_Endo+ModelBlock->Block_List[j].Max_Lead_Endo)
-            << ", " << nze << ");\n";
-            output << "    g1_x=spalloc(" << ModelBlock->Block_List[j].Size << ", " << (ModelBlock->Block_List[j].nb_exo + ModelBlock->Block_List[j].nb_exo_det)*(1+ModelBlock->Block_List[j].Max_Lag_Exo+ModelBlock->Block_List[j].Max_Lead_Exo) << ", " << nze_exo << ");\n";
-            output << "    g1_o=spalloc(" << ModelBlock->Block_List[j].Size << ", " << ModelBlock->Block_List[j].nb_other_endo*(1+ModelBlock->Block_List[j].Max_Lag_Other_Endo+ModelBlock->Block_List[j].Max_Lead_Other_Endo) << ", " << nze_other_endo << ");\n";
+            output << "    g1 = spalloc(" << block_mfs  << ", " << block_mfs*(1+getBlockMaxLag(block)+getBlockMaxLead(block)) << ", " << nze << ");\n";
+            output << "    g1_x=spalloc(" << block_size << ", " << (block_exo_size + block_exo_det_size)*
+                      (1+max(exo_det_max_leadlag_block[block].first, exo_max_leadlag_block[block].first)+max(exo_det_max_leadlag_block[block].second, exo_max_leadlag_block[block].second))
+                   << ", " << nze_exo << ");\n";
+            output << "    g1_o=spalloc(" << block_size << ", " << block_other_endo_size*
+                      (1+other_endo_max_leadlag_block[block].first+other_endo_max_leadlag_block[block].second)
+                   << ", " << nze_other_endo << ");\n";
             output << "  end;\n";
           }
         else
           {
             output << "  if(jacobian_eval)\n";
-            output << "    g1 = spalloc(" << ModelBlock->Block_List[j].Size << ", " << ModelBlock->Block_List[j].Size*(1+ModelBlock->Block_List[j].Max_Lag_Endo+ModelBlock->Block_List[j].Max_Lead_Endo) << ", " << nze << ");\n";
-            output << "    g1_x=spalloc(" << ModelBlock->Block_List[j].Size << ", " << (ModelBlock->Block_List[j].nb_exo + ModelBlock->Block_List[j].nb_exo_det)*(1+ModelBlock->Block_List[j].Max_Lag_Exo+ModelBlock->Block_List[j].Max_Lead_Exo) << ", " << nze_exo << ");\n";
-            output << "    g1_o=spalloc(" << ModelBlock->Block_List[j].Size << ", " << ModelBlock->Block_List[j].nb_other_endo*(1+ModelBlock->Block_List[j].Max_Lag_Other_Endo+ModelBlock->Block_List[j].Max_Lead_Other_Endo) << ", " << nze_other_endo << ");\n";
+            output << "    g1 = spalloc(" << block_size << ", " << block_size*(1+getBlockMaxLag(block)+getBlockMaxLead(block)) << ", " << nze << ");\n";
+            output << "    g1_x=spalloc(" << block_size << ", " << (block_exo_size + block_exo_det_size)*
+                      (1+max(exo_det_max_leadlag_block[block].first, exo_max_leadlag_block[block].first)+max(exo_det_max_leadlag_block[block].second, exo_max_leadlag_block[block].second))
+                   << ", " << nze_exo << ");\n";
+            output << "    g1_o=spalloc(" << block_size << ", " << block_other_endo_size*
+                      (1+other_endo_max_leadlag_block[block].first+other_endo_max_leadlag_block[block].second)
+                   << ", " << nze_other_endo << ");\n";
             output << "  else\n";
-            if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_COMPLETE || ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_SIMPLE)
+            if (simulation_type==SOLVE_TWO_BOUNDARIES_COMPLETE || simulation_type==SOLVE_TWO_BOUNDARIES_SIMPLE)
               {
-                output << "    g1 = spalloc(" << (ModelBlock->Block_List[j].Size-ModelBlock->Block_List[j].Nb_Recursives) << "*options_.periods, "
-                << (ModelBlock->Block_List[j].Size-ModelBlock->Block_List[j].Nb_Recursives) << "*(options_.periods+" << ModelBlock->Block_List[j].Max_Lag+ModelBlock->Block_List[j].Max_Lead+1 << ")"
+                output << "    g1 = spalloc(" << block_mfs << "*options_.periods, "
+                << block_mfs << "*(options_.periods+" << max_leadlag_block[block].first+max_leadlag_block[block].second+1 << ")"
                 << ", " << nze << "*options_.periods);\n";
-                /*output << "    g1_tmp_r = spalloc(" << (ModelBlock->Block_List[j].Nb_Recursives)
-                << ", " << (ModelBlock->Block_List[j].Size)*(ModelBlock->Block_List[j].Max_Lag+ModelBlock->Block_List[j].Max_Lead+1)
-                << ", " << nze << ");\n";
-                output << "    g1_tmp_b = spalloc(" << (ModelBlock->Block_List[j].Size-ModelBlock->Block_List[j].Nb_Recursives)
-                << ", " << (ModelBlock->Block_List[j].Size)*(ModelBlock->Block_List[j].Max_Lag+ModelBlock->Block_List[j].Max_Lead+1)
-                << ", " << nze << ");\n";*/
               }
             else
               {
-                output << "    g1 = spalloc(" << ModelBlock->Block_List[j].Size-ModelBlock->Block_List[j].Nb_Recursives
-                << ", " << ModelBlock->Block_List[j].Size-ModelBlock->Block_List[j].Nb_Recursives << ", " << nze << ");\n";
-                output << "    g1_tmp_r = spalloc(" << ModelBlock->Block_List[j].Nb_Recursives
-                << ", " << ModelBlock->Block_List[j].Size << ", " << nze << ");\n";
-                output << "    g1_tmp_b = spalloc(" << ModelBlock->Block_List[j].Size-ModelBlock->Block_List[j].Nb_Recursives
-                << ", " << ModelBlock->Block_List[j].Size << ", " << nze << ");\n";
+                output << "    g1 = spalloc(" << block_mfs
+                << ", " << block_mfs << ", " << nze << ");\n";
+                output << "    g1_tmp_r = spalloc(" << block_recursive
+                << ", " << block_size << ", " << nze << ");\n";
+                output << "    g1_tmp_b = spalloc(" << block_mfs
+                << ", " << block_size << ", " << nze << ");\n";
               }
             output << "  end;\n";
           }
 
         output << "  g2=0;g3=0;\n";
-        if (ModelBlock->Block_List[j].Temporary_InUse->size())
+        if (v_temporary_terms_inuse[block].size())
           {
             tmp_output.str("");
-            for (temporary_terms_inuse_type::const_iterator it = ModelBlock->Block_List[j].Temporary_InUse->begin();
-                 it != ModelBlock->Block_List[j].Temporary_InUse->end(); it++)
+            for (temporary_terms_inuse_type::const_iterator it = v_temporary_terms_inuse[block].begin();
+                 it != v_temporary_terms_inuse[block].end(); it++)
               tmp_output << " T" << *it;
             output << "  global" << tmp_output.str() << ";\n";
           }
-        if (ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_BACKWARD && ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_FORWARD)
-          output << "  residual=zeros(" << ModelBlock->Block_List[j].Size-ModelBlock->Block_List[j].Nb_Recursives << ",1);\n";
-        if (ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD)
+        if (simulation_type==SOLVE_TWO_BOUNDARIES_COMPLETE || simulation_type==SOLVE_TWO_BOUNDARIES_SIMPLE)
+          {
+            temporary_terms_type tt2;
+            tt2.clear();
+            for(int i=0; i< (int) block_size; i++)
+              {
+                if (v_temporary_terms[block][i].size() && global_temporary_terms)
+                  {
+                    output << "  " << "% //Temporary variables initialization" << endl
+                           << "  " << "T_zeros = zeros(y_kmin+periods, 1);" << endl;
+                    for (temporary_terms_type::const_iterator it = v_temporary_terms[block][i].begin();
+                         it != v_temporary_terms[block][i].end(); it++)
+                      {
+                        output << "  ";
+                        (*it)->writeOutput(output, oMatlabDynamicModel, local_temporary_terms);
+                        output << " = T_zeros;" << endl;
+                      }
+                  }
+              }
+          }
+        if (simulation_type==SOLVE_BACKWARD_SIMPLE || simulation_type==SOLVE_FORWARD_SIMPLE || simulation_type==SOLVE_BACKWARD_COMPLETE || simulation_type==SOLVE_FORWARD_COMPLETE)
+          output << "  residual=zeros(" << block_mfs << ",1);\n";
+        else if (simulation_type==SOLVE_TWO_BOUNDARIES_COMPLETE || simulation_type==SOLVE_TWO_BOUNDARIES_SIMPLE)
+          output << "  residual=zeros(" << block_mfs << ",y_kmin+periods);\n";
+        if (simulation_type==EVALUATE_BACKWARD)
           output << "  for it_ = (y_kmin+periods):y_kmin+1\n";
-        if (ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD)
+        if (simulation_type==EVALUATE_FORWARD)
           output << "  for it_ = y_kmin+1:(y_kmin+periods)\n";
 
-        if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_COMPLETE || ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_SIMPLE)
+        if (simulation_type==SOLVE_TWO_BOUNDARIES_COMPLETE || simulation_type==SOLVE_TWO_BOUNDARIES_SIMPLE)
           {
-            output << "  b = zeros(periods*y_size,1);\n";
-            output << "  for it_ = y_kmin+1:(periods+y_kmin)\n";
-            output << "    Per_y_=it_*y_size;\n";
-            output << "    Per_J_=(it_-y_kmin-1)*y_size;\n";
-            output << "    Per_K_=(it_-1)*y_size;\n";
+            output << "  b = zeros(periods*y_size,1);" << endl
+                   << "  for it_ = y_kmin+1:(periods+y_kmin)" << endl
+                   << "    Per_y_=it_*y_size;" << endl
+                   << "    Per_J_=(it_-y_kmin-1)*y_size;" << endl
+                   << "    Per_K_=(it_-1)*y_size;" << endl;
             sps="  ";
           }
         else
-          if (ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD || ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD )
+          if (simulation_type==EVALUATE_BACKWARD || simulation_type==EVALUATE_FORWARD )
             sps = "  ";
           else
             sps="";
         // The equations
-        for (i = 0;i < ModelBlock->Block_List[j].Size;i++)
+        for (unsigned int i = 0; i < block_size; i++)
           {
             temporary_terms_type tt2;
             tt2.clear();
-            if (ModelBlock->Block_List[j].Temporary_Terms_in_Equation[i]->size())
-              output << "  " << sps << "% //Temporary variables" << endl;
-            for (temporary_terms_type::const_iterator it = ModelBlock->Block_List[j].Temporary_Terms_in_Equation[i]->begin();
-                 it != ModelBlock->Block_List[j].Temporary_Terms_in_Equation[i]->end(); it++)
+            if (v_temporary_terms[block].size())
               {
-                output << "  " <<  sps;
-                (*it)->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms);
-                output << " = ";
-                (*it)->writeOutput(output, oMatlabDynamicModelSparse, tt2);
-                // Insert current node into tt2
-                tt2.insert(*it);
-                output << ";" << endl;
+                output << "  " << "% //Temporary variables" << endl;
+                for (temporary_terms_type::const_iterator it = v_temporary_terms[block][i].begin();
+                     it != v_temporary_terms[block][i].end(); it++)
+                  {
+                    output << "  " <<  sps;
+                    (*it)->writeOutput(output, local_output_type, local_temporary_terms);
+                    output << " = ";
+                    (*it)->writeOutput(output, local_output_type, tt2);
+                    // Insert current node into tt2
+                    tt2.insert(*it);
+                    output << ";" << endl;
+                  }
               }
-            string sModel = symbol_table.getName(symbol_table.getID(eEndogenous, ModelBlock->Block_List[j].Variable[i])) ;
-            eq_node = equations[ModelBlock->Block_List[j].Equation[i]];
+
+            int variable_ID = getBlockVariableID(block, i);
+            int equation_ID = getBlockEquationID(block, i);
+            EquationType equ_type = getBlockEquationType(block, i);
+            string sModel = symbol_table.getName(symbol_table.getID(eEndogenous, variable_ID)) ;
+            eq_node = (BinaryOpNode*)getBlockEquationNodeID(block,i);
             lhs = eq_node->get_arg1();
             rhs = eq_node->get_arg2();
             tmp_output.str("");
-            /*if((ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_BACKWARD or ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_FORWARD) and (i<ModelBlock->Block_List[j].Nb_Recursives))
-              lhs->writeOutput(tmp_output, oMatlabDynamicModelSparse, temporary_terms);
-            else*/
-						lhs->writeOutput(tmp_output, oMatlabDynamicModelSparse, temporary_terms);
-            switch (ModelBlock->Block_List[j].Simulation_Type)
+						lhs->writeOutput(tmp_output, local_output_type, local_temporary_terms);
+            switch (simulation_type)
               {
               case EVALUATE_BACKWARD:
               case EVALUATE_FORWARD:
-evaluation:     if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_COMPLETE || ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_SIMPLE)
-                  output << "    % equation " << ModelBlock->Block_List[j].Equation[i]+1 << " variable : " << sModel
-                  << " (" << ModelBlock->Block_List[j].Variable[i]+1 << ") " << block_triangular.c_Equation_Type(ModelBlock->Block_List[j].Equation_Type[i]) << endl;
+evaluation:     if (simulation_type==SOLVE_TWO_BOUNDARIES_COMPLETE || simulation_type==SOLVE_TWO_BOUNDARIES_SIMPLE)
+                  output << "    % equation " << getBlockEquationID(block, i)+1 << " variable : " << sModel
+                  << " (" << variable_ID+1 << ") " << c_Equation_Type(equ_type) << endl;
                 output << "    ";
-                if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE)
+                if (equ_type == E_EVALUATE)
                   {
                     output << tmp_output.str();
                     output << " = ";
-                    /*if(!(ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD or ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD))
-                      {
-                        lhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms);
-                        output << "-relax*(";
-                        lhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms);
-                        output << "-(";
-                        rhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms);
-                        output << "))";
-                      }
-                    else*/
-                    rhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms);
+                    rhs->writeOutput(output, local_output_type, local_temporary_terms);
                   }
-                else if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE_S)
+                else if (equ_type == E_EVALUATE_S)
                   {
                     output << "%" << tmp_output.str();
                     output << " = ";
-                    if (ModelBlock->Block_List[j].Equation_Normalized[i])
+                    if (isBlockEquationRenormalized(block, i))
                       {
-                        rhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms);
+                        rhs->writeOutput(output, local_output_type, local_temporary_terms);
                         output << "\n    ";
                         tmp_output.str("");
-                        eq_node = (BinaryOpNode *)ModelBlock->Block_List[j].Equation_Normalized[i];
+                        eq_node = (BinaryOpNode *)getBlockEquationRenormalizedNodeID(block, i);
                         lhs = eq_node->get_arg1();
                         rhs = eq_node->get_arg2();
-                        lhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms);
+                        lhs->writeOutput(output, local_output_type, local_temporary_terms);
                         output << " = ";
-                        /*if(!(ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD or ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD))
-                          {
-                            lhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms);
-                            output << "-relax*(";
-                            lhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms);
-                            output << "-(";
-                            rhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms);
-                            output << "))";
-                          }
-                        else*/
-                          rhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms);
+                        rhs->writeOutput(output, local_output_type, local_temporary_terms);
                       }
                   }
                 else
                   {
-                    cerr << "Type missmatch for equation " << ModelBlock->Block_List[j].Equation[i]+1  << "\n";
+                    cerr << "Type missmatch for equation " << equation_ID+1  << "\n";
                     exit(EXIT_FAILURE);
                   }
                 output << ";\n";
@@ -507,342 +457,251 @@ evaluation:     if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDAR
               case SOLVE_FORWARD_SIMPLE:
               case SOLVE_BACKWARD_COMPLETE:
               case SOLVE_FORWARD_COMPLETE:
-                if (i<ModelBlock->Block_List[j].Nb_Recursives)
-                  {
-                    /*if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE_S)
-                      recursive_variables[getDerivID(symbol_table.getID(eEndogenous, ModelBlock->Block_List[j].Variable[i]), 0)] = ModelBlock->Block_List[j].Equation_Normalized[i];
-                    else
-                      recursive_variables[getDerivID(symbol_table.getID(eEndogenous, ModelBlock->Block_List[j].Variable[i]), 0)] = equations[ModelBlock->Block_List[j].Equation[i]];*/
-                    goto evaluation;
-                  }
-                feedback_variables.push_back(ModelBlock->Block_List[j].Variable[i]);
-                output << "  % equation " << ModelBlock->Block_List[j].Equation[i]+1 << " variable : " << sModel
-                << " (" << ModelBlock->Block_List[j].Variable[i]+1 << ") " << block_triangular.c_Equation_Type(ModelBlock->Block_List[j].Equation_Type[i]) << endl;
-                output << "  " << "residual(" << i+1-ModelBlock->Block_List[j].Nb_Recursives << ") = (";
+                if (i<block_recursive)
+                  goto evaluation;
+                feedback_variables.push_back(variable_ID);
+                output << "  % equation " << equation_ID+1 << " variable : " << sModel
+                << " (" << variable_ID+1 << ") " << c_Equation_Type(equ_type) << endl;
+                output << "  " << "residual(" << i+1-block_recursive << ") = (";
                 goto end;
               case SOLVE_TWO_BOUNDARIES_COMPLETE:
               case SOLVE_TWO_BOUNDARIES_SIMPLE:
-                if (i<ModelBlock->Block_List[j].Nb_Recursives)
-                  {
-                    /*if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE_S)
-                      recursive_variables[getDerivID(symbol_table.getID(eEndogenous, ModelBlock->Block_List[j].Variable[i]), 0)] = ModelBlock->Block_List[j].Equation_Normalized[i];
-                    else
-                      recursive_variables[getDerivID(symbol_table.getID(eEndogenous, ModelBlock->Block_List[j].Variable[i]), 0)] = equations[ModelBlock->Block_List[j].Equation[i]];*/
-                    goto evaluation;
-                  }
-                feedback_variables.push_back(ModelBlock->Block_List[j].Variable[i]);
-                output << "    % equation " << ModelBlock->Block_List[j].Equation[i]+1 << " variable : " << sModel
-                << " (" << ModelBlock->Block_List[j].Variable[i]+1 << ") " << block_triangular.c_Equation_Type(ModelBlock->Block_List[j].Equation_Type[i]) << endl;
-                Uf[ModelBlock->Block_List[j].Equation[i]] << "    b(" << i+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_J_) = -residual(" << i+1-ModelBlock->Block_List[j].Nb_Recursives << ", it_)";
-                output << "    residual(" << i+1-ModelBlock->Block_List[j].Nb_Recursives << ", it_) = (";
+                if (i<block_recursive)
+                  goto evaluation;
+                feedback_variables.push_back(variable_ID);
+                output << "    % equation " << equation_ID+1 << " variable : " << sModel
+                << " (" << variable_ID+1 << ") " << c_Equation_Type(equ_type) << endl;
+                Uf[equation_ID] << "    b(" << i+1-block_recursive << "+Per_J_) = -residual(" << i+1-block_recursive << ", it_)";
+                output << "    residual(" << i+1-block_recursive << ", it_) = (";
                 goto end;
               default:
 end:
                 output << tmp_output.str();
                 output << ") - (";
-                rhs->writeOutput(output, oMatlabDynamicModelSparse, temporary_terms);
+                rhs->writeOutput(output, local_output_type, local_temporary_terms);
                 output << ");\n";
 #ifdef CONDITION
-                if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_COMPLETE || ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_SIMPLE)
+                if (simulation_type==SOLVE_TWO_BOUNDARIES_COMPLETE || simulation_type==SOLVE_TWO_BOUNDARIES_SIMPLE)
                   output << "  condition(" << i+1 << ")=0;\n";
 #endif
               }
           }
         // The Jacobian if we have to solve the block
-        if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_SIMPLE
-            ||  ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_COMPLETE)
+        if (simulation_type==SOLVE_TWO_BOUNDARIES_SIMPLE || simulation_type==SOLVE_TWO_BOUNDARIES_COMPLETE)
           output << "  " << sps << "% Jacobian  " << endl;
         else
-          if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_BACKWARD_SIMPLE || ModelBlock->Block_List[j].Simulation_Type==SOLVE_FORWARD_SIMPLE ||
-              ModelBlock->Block_List[j].Simulation_Type==SOLVE_BACKWARD_COMPLETE || ModelBlock->Block_List[j].Simulation_Type==SOLVE_FORWARD_COMPLETE)
+          if (simulation_type==SOLVE_BACKWARD_SIMPLE   || simulation_type==SOLVE_FORWARD_SIMPLE ||
+              simulation_type==SOLVE_BACKWARD_COMPLETE || simulation_type==SOLVE_FORWARD_COMPLETE)
             output << "  % Jacobian  " << endl << "  if jacobian_eval" << endl;
           else
             output << "    % Jacobian  " << endl << "    if jacobian_eval" << endl;
-        switch (ModelBlock->Block_List[j].Simulation_Type)
+        switch (simulation_type)
           {
           case EVALUATE_BACKWARD:
           case EVALUATE_FORWARD:
-            for (m=0;m<ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag+1;m++)
+            for (t_derivative::const_iterator it = derivative_endo[block].begin(); it != derivative_endo[block].end(); it++)
               {
-                k=m-ModelBlock->Block_List[j].Max_Lag;
-                for (i=0;i<ModelBlock->Block_List[j].IM_lead_lag[m].size;i++)
-                  {
-                    int eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_Index[i];
-                    int var=ModelBlock->Block_List[j].IM_lead_lag[m].Var_Index[i];
-                    int eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ[i];
-                    int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Var[i];
-                    output << "      g1(" << eqr+1 << ", " << /*varr+1+(m+variable_table.max_lag-ModelBlock->Block_List[j].Max_Lag)*symbol_table.endo_nbr*/
-                    varr+1+m*ModelBlock->Block_List[j].Size << ") = ";
-                    writeDerivative(output, eq, symbol_table.getID(eEndogenous, var), k, oMatlabDynamicModelSparse, temporary_terms);
-                    output << "; % variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, var))
-                    << "(" << k//variable_table.getLag(variable_table.getSymbolID(ModelBlock->Block_List[j].Variable[0]))
+                int lag = it->first.first;
+                int eq = it->first.second.first;
+                int var = it->first.second.second;
+                int eqr = getBlockInitialEquationID(block, eq);
+                int varr = getBlockInitialVariableID(block, var);
+
+                NodeID id = it->second;
+
+                output << "      g1(" << eqr+1 << ", " << varr+1+(lag+block_max_lag)*block_size << ") = ";
+                id->writeOutput(output, local_output_type, local_temporary_terms);
+                output << "; % variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, var))
+                    << "(" << lag
                     << ") " << var+1
                     << ", equation=" << eq+1 << endl;
-                  }
               }
-            //jacobian_max_endo_col=(variable_table.max_endo_lag+variable_table.max_endo_lead+1)*symbol_table.endo_nbr;
-            /*for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++)
+            for (t_derivative::const_iterator it = derivative_other_endo[block].begin(); it != derivative_other_endo[block].end(); it++)
               {
-                k=m-ModelBlock->Block_List[j].Max_Lag;
-                for (i=0;i<ModelBlock->Block_List[j].IM_lead_lag[m].size_exo;i++)
-                  {
-                    int eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_X_Index[i];
-                    int var=ModelBlock->Block_List[j].IM_lead_lag[m].Exogenous_Index[i];
-                    int eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_X[i];
-                    int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Exogenous[i];
-                    output << "      g1_x(" << eqr+1 << ", "
-                           << varr+1+(m+max_exo_lag-ModelBlock->Block_List[j].Max_Lag)*symbol_table.exo_nbr() << ") = ";
-                    writeDerivative(output, eq, symbol_table.getID(eExogenous, var), k, oMatlabDynamicModelSparse, temporary_terms);
-                    output << "; % variable=" << symbol_table.getName(var)
-                           << "(" << k << ") " << var+1
-                           << ", equation=" << eq+1 << endl;
-                  }
-              }*/
-            for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++)
-              {
-                k=m-ModelBlock->Block_List[j].Max_Lag;
-                if (block_triangular.incidencematrix.Model_Max_Lag_Endo - ModelBlock->Block_List[j].Max_Lag +m >=0)
-                  {
-                    for (i=0;i<ModelBlock->Block_List[j].IM_lead_lag[m].size_other_endo;i++)
-                      {
-                        int eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_Index_other_endo[i];
-                        int var=ModelBlock->Block_List[j].IM_lead_lag[m].Var_Index_other_endo[i];
-                        int eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_other_endo[i];
-                        int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Var_other_endo[i];
-                        output << "      g1_o(" << eqr+1 << ", "
-                        << varr+1+(m+max_endo_lag-ModelBlock->Block_List[j].Max_Lag)*symbol_table.endo_nbr() << ") = ";
-                        writeDerivative(output, eq, symbol_table.getID(eEndogenous, var), k, oMatlabDynamicModelSparse, temporary_terms);
-                        output << "; % variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, var))
-                        << "(" << k << ") " << var+1
-                        << ", equation=" << eq+1 << endl;
-                      }
-                  }
+                int lag = it->first.first;
+                int eq = it->first.second.first;
+                int var = it->first.second.second;
+                int eqr = getBlockInitialEquationID(block, eq);
+                NodeID id = it->second;
+
+                output << "      g1_o(" << eqr+1 << ", " << var+1+(lag+block_max_lag)*block_size << ") = ";
+                id->writeOutput(output, local_output_type, local_temporary_terms);
+                output << "; % variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, var))
+                    << "(" << lag
+                    << ") " << var+1
+                    << ", equation=" << eq+1 << endl;
               }
             output << "      varargout{1}=g1_x;\n";
             output << "      varargout{2}=g1_o;\n";
             output << "    end;" << endl;
-            //output << "    ya = y;\n";
             output << "  end;" << endl;
             break;
           case SOLVE_BACKWARD_SIMPLE:
           case SOLVE_FORWARD_SIMPLE:
           case SOLVE_BACKWARD_COMPLETE:
           case SOLVE_FORWARD_COMPLETE:
-            for (m=0;m<ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag+1;m++)
+            for (t_derivative::const_iterator it = derivative_endo[block].begin(); it != derivative_endo[block].end(); it++)
               {
-                k=m-ModelBlock->Block_List[j].Max_Lag;
-                for (i=0;i<ModelBlock->Block_List[j].IM_lead_lag[m].size;i++)
-                  {
-                    int eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_Index[i];
-                    int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Var_Index[i];
-                    int eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ[i];
-                    int var=ModelBlock->Block_List[j].IM_lead_lag[m].Var[i];
-                    output << "    g1(" << eq+1 << ", "
-                    << var+1 + m*(ModelBlock->Block_List[j].Size) << ") = ";
-                    writeDerivative(output, eqr, symbol_table.getID(eEndogenous, varr), k, oMatlabDynamicModelSparse, temporary_terms);
-                    output << "; % variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, varr))
-                    << "(" << k << ") " << varr+1
-                    << ", equation=" << eqr+1 << endl;
-                  }
+                int lag = it->first.first;
+                unsigned int eq = it->first.second.first;
+                unsigned int var = it->first.second.second;
+                NodeID id = it->second;
+
+                output << "    g1(" << eq+1 << ", " << var+1+(lag+block_max_lag)*block_size << ") = ";
+                id->writeOutput(output, local_output_type, local_temporary_terms);
+                output << "; % variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, var))
+                    << "(" << lag
+                    << ") " << var+1
+                    << ", equation=" << eq+1 << endl;
               }
-            /*for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++)
-              {
-                k=m-ModelBlock->Block_List[j].Max_Lag;
-                for (i=0;i<ModelBlock->Block_List[j].IM_lead_lag[m].size_exo;i++)
-                  {
-                    int eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_X_Index[i];
-                    int var=ModelBlock->Block_List[j].IM_lead_lag[m].Exogenous_Index[i];
-                    int eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_X[i];
-                    int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Exogenous[i];
-                    output << "    g1_x(" << eqr+1 << ", " << varr+1+(m+max_exo_lag-ModelBlock->Block_List[j].Max_Lag)*ModelBlock->Block_List[j].nb_exo << ") = ";
-                    writeDerivative(output, eq, symbol_table.getID(eExogenous, var), k, oMatlabDynamicModelSparse, temporary_terms);
-                    output << "; % variable=" << symbol_table.getName(var)
-                           << "(" << k << ") " << var+1
-                           << ", equation=" << eq+1 << endl;
-                  }
-              }*/
-            for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++)
+
+            for (t_derivative::const_iterator it = derivative_other_endo[block].begin(); it != derivative_other_endo[block].end(); it++)
               {
-                k=m-ModelBlock->Block_List[j].Max_Lag;
-                if (block_triangular.incidencematrix.Model_Max_Lag_Endo - ModelBlock->Block_List[j].Max_Lag +m >=0)
-                  {
-                    for (i=0;i<ModelBlock->Block_List[j].IM_lead_lag[m].size_other_endo;i++)
-                      {
-                        int eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_Index_other_endo[i];
-                        int var=ModelBlock->Block_List[j].IM_lead_lag[m].Var_Index_other_endo[i];
-                        int eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_other_endo[i];
-                        int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Var_other_endo[i];
-                        output << "    g1_o(" << eqr+1/*-ModelBlock->Block_List[j].Nb_Recursives*/ << ", "
-                        << varr+1+(m+max_endo_lag-ModelBlock->Block_List[j].Max_Lag)*symbol_table.endo_nbr() << ") = ";
-                        writeDerivative(output, eq, symbol_table.getID(eEndogenous, var), k, oMatlabDynamicModelSparse, temporary_terms);
-                        output << "; % variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, var))
-                        << "(" << k << ") " << var+1
-                        << ", equation=" << eq+1 << endl;
-                      }
-                  }
+                int lag = it->first.first;
+                unsigned int eq = it->first.second.first;
+                unsigned int var = it->first.second.second;
+                NodeID id = it->second;
+
+                output << "    g1_o(" << eq+1 << ", " << var+1+(lag+block_max_lag)*block_size << ") = ";
+                id->writeOutput(output, local_output_type, local_temporary_terms);
+                output << "; % variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, var))
+                    << "(" << lag
+                    << ") " << var+1
+                    << ", equation=" << eq+1 << endl;
               }
             output << "    varargout{1}=g1_x;\n";
             output << "    varargout{2}=g1_o;\n";
             output << "  else" << endl;
-
-            for(i=0; i<(int)ModelBlock->Block_List[j].Chain_Rule_Derivatives->size();i++)
+            for (t_block_derivatives_equation_variable_laglead_nodeid::const_iterator it = blocks_derivatives[block].begin(); it != (blocks_derivatives[block]).end(); it++)
               {
-                pair< pair<int, pair<int, int> >, pair<int, int> > it = ModelBlock->Block_List[j].Chain_Rule_Derivatives->at(i);
-                k=it.first.first;
-                int eq=it.first.second.first;
-                int var=it.first.second.second;
-                int eqr=it.second.first;
-                int varr=it.second.second;
-                output << "    g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives << ", "
-                       << var+1-ModelBlock->Block_List[j].Nb_Recursives  << ") = ";
-                writeChainRuleDerivative(output, eqr, varr, k, oMatlabDynamicModelSparse, temporary_terms);
-                output << "; %2 variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, varr))
-                       << "(" << k << ") " << varr+1 << ", equation=" << eqr+1 << endl;
+                unsigned int eq = it->first.first;
+                unsigned int var = it->first.second;
+                unsigned int eqr = getBlockEquationID(block, eq);
+                unsigned int varr = getBlockVariableID(block, var);
+                NodeID id = it->second.second;
+                int lag = it->second.first;
+                output << "    g1(" << eq+1 << ", " << var+1-block_recursive << ") = ";
+                id->writeOutput(output, local_output_type, local_temporary_terms);
+                output << "; % variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, varr))
+                    << "(" << lag
+                    << ") " << varr+1
+                    << ", equation=" << eqr+1 << endl;
               }
             output << "  end;\n";
             break;
           case SOLVE_TWO_BOUNDARIES_SIMPLE:
           case SOLVE_TWO_BOUNDARIES_COMPLETE:
             output << "    if ~jacobian_eval" << endl;
-            for(i=0; i<(int)ModelBlock->Block_List[j].Chain_Rule_Derivatives->size();i++)
+            for (t_block_derivatives_equation_variable_laglead_nodeid::const_iterator it = blocks_derivatives[block].begin(); it != (blocks_derivatives[block]).end(); it++)
               {
-                pair< pair<int, pair<int, int> >, pair<int, int> > it = ModelBlock->Block_List[j].Chain_Rule_Derivatives->at(i);
-                k=it.first.first;
-                int eq=it.first.second.first;
-                int var=it.first.second.second;
-                int eqr=it.second.first;
-                int varr=it.second.second;
+                unsigned int eq = it->first.first;
+                unsigned int var = it->first.second;
+                unsigned int eqr = getBlockEquationID(block, eq);
+                unsigned int varr = getBlockVariableID(block, var);
                 ostringstream tmp_output;
-                if(eq>=ModelBlock->Block_List[j].Nb_Recursives and var>=ModelBlock->Block_List[j].Nb_Recursives)
+                NodeID id = it->second.second;
+                int lag = it->second.first;
+                if(eq>=block_recursive and var>=block_recursive)
                   {
-                    if (k==0)
-                      Uf[ModelBlock->Block_List[j].Equation[eq]] << "+g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives
-                        << "+Per_J_, " << var+1-ModelBlock->Block_List[j].Nb_Recursives
+                    if (lag==0)
+                      Uf[eqr] << "+g1(" << eq+1-block_recursive
+                        << "+Per_J_, " << var+1-block_recursive
                         << "+Per_K_)*y(it_, " << varr+1 << ")";
-                    else if (k==1)
-                      Uf[ModelBlock->Block_List[j].Equation[eq]] << "+g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives
-                        << "+Per_J_, " << var+1-ModelBlock->Block_List[j].Nb_Recursives
+                    else if (lag==1)
+                      Uf[eqr] << "+g1(" << eq+1-block_recursive
+                        << "+Per_J_, " << var+1-block_recursive
                         << "+Per_y_)*y(it_+1, " << varr+1 << ")";
-                    else if (k>0)
-                      Uf[ModelBlock->Block_List[j].Equation[eq]] << "+g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives
-                        << "+Per_J_, " << var+1-ModelBlock->Block_List[j].Nb_Recursives
-                        << "+y_size*(it_+" << k-1 << "))*y(it_+" << k << ", " << varr+1 << ")";
-                    else if (k<0)
-                      Uf[ModelBlock->Block_List[j].Equation[eq]] << "+g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives
-                        << "+Per_J_, " << var+1-ModelBlock->Block_List[j].Nb_Recursives
-                        << "+y_size*(it_" << k-1 << "))*y(it_" << k << ", " << varr+1 << ")";
-                    if (k==0)
-                      tmp_output << "     g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_J_, "
-                        << var+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_K_) = ";
-                    else if (k==1)
-                      tmp_output << "     g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_J_, "
-                        << var+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_y_) = ";
-                    else if (k>0)
-                      tmp_output << "     g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_J_, "
-                        << var+1-ModelBlock->Block_List[j].Nb_Recursives << "+y_size*(it_+" << k-1 << ")) = ";
-                    else if (k<0)
-                      tmp_output << "     g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives << "+Per_J_, "
-                        << var+1-ModelBlock->Block_List[j].Nb_Recursives << "+y_size*(it_" << k-1 << ")) = ";
+                    else if (lag>0)
+                      Uf[eqr] << "+g1(" << eq+1-block_recursive
+                        << "+Per_J_, " << var+1-block_recursive
+                        << "+y_size*(it_+" << lag-1 << "))*y(it_+" << lag << ", " << varr+1 << ")";
+                    else if (lag<0)
+                      Uf[eqr] << "+g1(" << eq+1-block_recursive
+                        << "+Per_J_, " << var+1-block_recursive
+                        << "+y_size*(it_" << lag-1 << "))*y(it_" << lag << ", " << varr+1 << ")";
+                    if (lag==0)
+                      tmp_output << "     g1(" << eq+1-block_recursive << "+Per_J_, "
+                        << var+1-block_recursive << "+Per_K_) = ";
+                    else if (lag==1)
+                      tmp_output << "     g1(" << eq+1-block_recursive << "+Per_J_, "
+                        << var+1-block_recursive << "+Per_y_) = ";
+                    else if (lag>0)
+                      tmp_output << "     g1(" << eq+1-block_recursive << "+Per_J_, "
+                        << var+1-block_recursive << "+y_size*(it_+" << lag-1 << ")) = ";
+                    else if (lag<0)
+                      tmp_output << "     g1(" << eq+1-block_recursive << "+Per_J_, "
+                        << var+1-block_recursive << "+y_size*(it_" << lag-1 << ")) = ";
                     output << " " << tmp_output.str();
-
-                    writeChainRuleDerivative(output, eqr, varr, k, oMatlabDynamicModelSparse, temporary_terms);
-
+                    id->writeOutput(output, local_output_type, local_temporary_terms);
                     output << ";";
                     output << " %2 variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, varr))
-                      << "(" << k << ") " << varr+1
+                      << "(" << lag << ") " << varr+1
                       << ", equation=" << eqr+1 << " (" << eq+1 << ")" << endl;
                   }
+
 #ifdef CONDITION
                 output << "  if (fabs(condition[" << eqr << "])<fabs(u[" << u << "+Per_u_]))\n";
                 output << "    condition(" << eqr << ")=u(" << u << "+Per_u_);\n";
 #endif
-                  //}
               }
-            for (i = 0;i < ModelBlock->Block_List[j].Size;i++)
+            for (unsigned int i = 0; i < block_size; i++)
               {
-                if (i>=ModelBlock->Block_List[j].Nb_Recursives)
-                  output << "  " << Uf[ModelBlock->Block_List[j].Equation[i]].str() << ";\n";
+                if (i>=block_recursive)
+                  output << "  " << Uf[getBlockEquationID(block, i)].str() << ";\n";
 #ifdef CONDITION
                 output << "  if (fabs(condition(" << i+1 << "))<fabs(u(" << i << "+Per_u_)))\n";
                 output << "    condition(" << i+1 << ")=u(" << i+1 << "+Per_u_);\n";
 #endif
               }
 #ifdef CONDITION
-            for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++)
+            for (m=0;m<=ModelBlock->Block_List[block].Max_Lead+ModelBlock->Block_List[block].Max_Lag;m++)
               {
-                k=m-ModelBlock->Block_List[j].Max_Lag;
-                for (i=0;i<ModelBlock->Block_List[j].IM_lead_lag[m].size;i++)
+                k=m-ModelBlock->Block_List[block].Max_Lag;
+                for (i=0;i<ModelBlock->Block_List[block].IM_lead_lag[m].size;i++)
                   {
-                    int eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_Index[i];
-                    int var=ModelBlock->Block_List[j].IM_lead_lag[m].Var_Index[i];
-                    int u=ModelBlock->Block_List[j].IM_lead_lag[m].u[i];
-                    int eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ[i];
+                    unsigned int eq=ModelBlock->Block_List[block].IM_lead_lag[m].Equ_Index[i];
+                    unsigned int var=ModelBlock->Block_List[block].IM_lead_lag[m].Var_Index[i];
+                    unsigned int u=ModelBlock->Block_List[block].IM_lead_lag[m].u[i];
+                    unsigned int eqr=ModelBlock->Block_List[block].IM_lead_lag[m].Equ[i];
                     output << "  u(" << u+1 << "+Per_u_) = u(" << u+1 << "+Per_u_) / condition(" << eqr+1 << ");\n";
                   }
               }
-            for (i = 0;i < ModelBlock->Block_List[j].Size;i++)
+            for (i = 0;i < ModelBlock->Block_List[block].Size;i++)
               output << "  u(" << i+1 << "+Per_u_) = u(" << i+1 << "+Per_u_) / condition(" << i+1 << ");\n";
 #endif
 
             output << "    else" << endl;
-            for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++)
+
+            for (t_derivative::const_iterator it = derivative_endo[block].begin(); it != derivative_endo[block].end(); it++)
               {
-                k=m-ModelBlock->Block_List[j].Max_Lag;
-                for (i=0;i<ModelBlock->Block_List[j].IM_lead_lag[m].size;i++)
-                  {
-                    int eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_Index[i];
-                    int var=ModelBlock->Block_List[j].IM_lead_lag[m].Var_Index[i];
-                    int eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ[i];
-                    int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Var[i];
-                    output << "      g1(" << eqr+1 << ", " << varr+1+(m-ModelBlock->Block_List[j].Max_Lag+ModelBlock->Block_List[j].Max_Lag_Endo)*ModelBlock->Block_List[j].Size << ") = ";
-                    writeDerivative(output, eq, symbol_table.getID(eEndogenous, var), k, oMatlabDynamicModelSparse, temporary_terms);
-                    output << "; % variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, var))
-                    << "(" << k << ") " << var+1
+                int lag = it->first.first;
+                unsigned int eq = it->first.second.first;
+                unsigned int var = it->first.second.second;
+                NodeID id = it->second;
+                output << "      g1(" << eq+1 << ", " << var+1+(lag+block_max_lag)*block_size << ") = ";
+                id->writeOutput(output, local_output_type, local_temporary_terms);
+                output << "; % variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, var))
+                    << "(" << lag
+                    << ") " << var+1
                     << ", equation=" << eq+1 << endl;
-                  }
               }
-            jacobian_max_endo_col=(ModelBlock->Block_List[j].Max_Lead_Endo+ModelBlock->Block_List[j].Max_Lag_Endo+1)*ModelBlock->Block_List[j].Size;
-            /*for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++)
-              {
-                k=m-ModelBlock->Block_List[j].Max_Lag;
-                for (i=0;i<ModelBlock->Block_List[j].IM_lead_lag[m].size_exo;i++)
-                  {
-                    int eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_X_Index[i];
-                    int eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_X[i];
-                    int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Exogenous[i];
-                    int var=ModelBlock->Block_List[j].IM_lead_lag[m].Exogenous_Index[i];
-                    output << "      g1_x(" << eqr+1 << ", "
-                           << jacobian_max_endo_col+(m-(ModelBlock->Block_List[j].Max_Lag-ModelBlock->Block_List[j].Max_Lag_Exo))*ModelBlock->Block_List[j].nb_exo+varr+1 << ") = ";
-                    writeDerivative(output, eq, symbol_table.getID(eExogenous, var), k, oMatlabDynamicModelSparse, temporary_terms);
-                    output << "; % variable (exogenous)=" << symbol_table.getName(var)
-                           << "(" << k << ") " << var+1 << " " << varr+1
-                           << ", equation=" << eq+1 << endl;
-                  }
-              }*/
-            for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++)
+            for (t_derivative::const_iterator it = derivative_other_endo[block].begin(); it != derivative_other_endo[block].end(); it++)
               {
-                k=m-ModelBlock->Block_List[j].Max_Lag;
-                if (block_triangular.incidencematrix.Model_Max_Lag_Endo - ModelBlock->Block_List[j].Max_Lag +m >=0)
-                  {
-                    for (i=0;i<ModelBlock->Block_List[j].IM_lead_lag[m].size_other_endo;i++)
-                      {
-                        int eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_Index_other_endo[i];
-                        int var=ModelBlock->Block_List[j].IM_lead_lag[m].Var_Index_other_endo[i];
-                        int eqr=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_other_endo[i];
-                        int varr=ModelBlock->Block_List[j].IM_lead_lag[m].Var_other_endo[i];
-                        output << "      g1_o(" << eqr+1 << ", "
-                        << varr+1+(m+max_endo_lag-ModelBlock->Block_List[j].Max_Lag)*symbol_table.endo_nbr() << ") = ";
-                        writeDerivative(output, eq, symbol_table.getID(eEndogenous, var), k, oMatlabDynamicModelSparse, temporary_terms);
-                        output << "; % variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, var))
-                        << "(" << k << ") " << var+1
-                        << ", equation=" << eq+1 << endl;
-                      }
-                  }
+                int lag = it->first.first;
+                unsigned int eq = it->first.second.first;
+                unsigned int var = it->first.second.second;
+                NodeID id = it->second;
+
+                output << "      g1_o(" << eq+1 << ", " << var+1+(lag+block_max_lag)*block_size << ") = ";
+                id->writeOutput(output, local_output_type, local_temporary_terms);
+                output << "; % variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, var))
+                    << "(" << lag
+                    << ") " << var+1
+                    << ", equation=" << eq+1 << endl;
               }
             output << "      varargout{1}=g1_x;\n";
             output << "      varargout{2}=g1_o;\n";
             output << "    end;\n";
-            //output << "    ya = y;\n";
             output << "  end;\n";
             break;
           default:
@@ -853,7 +712,7 @@ end:
   }
 
 void
-DynamicModel::writeModelEquationsCodeOrdered(const string file_name, const Model_Block *ModelBlock, const string bin_basename, map_idx_type map_idx) const
+DynamicModel::writeModelEquationsCodeOrdered(const string file_name, const string bin_basename, map_idx_type map_idx) const
   {
     struct Uff_l
       {
@@ -866,7 +725,7 @@ DynamicModel::writeModelEquationsCodeOrdered(const string file_name, const Model
         Uff_l *Ufl, *Ufl_First;
       };
 
-    int i,j,k,v;
+    int i,v;
     string tmp_s;
     ostringstream tmp_output;
     ofstream code_file;
@@ -876,6 +735,7 @@ DynamicModel::writeModelEquationsCodeOrdered(const string file_name, const Model
     map<NodeID, int> reference_count;
     vector<int> feedback_variables;
     bool file_open=false;
+
     string main_name=file_name;
     main_name+=".cod";
     code_file.open(main_name.c_str(), ios::out | ios::binary | ios::ate );
@@ -885,93 +745,61 @@ DynamicModel::writeModelEquationsCodeOrdered(const string file_name, const Model
         exit(EXIT_FAILURE);
       }
     //Temporary variables declaration
-    /*code_file.write(&FDIMT, sizeof(FDIMT));
-    k=temporary_terms.size();
-    code_file.write(reinterpret_cast<char *>(&k),sizeof(k));*/
+
     FDIMT_ fdimt(temporary_terms.size());
     fdimt.write(code_file);
 
-    for (j = 0; j < ModelBlock->Size ;j++)
+    for (unsigned int block = 0; block < getNbBlocks(); block++)
       {
         feedback_variables.clear();
-        if (j>0)
+        if (block>0)
           {
             FENDBLOCK_ fendblock;
             fendblock.write(code_file);
-            //code_file.write(&FENDBLOCK, sizeof(FENDBLOCK));
           }
         int count_u;
         int u_count_int=0;
-        if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_SIMPLE || ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_COMPLETE ||
-            ModelBlock->Block_List[j].Simulation_Type==SOLVE_BACKWARD_COMPLETE || ModelBlock->Block_List[j].Simulation_Type==SOLVE_FORWARD_COMPLETE)
+        BlockSimulationType simulation_type = getBlockSimulationType(block);
+        unsigned int block_size = getBlockSize(block);
+        unsigned int block_mfs = getBlockMfs(block);
+        unsigned int block_recursive = block_size - block_mfs;
+        int block_max_lag=max_leadlag_block[block].first;
+
+        if (simulation_type==SOLVE_TWO_BOUNDARIES_SIMPLE || simulation_type==SOLVE_TWO_BOUNDARIES_COMPLETE ||
+            simulation_type==SOLVE_BACKWARD_COMPLETE || simulation_type==SOLVE_FORWARD_COMPLETE)
           {
-            //cout << "ModelBlock->Block_List[j].Nb_Recursives = " << ModelBlock->Block_List[j].Nb_Recursives << "\n";
-            Write_Inf_To_Bin_File(file_name, bin_basename, j, u_count_int,file_open,
-                                  ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_COMPLETE || ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_SIMPLE);
-            //cout << "u_count_int=" << u_count_int << "\n";
-
-
-            /*code_file.write(reinterpret_cast<char *>(&ModelBlock->Block_List[j].is_linear),sizeof(ModelBlock->Block_List[j].is_linear));
-            //v=block_triangular.ModelBlock->Block_List[j].IM_lead_lag[block_triangular.ModelBlock->Block_List[j].Max_Lag + block_triangular.ModelBlock->Block_List[j].Max_Lead].u_finish + 1;
-            v=symbol_table.endo_nbr();
-            code_file.write(reinterpret_cast<char *>(&v),sizeof(v));
-            v=block_triangular.ModelBlock->Block_List[j].Max_Lag;
-            code_file.write(reinterpret_cast<char *>(&v),sizeof(v));
-            v=block_triangular.ModelBlock->Block_List[j].Max_Lead;
-            code_file.write(reinterpret_cast<char *>(&v),sizeof(v));
-
-            v=u_count_int;
-            code_file.write(reinterpret_cast<char *>(&v),sizeof(v));*/
+            Write_Inf_To_Bin_File(file_name, bin_basename, block, u_count_int,file_open,
+                                  simulation_type==SOLVE_TWO_BOUNDARIES_COMPLETE || simulation_type==SOLVE_TWO_BOUNDARIES_SIMPLE);
             file_open=true;
           }
-        FBEGINBLOCK_ fbeginblock(ModelBlock->Block_List[j].Size - ModelBlock->Block_List[j].Nb_Recursives,
-                                 ModelBlock->Block_List[j].Simulation_Type,
-                                 ModelBlock->Block_List[j].Variable,
-                                 ModelBlock->Block_List[j].Equation,
-                                 ModelBlock->Block_List[j].Own_Derivative,
-                                 ModelBlock->Block_List[j].is_linear,
+        FBEGINBLOCK_ fbeginblock(block_mfs,
+                                 simulation_type,
+                                 getBlockFirstEquation(block),
+                                 block_size,
+                                 variable_reordered,
+                                 equation_reordered,
+                                 blocks_linear[block],
                                  symbol_table.endo_nbr(),
-                                 ModelBlock->Block_List[j].Max_Lag,
-                                 ModelBlock->Block_List[j].Max_Lead,
+                                 block_max_lag,
+                                 block_max_lag,
                                  u_count_int
                                  );
         fbeginblock.write(code_file);
-        /*code_file.write(&FBEGINBLOCK, sizeof(FBEGINBLOCK));
-        v=ModelBlock->Block_List[j].Size - ModelBlock->Block_List[j].Nb_Recursives;
-        //cout << "v (Size) = " << v  << "\n";
-        code_file.write(reinterpret_cast<char *>(&v),sizeof(v));
-        v=ModelBlock->Block_List[j].Simulation_Type;
-        code_file.write(reinterpret_cast<char *>(&v),sizeof(v));
-
-        for (i=ModelBlock->Block_List[j].Nb_Recursives; i < ModelBlock->Block_List[j].Size;i++)
-          {
-            code_file.write(reinterpret_cast<char *>(&ModelBlock->Block_List[j].Variable[i]),sizeof(ModelBlock->Block_List[j].Variable[i]));
-            code_file.write(reinterpret_cast<char *>(&ModelBlock->Block_List[j].Equation[i]),sizeof(ModelBlock->Block_List[j].Equation[i]));
-            code_file.write(reinterpret_cast<char *>(&ModelBlock->Block_List[j].Own_Derivative[i]),sizeof(ModelBlock->Block_List[j].Own_Derivative[i]));
-          }*/
 
-            // The equations
-            for (i = 0;i < ModelBlock->Block_List[j].Size;i++)
+        // The equations
+        for (i = 0;i < (int) block_size;i++)
+          {
+            //The Temporary terms
+            temporary_terms_type tt2;
+            tt2.clear();
+            if (v_temporary_terms[block][i].size())
               {
-                //The Temporary terms
-                temporary_terms_type tt2;
-                tt2.clear();
-#ifdef DEBUGC
-                k=0;
-#endif
-                for (temporary_terms_type::const_iterator it = ModelBlock->Block_List[j].Temporary_Terms_in_Equation[i]->begin();
-                     it != ModelBlock->Block_List[j].Temporary_Terms_in_Equation[i]->end(); it++)
+                for (temporary_terms_type::const_iterator it = v_temporary_terms[block][i].begin();
+                     it != v_temporary_terms[block][i].end(); it++)
                   {
                     (*it)->compile(code_file, false, tt2, map_idx, true, false);
-
                     FSTPT_ fstpt((int)(map_idx.find((*it)->idx)->second));
                     fstpt.write(code_file);
-
-                    /*code_file.write(&FSTPT, sizeof(FSTPT));
-                    map_idx_type::const_iterator ii=map_idx.find((*it)->idx);
-                    v=(int)ii->second;
-                    code_file.write(reinterpret_cast<char *>(&v), sizeof(v));*/
-
                     // Insert current node into tt2
                     tt2.insert(*it);
 #ifdef DEBUGC
@@ -982,204 +810,167 @@ DynamicModel::writeModelEquationsCodeOrdered(const string file_name, const Model
 #endif
 
                   }
+              }
 #ifdef DEBUGC
-                for (temporary_terms_type::const_iterator it = ModelBlock->Block_List[j].Temporary_terms->begin();
-                     it != ModelBlock->Block_List[j].Temporary_terms->end(); it++)
+            for (temporary_terms_type::const_iterator it = v_temporary_terms[block][i].begin();
+                     it != v_temporary_terms[block][i].end(); it++)
+              {
+                map_idx_type::const_iterator ii=map_idx.find((*it)->idx);
+                cout << "map_idx[" << (*it)->idx <<"]=" << ii->second << "\n";
+              }
+#endif
+
+            int variable_ID, equation_ID;
+            EquationType equ_type;
+
+
+            switch (simulation_type)
+              {
+evaluation:
+              case EVALUATE_BACKWARD:
+              case EVALUATE_FORWARD:
+                equ_type = getBlockEquationType(block, i);
+                if (equ_type == E_EVALUATE)
                   {
-                    map_idx_type::const_iterator ii=map_idx.find((*it)->idx);
-                    cout << "map_idx[" << (*it)->idx <<"]=" << ii->second << "\n";
+                    eq_node = (BinaryOpNode*)getBlockEquationNodeID(block,i);
+                    lhs = eq_node->get_arg1();
+                    rhs = eq_node->get_arg2();
+                    rhs->compile(code_file, false, temporary_terms, map_idx, true, false);
+                    lhs->compile(code_file, true, temporary_terms, map_idx, true, false);
                   }
-#endif
-                switch (ModelBlock->Block_List[j].Simulation_Type)
+                else if (equ_type == E_EVALUATE_S)
                   {
-evaluation:
-                  case EVALUATE_BACKWARD:
-                  case EVALUATE_FORWARD:
-                    if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE)
-                      {
-                        eq_node = equations[ModelBlock->Block_List[j].Equation[i]];
-                        lhs = eq_node->get_arg1();
-                        rhs = eq_node->get_arg2();
-                        rhs->compile(code_file, false, temporary_terms, map_idx, true, false);
-                        lhs->compile(code_file, true, temporary_terms, map_idx, true, false);
-                      }
-                    else if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE_S)
-                      {
-                        eq_node = (BinaryOpNode*)ModelBlock->Block_List[j].Equation_Normalized[i];
-                        lhs = eq_node->get_arg1();
-                        rhs = eq_node->get_arg2();
-                        rhs->compile(code_file, false, temporary_terms, map_idx, true, false);
-                        lhs->compile(code_file, true, temporary_terms, map_idx, true, false);
-                      }
-                    break;
-                  case SOLVE_BACKWARD_COMPLETE:
-                  case SOLVE_FORWARD_COMPLETE:
-                  case SOLVE_TWO_BOUNDARIES_COMPLETE:
-                  case SOLVE_TWO_BOUNDARIES_SIMPLE:
-                    if (i<ModelBlock->Block_List[j].Nb_Recursives)
-                      goto evaluation;
-                    feedback_variables.push_back(ModelBlock->Block_List[j].Variable[i]);
-                    v=ModelBlock->Block_List[j].Equation[i];
-                    Uf[v].Ufl=NULL;
-                    goto end;
-                  default:
-end:
-                    eq_node = equations[ModelBlock->Block_List[j].Equation[i]];
+                    eq_node = (BinaryOpNode*)getBlockEquationRenormalizedNodeID(block,i);
                     lhs = eq_node->get_arg1();
                     rhs = eq_node->get_arg2();
-                    lhs->compile(code_file, false, temporary_terms, map_idx, true, false);
                     rhs->compile(code_file, false, temporary_terms, map_idx, true, false);
-
-                    FBINARY_ fbinary(oMinus);
-                    fbinary.write(code_file);
-                    /*code_file.write(&FBINARY, sizeof(FBINARY));
-                    int v=oMinus;
-                    code_file.write(reinterpret_cast<char *>(&v),sizeof(v));*/
-                    FSTPR_ fstpr(i - ModelBlock->Block_List[j].Nb_Recursives);
-                    fstpr.write(code_file);
-                    /*code_file.write(&FSTPR, sizeof(FSTPR));
-                    v = i - ModelBlock->Block_List[j].Nb_Recursives;
-                    code_file.write(reinterpret_cast<char *>(&v), sizeof(v));*/
+                    lhs->compile(code_file, true, temporary_terms, map_idx, true, false);
                   }
+                break;
+              case SOLVE_BACKWARD_COMPLETE:
+              case SOLVE_FORWARD_COMPLETE:
+              case SOLVE_TWO_BOUNDARIES_COMPLETE:
+              case SOLVE_TWO_BOUNDARIES_SIMPLE:
+                if (i< (int) block_recursive)
+                  goto evaluation;
+                variable_ID = getBlockVariableID(block, i);
+                equation_ID = getBlockEquationID(block, i);
+                feedback_variables.push_back(variable_ID);
+                Uf[equation_ID].Ufl=NULL;
+                goto end;
+              default:
+end:
+                eq_node = (BinaryOpNode*)getBlockEquationNodeID(block, i);
+                lhs = eq_node->get_arg1();
+                rhs = eq_node->get_arg2();
+                lhs->compile(code_file, false, temporary_terms, map_idx, true, false);
+                rhs->compile(code_file, false, temporary_terms, map_idx, true, false);
+
+                FBINARY_ fbinary(oMinus);
+                fbinary.write(code_file);
+                FSTPR_ fstpr(i - block_recursive);
+                fstpr.write(code_file);
               }
-            FENDEQU_ fendequ;
-            fendequ.write(code_file);
-            //code_file.write(&FENDEQU, sizeof(FENDEQU));
-            // The Jacobian if we have to solve the block
-            if (ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_BACKWARD
-                && ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_FORWARD)
+          }
+        FENDEQU_ fendequ;
+        fendequ.write(code_file);
+        // The Jacobian if we have to solve the block
+        if    (simulation_type != EVALUATE_BACKWARD
+            && simulation_type != EVALUATE_FORWARD)
+          {
+            switch (simulation_type)
               {
-                switch (ModelBlock->Block_List[j].Simulation_Type)
+              case SOLVE_BACKWARD_SIMPLE:
+              case SOLVE_FORWARD_SIMPLE:
+                compileDerivative(code_file, getBlockEquationID(block, 0), getBlockVariableID(block, 0), 0, map_idx);
                   {
-                  case SOLVE_BACKWARD_SIMPLE:
-                  case SOLVE_FORWARD_SIMPLE:
-                    compileDerivative(code_file, ModelBlock->Block_List[j].Equation[0], ModelBlock->Block_List[j].Variable[0], 0, map_idx);
+                    FSTPG_ fstpg(0);
+                    fstpg.write(code_file);
+                  }
+                break;
+
+              case SOLVE_BACKWARD_COMPLETE:
+              case SOLVE_FORWARD_COMPLETE:
+              case SOLVE_TWO_BOUNDARIES_COMPLETE:
+              case SOLVE_TWO_BOUNDARIES_SIMPLE:
+                count_u = feedback_variables.size();
+                for (t_block_derivatives_equation_variable_laglead_nodeid::const_iterator it = blocks_derivatives[block].begin(); it != (blocks_derivatives[block]).end(); it++)
+                  {
+                    unsigned int eq = it->first.first;
+                    unsigned int var = it->first.second;
+                    unsigned int eqr = getBlockEquationID(block, eq);
+                    unsigned int varr = getBlockVariableID(block, var);
+                    int lag = it->second.first;
+                    if(eq>=block_recursive and var>=block_recursive)
                       {
-                        FSTPG_ fstpg(0);
-                        fstpg.write(code_file);
+                        if (!Uf[eqr].Ufl)
+                          {
+                            Uf[eqr].Ufl=(Uff_l*)malloc(sizeof(Uff_l));
+                            Uf[eqr].Ufl_First=Uf[eqr].Ufl;
+                          }
+                        else
+                          {
+                            Uf[eqr].Ufl->pNext=(Uff_l*)malloc(sizeof(Uff_l));
+                            Uf[eqr].Ufl=Uf[eqr].Ufl->pNext;
+                          }
+                        Uf[eqr].Ufl->pNext=NULL;
+                        Uf[eqr].Ufl->u=count_u;
+                        Uf[eqr].Ufl->var=varr;
+                        Uf[eqr].Ufl->lag=lag;
+                        compileChainRuleDerivative(code_file, eqr, varr, lag, map_idx);
+                        FSTPU_ fstpu(count_u);
+                        fstpu.write(code_file);
+                        count_u++;
                       }
-                    /*code_file.write(&FSTPG, sizeof(FSTPG));
-                    v=0;
-                    code_file.write(reinterpret_cast<char *>(&v), sizeof(v));*/
-                    break;
-
-                  case SOLVE_BACKWARD_COMPLETE:
-                  case SOLVE_FORWARD_COMPLETE:
-                  case SOLVE_TWO_BOUNDARIES_COMPLETE:
-                  case SOLVE_TWO_BOUNDARIES_SIMPLE:
-                    //count_u=ModelBlock->Block_List[j].Size - ModelBlock->Block_List[j].Nb_Recursives;
-                    count_u = feedback_variables.size();
-                    for(i=0; i<(int)ModelBlock->Block_List[j].Chain_Rule_Derivatives->size();i++)
+                  }
+                for (i = 0;i < (int) block_size;i++)
+                  {
+                    if(i>= (int) block_recursive)
                       {
-                        pair< pair<int, pair<int, int> >, pair<int, int> > it = ModelBlock->Block_List[j].Chain_Rule_Derivatives->at(i);
-                        k=it.first.first;
-                        int eq=it.first.second.first;
-                        int var=it.first.second.second;
-                        int eqr=it.second.first;
-                        int varr=it.second.second;
-                        //cout << "k=" << k << " eq=" << eq << " (" << eq-ModelBlock->Block_List[j].Nb_Recursives << ") var=" << var << " (" << var-ModelBlock->Block_List[j].Nb_Recursives << ") eqr=" << eqr << " varr=" << varr << " count_u=" << count_u << "\n";
-                        int v=ModelBlock->Block_List[j].Equation[eq];
-                        /*m = ModelBlock->Block_List[j].Max_Lag + k;
-                        int u=ModelBlock->Block_List[j].IM_lead_lag[m].u[i];*/
-                        if(eq>=ModelBlock->Block_List[j].Nb_Recursives and var>=ModelBlock->Block_List[j].Nb_Recursives)
+                        FLDR_ fldr(i-block_recursive);
+                        fldr.write(code_file);
+
+                        FLDZ_ fldz;
+                        fldz.write(code_file);
+
+                        v=getBlockEquationID(block, i);
+                        for (Uf[v].Ufl=Uf[v].Ufl_First; Uf[v].Ufl; Uf[v].Ufl=Uf[v].Ufl->pNext)
                           {
-                            if (!Uf[v].Ufl)
-                              {
-                                Uf[v].Ufl=(Uff_l*)malloc(sizeof(Uff_l));
-                                Uf[v].Ufl_First=Uf[v].Ufl;
-                              }
-                            else
-                              {
-                                Uf[v].Ufl->pNext=(Uff_l*)malloc(sizeof(Uff_l));
-                                Uf[v].Ufl=Uf[v].Ufl->pNext;
-                              }
-                            Uf[v].Ufl->pNext=NULL;
-                            Uf[v].Ufl->u=count_u;
-                            Uf[v].Ufl->var=varr;
-                            Uf[v].Ufl->lag=k;
-                            compileChainRuleDerivative(code_file, eqr, varr, k, map_idx);
-
-                            FSTPU_ fstpu(count_u);
-                            fstpu.write(code_file);
-
-                            /*code_file.write(&FSTPU, sizeof(FSTPU));
-                            code_file.write(reinterpret_cast<char *>(&count_u), sizeof(count_u));*/
-                            count_u++;
-												  }
-											}
-                    for (i = 0;i < ModelBlock->Block_List[j].Size;i++)
-                      {
-                        if(i>=ModelBlock->Block_List[j].Nb_Recursives)
+                            FLDU_ fldu(Uf[v].Ufl->u);
+                            fldu.write(code_file);
+                            FLDV_ fldv(eEndogenous, Uf[v].Ufl->var, Uf[v].Ufl->lag);
+                            fldv.write(code_file);
+
+                            FBINARY_ fbinary(oTimes);
+                            fbinary.write(code_file);
+
+                            FCUML_ fcuml;
+                            fcuml.write(code_file);
+                          }
+                        Uf[v].Ufl=Uf[v].Ufl_First;
+                        while (Uf[v].Ufl)
                           {
-                            FLDR_ fldr(i-ModelBlock->Block_List[j].Nb_Recursives);
-                            fldr.write(code_file);
-                            /*code_file.write(&FLDR, sizeof(FLDR));
-                            v = i-ModelBlock->Block_List[j].Nb_Recursives;
-                            code_file.write(reinterpret_cast<char *>(&v), sizeof(v));*/
-
-                            FLDZ_ fldz;
-                            fldz.write(code_file);
-                            //code_file.write(&FLDZ, sizeof(FLDZ));
-
-                            v=ModelBlock->Block_List[j].Equation[i];
-                            for (Uf[v].Ufl=Uf[v].Ufl_First; Uf[v].Ufl; Uf[v].Ufl=Uf[v].Ufl->pNext)
-                              {
-                                FLDU_ fldu(Uf[v].Ufl->u);
-                                fldu.write(code_file);
-                                /*code_file.write(&FLDU, sizeof(FLDU));
-                                code_file.write(reinterpret_cast<char *>(&Uf[v].Ufl->u), sizeof(Uf[v].Ufl->u));*/
-                                FLDV_ fldv(eEndogenous, Uf[v].Ufl->var, Uf[v].Ufl->lag);
-                                fldv.write(code_file);
-
-                                /*code_file.write(&FLDV, sizeof(FLDV));
-                                char vc=eEndogenous;
-                                code_file.write(reinterpret_cast<char *>(&vc), sizeof(vc));
-                                int v1=Uf[v].Ufl->var;
-                                code_file.write(reinterpret_cast<char *>(&v1), sizeof(v1));
-                                v1=Uf[v].Ufl->lag;
-                                code_file.write(reinterpret_cast<char *>(&v1), sizeof(v1));*/
-                                FBINARY_ fbinary(oTimes);
-                                fbinary.write(code_file);
-                                /*code_file.write(&FBINARY, sizeof(FBINARY));
-                                v1=oTimes;
-                                code_file.write(reinterpret_cast<char *>(&v1), sizeof(v1));*/
-
-                                FCUML_ fcuml;
-                                fcuml.write(code_file);
-                                //code_file.write(&FCUML, sizeof(FCUML));
-                              }
+                            Uf[v].Ufl_First=Uf[v].Ufl->pNext;
+                            free(Uf[v].Ufl);
                             Uf[v].Ufl=Uf[v].Ufl_First;
-                            while (Uf[v].Ufl)
-                              {
-                                Uf[v].Ufl_First=Uf[v].Ufl->pNext;
-                                free(Uf[v].Ufl);
-                                Uf[v].Ufl=Uf[v].Ufl_First;
-                              }
-                            FBINARY_ fbinary(oMinus);
-                            fbinary.write(code_file);
-                            /*code_file.write(&FBINARY, sizeof(FBINARY));
-                            v=oMinus;
-                            code_file.write(reinterpret_cast<char *>(&v), sizeof(v));*/
-
-                            FSTPU_ fstpu(i - ModelBlock->Block_List[j].Nb_Recursives);
-                            fstpu.write(code_file);
-                            /*code_file.write(&FSTPU, sizeof(FSTPU));
-                            v = i - ModelBlock->Block_List[j].Nb_Recursives;
-                            code_file.write(reinterpret_cast<char *>(&v), sizeof(v));*/
                           }
+                        FBINARY_ fbinary(oMinus);
+                        fbinary.write(code_file);
+
+                        FSTPU_ fstpu(i - block_recursive);
+                        fstpu.write(code_file);
                       }
-                    break;
-                  default:
-                    break;
                   }
+                break;
+              default:
+                break;
               }
+          }
       }
     FENDBLOCK_ fendblock;
     fendblock.write(code_file);
-    //code_file.write(&FENDBLOCK, sizeof(FENDBLOCK));
     FEND_ fend;
     fend.write(code_file);
-    //code_file.write(&FEND, sizeof(FEND));
     code_file.close();
   }
 
@@ -1201,7 +992,7 @@ DynamicModel::writeDynamicMFile(const string &dynamic_basename) const
     << "%" << endl
     << "% Warning : this file is generated automatically by Dynare" << endl
     << "%           from model file (.mod)" << endl << endl;
-    
+
     if (containsSteadyStateOperator())
       mDynamicModelFile << "global oo_;" << endl << endl;
 
@@ -1215,7 +1006,7 @@ DynamicModel::writeDynamicCFile(const string &dynamic_basename) const
   {
     string filename = dynamic_basename + ".c";
     ofstream mDynamicModelFile;
-    
+
     mDynamicModelFile.open(filename.c_str(), ios::out | ios::binary);
     if (!mDynamicModelFile.is_open())
       {
@@ -1336,73 +1127,38 @@ DynamicModel::Write_Inf_To_Bin_File(const string &dynamic_basename, const string
         exit(EXIT_FAILURE);
       }
     u_count_int=0;
-    int Size = block_triangular.ModelBlock->Block_List[num].Size - block_triangular.ModelBlock->Block_List[num].Nb_Recursives;
-    for(int i=0; i<(int)block_triangular.ModelBlock->Block_List[num].Chain_Rule_Derivatives->size();i++)
-			{
-        //Chain_Rule_Derivatives.insert(make_pair( make_pair(eq, eqr), make_pair(var, make_pair(varr, lag))));
-        pair< pair<int, pair<int, int> >, pair<int, int> > it = block_triangular.ModelBlock->Block_List[num].Chain_Rule_Derivatives->at(i);
-        int k=it.first.first;
-        int eq=it.first.second.first;
-
-        int var_init=it.first.second.second;
-        /*int eqr=it.second.first;
-        int varr=it.second.second;*/
-        if(eq>=block_triangular.ModelBlock->Block_List[num].Nb_Recursives and var_init>=block_triangular.ModelBlock->Block_List[num].Nb_Recursives)
+    unsigned int block_size = getBlockSize(num);
+    unsigned int block_mfs = getBlockMfs(num);
+    unsigned int block_recursive = block_size - block_mfs;
+    for (t_block_derivatives_equation_variable_laglead_nodeid::const_iterator it = blocks_derivatives[num].begin(); it != (blocks_derivatives[num]).end(); it++)
+      {
+        unsigned int eq = it->first.first;
+        unsigned int var = it->first.second;
+        int lag = it->second.first;
+        if(eq>=block_recursive and var>=block_recursive)
 					{
-            int v=eq-block_triangular.ModelBlock->Block_List[num].Nb_Recursives;
+            int v = eq - block_recursive;
             SaveCode.write(reinterpret_cast<char *>(&v), sizeof(v));
-						int var=it.first.second.second-block_triangular.ModelBlock->Block_List[num].Nb_Recursives + k * Size;
-				    SaveCode.write(reinterpret_cast<char *>(&var), sizeof(var));
-            SaveCode.write(reinterpret_cast<char *>(&k), sizeof(k));
-            int u = u_count_int + Size;
+						int varr = var - block_recursive + lag * block_mfs;
+				    SaveCode.write(reinterpret_cast<char *>(&varr), sizeof(varr));
+            SaveCode.write(reinterpret_cast<char *>(&lag), sizeof(lag));
+            int u = u_count_int + block_mfs;
             SaveCode.write(reinterpret_cast<char *>(&u), sizeof(u));
-            //cout << "eq=" << eq << " var=" << var << " k=" << k << " u=" << u << "\n";
             u_count_int++;
 					}
-			}
-
+      }
 
-    /*for (int m=0;m<=block_triangular.ModelBlock->Block_List[num].Max_Lead+block_triangular.ModelBlock->Block_List[num].Max_Lag;m++)
-      {
-        int k1=m-block_triangular.ModelBlock->Block_List[num].Max_Lag;
-        for (j=0;j<block_triangular.ModelBlock->Block_List[num].IM_lead_lag[m].size;j++)
-          {
-            int varr=block_triangular.ModelBlock->Block_List[num].IM_lead_lag[m].Var[j]+k1*block_triangular.ModelBlock->Block_List[num].Size;
-            int u=block_triangular.ModelBlock->Block_List[num].IM_lead_lag[m].u[j];
-            int eqr1=block_triangular.ModelBlock->Block_List[num].IM_lead_lag[m].Equ[j];
-            SaveCode.write(reinterpret_cast<char *>(&eqr1), sizeof(eqr1));
-            SaveCode.write(reinterpret_cast<char *>(&varr), sizeof(varr));
-            SaveCode.write(reinterpret_cast<char *>(&k1), sizeof(k1));
-            SaveCode.write(reinterpret_cast<char *>(&u), sizeof(u));
-            u_count_int++;
-          }
-      }*/
     if (is_two_boundaries)
+			u_count_int+=block_mfs;
+    for (j = block_recursive; j < (int) block_size; j++)
       {
-        /*for (j=0;j<Size;j++)
-          {
-            int eqr1=j;
-            int varr=Size*(block_triangular.periods
-                     +block_triangular.incidencematrix.Model_Max_Lead_Endo);
-            int k1=0;
-            SaveCode.write(reinterpret_cast<char *>(&eqr1), sizeof(eqr1));
-            SaveCode.write(reinterpret_cast<char *>(&varr), sizeof(varr));
-            SaveCode.write(reinterpret_cast<char *>(&k1), sizeof(k1));
-            SaveCode.write(reinterpret_cast<char *>(&eqr1), sizeof(eqr1));
-            u_count_int++;
-          }*/
-				u_count_int+=Size;
-      }
-    //cout << "u_count_int=" << u_count_int << "\n";
-    for (j=block_triangular.ModelBlock->Block_List[num].Nb_Recursives;j<block_triangular.ModelBlock->Block_List[num].Size;j++)
-      {
-        int varr=block_triangular.ModelBlock->Block_List[num].Variable[j];
+        unsigned int varr=getBlockVariableID(num, j);
         SaveCode.write(reinterpret_cast<char *>(&varr), sizeof(varr));
       }
-    for (j=block_triangular.ModelBlock->Block_List[num].Nb_Recursives;j<block_triangular.ModelBlock->Block_List[num].Size;j++)
+    for (j = block_recursive; j < (int) block_size; j++)
       {
-        int eqr1=block_triangular.ModelBlock->Block_List[num].Equation[j];
-        SaveCode.write(reinterpret_cast<char *>(&eqr1), sizeof(eqr1));
+        unsigned int eqr=getBlockEquationID(num, j);
+        SaveCode.write(reinterpret_cast<char *>(&eqr), sizeof(eqr));
       }
     SaveCode.close();
   }
@@ -1413,8 +1169,7 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
     string sp;
     ofstream mDynamicModelFile;
     ostringstream tmp, tmp1, tmp_eq;
-    int prev_Simulation_Type, tmp_i;
-    //SymbolicGaussElimination SGE;
+    int prev_Simulation_Type;
     bool OK;
     chdir(basename.c_str());
     string filename = dynamic_basename + ".m";
@@ -1431,7 +1186,7 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
     mDynamicModelFile << "%           from model file (.mod)\n\n";
     mDynamicModelFile << "%/\n";
 
-    int i, k, Nb_SGE=0;
+    int Nb_SGE=0;
     bool skip_head, open_par=false;
 
     mDynamicModelFile << "function [varargout] = " << dynamic_basename << "(varargin)\n";
@@ -1464,95 +1219,73 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
     if (tmp_output.str().length()>0)
       mDynamicModelFile << tmp_output.str();
 
-    mDynamicModelFile << "  y_kmin=M_.maximum_lag;\n";
-    mDynamicModelFile << "  y_kmax=M_.maximum_lead;\n";
-    mDynamicModelFile << "  y_size=M_.endo_nbr;\n";
-    mDynamicModelFile << "  if(length(varargin)>0)\n";
-    mDynamicModelFile << "    %it is a simple evaluation of the dynamic model for time _it\n";
-    mDynamicModelFile << "    params=varargin{3};\n";
-    mDynamicModelFile << "    it_=varargin{4};\n";
-    /*i = symbol_table.endo_nbr*(variable_table.max_endo_lag+variable_table.max_endo_lead+1)+
-      symbol_table.exo_nbr*(variable_table.max_exo_lag+variable_table.max_exo_lead+1);
-      mDynamicModelFile << "    g1=spalloc(" << symbol_table.endo_nbr << ", " << i << ", " << i*symbol_table.endo_nbr << ");\n";*/
-    mDynamicModelFile << "    Per_u_=0;\n";
-    mDynamicModelFile << "    Per_y_=it_*y_size;\n";
-    mDynamicModelFile << "    y=varargin{1};\n";
-    mDynamicModelFile << "    ys=y(it_,:);\n";
-    mDynamicModelFile << "    x=varargin{2};\n";
+    mDynamicModelFile << "  y_kmin=M_.maximum_lag;" << endl
+                      << "  y_kmax=M_.maximum_lead;" << endl
+                      << "  y_size=M_.endo_nbr;" << endl
+                      << "  if(length(varargin)>0)" << endl
+                      << "    %it is a simple evaluation of the dynamic model for time _it" << endl
+                      << "    params=varargin{3};" << endl
+                      << "    it_=varargin{4};" << endl
+                      << "    Per_u_=0;" << endl
+                      << "    Per_y_=it_*y_size;" << endl
+                      << "    y=varargin{1};" << endl
+                      << "    ys=y(it_,:);" << endl
+                      << "    x=varargin{2};" << endl;
     prev_Simulation_Type=-1;
     tmp.str("");
     tmp_eq.str("");
-    for (int count_call=1, i = 0;i < block_triangular.ModelBlock->Size;i++, count_call++)
+    unsigned int nb_blocks = getNbBlocks();
+    unsigned int block = 0;
+    for (int count_call=1; block < nb_blocks; block++, count_call++)
       {
-        mDynamicModelFile << "    %block_triangular.ModelBlock->Block_List[i].Nb_Recursives=" << block_triangular.ModelBlock->Block_List[i].Nb_Recursives << " block_triangular.ModelBlock->Block_List[i].Size=" <<  block_triangular.ModelBlock->Block_List[i].Size << "\n";
-        k=block_triangular.ModelBlock->Block_List[i].Simulation_Type;
-        if(k==EVALUATE_FORWARD || k==EVALUATE_BACKWARD)
+        unsigned int block_size = getBlockSize(block);
+        unsigned int block_mfs = getBlockMfs(block);
+        unsigned int block_recursive = block_size - block_mfs;
+        BlockSimulationType simulation_type = getBlockSimulationType(block);
+
+        if(simulation_type==EVALUATE_FORWARD || simulation_type==EVALUATE_BACKWARD)
           {
-            for (int ik=0 ;ik<block_triangular.ModelBlock->Block_List[i].Size;ik++)
+            for (unsigned int ik=0 ;ik<block_size;ik++)
               {
-                tmp << " " << block_triangular.ModelBlock->Block_List[i].Variable[ik]+1;
-                tmp_eq << " " << block_triangular.ModelBlock->Block_List[i].Equation[ik]+1;
+                tmp << " " << getBlockVariableID(block, ik)+1;
+                tmp_eq << " " << getBlockEquationID(block, ik)+1;
               }
           }
         else
           {
-            for (int ik=block_triangular.ModelBlock->Block_List[i].Nb_Recursives ;ik<block_triangular.ModelBlock->Block_List[i].Size;ik++)
+            for (unsigned int ik = block_recursive; ik < block_size; ik++)
               {
-                tmp << " " << block_triangular.ModelBlock->Block_List[i].Variable[ik]+1;
-                tmp_eq << " " << block_triangular.ModelBlock->Block_List[i].Equation[ik]+1;
+                tmp << " " << getBlockVariableID(block, ik)+1;
+                tmp_eq << " " << getBlockEquationID(block, ik)+1;
               }
           }
         mDynamicModelFile << "    y_index_eq=[" << tmp_eq.str() << "];\n";
         mDynamicModelFile << "    y_index=[" << tmp.str() << "];\n";
 
-        switch (k)
+        switch (simulation_type)
           {
           case EVALUATE_FORWARD:
           case EVALUATE_BACKWARD:
-            mDynamicModelFile << "    [y, dr(" << count_call << ").g1, dr(" << count_call << ").g2, dr(" << count_call << ").g3, dr(" << count_call << ").g1_x, dr(" << count_call << ").g1_o]=" << dynamic_basename << "_" << i + 1 << "(y, x, params, 1, it_-1, 1);\n";
+            mDynamicModelFile << "    [y, dr(" << count_call << ").g1, dr(" << count_call << ").g2, dr(" << count_call << ").g3, dr(" << count_call << ").g1_x, dr(" << count_call << ").g1_o]=" << dynamic_basename << "_" << block + 1 << "(y, x, params, 1, it_-1, 1);\n";
             mDynamicModelFile << "    residual(y_index_eq)=ys(y_index)-y(it_, y_index);\n";
            break;
           case SOLVE_FORWARD_SIMPLE:
           case SOLVE_BACKWARD_SIMPLE:
-            //mDynamicModelFile << "    y_index_eq = " << block_triangular.ModelBlock->Block_List[i].Equation[0]+1 << ";\n";
-            mDynamicModelFile << "    [r, dr(" << count_call << ").g1, dr(" << count_call << ").g2, dr(" << count_call << ").g3, dr(" << count_call << ").g1_x, dr(" << count_call << ").g1_o]=" << dynamic_basename << "_" << i + 1 << "(y, x, params, it_, 1);\n";
+            mDynamicModelFile << "    [r, dr(" << count_call << ").g1, dr(" << count_call << ").g2, dr(" << count_call << ").g3, dr(" << count_call << ").g1_x, dr(" << count_call << ").g1_o]=" << dynamic_basename << "_" << block + 1 << "(y, x, params, it_, 1);\n";
             mDynamicModelFile << "    residual(y_index_eq)=r;\n";
             break;
           case SOLVE_FORWARD_COMPLETE:
           case SOLVE_BACKWARD_COMPLETE:
-            //mDynamicModelFile << "    y_index_eq = [" << tmp_eq.str() << "];\n";
-            mDynamicModelFile << "    [r, dr(" << count_call << ").g1, dr(" << count_call << ").g2, dr(" << count_call << ").g3, dr(" << count_call << ").g1_x, dr(" << count_call << ").g1_o]=" << dynamic_basename << "_" << i + 1 << "(y, x, params, it_, 1);\n";
+            mDynamicModelFile << "    [r, dr(" << count_call << ").g1, dr(" << count_call << ").g2, dr(" << count_call << ").g3, dr(" << count_call << ").g1_x, dr(" << count_call << ").g1_o]=" << dynamic_basename << "_" << block + 1 << "(y, x, params, it_, 1);\n";
             mDynamicModelFile << "    residual(y_index_eq)=r;\n";
             break;
           case SOLVE_TWO_BOUNDARIES_COMPLETE:
           case SOLVE_TWO_BOUNDARIES_SIMPLE:
-            int j;
-            /*mDynamicModelFile << "    y_index_eq = [" << tmp_eq.str() << "];\n";
-            tmp_i=block_triangular.ModelBlock->Block_List[i].Max_Lag_Endo+block_triangular.ModelBlock->Block_List[i].Max_Lead_Endo+1;
-            mDynamicModelFile << "    y_index = [";
-            for (j=0;j<tmp_i;j++)
-              for (int ik=0;ik<block_triangular.ModelBlock->Block_List[i].Size;ik++)
-                {
-                  mDynamicModelFile << " " << block_triangular.ModelBlock->Block_List[i].Variable[ik]+1+j*symbol_table.endo_nbr();
-                }
-            int tmp_ix=block_triangular.ModelBlock->Block_List[i].Max_Lag_Exo+block_triangular.ModelBlock->Block_List[i].Max_Lead_Exo+1;
-            for (j=0;j<tmp_ix;j++)
-              for (int ik=0;ik<block_triangular.ModelBlock->Block_List[i].nb_exo;ik++)
-                mDynamicModelFile << " " << block_triangular.ModelBlock->Block_List[i].Exogenous[ik]+1+j*symbol_table.exo_nbr()+symbol_table.endo_nbr()*tmp_i;
-            mDynamicModelFile << " ];\n";*/
-            //mDynamicModelFile << "    ga = [];\n";
-            j = block_triangular.ModelBlock->Block_List[i].Size*(block_triangular.ModelBlock->Block_List[i].Max_Lag_Endo+block_triangular.ModelBlock->Block_List[i].Max_Lead_Endo+1)
-                + block_triangular.ModelBlock->Block_List[i].nb_exo*(block_triangular.ModelBlock->Block_List[i].Max_Lag_Exo+block_triangular.ModelBlock->Block_List[i].Max_Lead_Exo+1);
-            /*mDynamicModelFile << "    ga=spalloc(" << block_triangular.ModelBlock->Block_List[i].Size << ", " << j << ", " <<
-              block_triangular.ModelBlock->Block_List[i].Size*j << ");\n";*/
-            tmp_i=block_triangular.ModelBlock->Block_List[i].Max_Lag_Endo+block_triangular.ModelBlock->Block_List[i].Max_Lead_Endo+1;
-            mDynamicModelFile << "    [r, dr(" << count_call << ").g1, dr(" << count_call << ").g2, dr(" << count_call << ").g3, b, dr(" << count_call << ").g1_x, dr(" << count_call << ").g1_o]=" << dynamic_basename << "_" <<  i + 1 << "(y, x, params, it_-" << max_lag << ", 1, " << max_lag << ", " << block_triangular.ModelBlock->Block_List[i].Size-block_triangular.ModelBlock->Block_List[i].Nb_Recursives << ");\n";
-            /*if(block_triangular.ModelBlock->Block_List[i].Max_Lag==variable_table.max_lag && block_triangular.ModelBlock->Block_List[i].Max_Lead==variable_table.max_lead)
-              mDynamicModelFile << "    g1(y_index_eq,y_index) = ga;\n";
-              else
-              mDynamicModelFile << "    g1(y_index_eq,y_index) = ga(:," << 1+(variable_table.max_lag-block_triangular.ModelBlock->Block_List[i].Max_Lag)*block_triangular.ModelBlock->Block_List[i].Size << ":" << (variable_table.max_lag+1+block_triangular.ModelBlock->Block_List[i].Max_Lead)*block_triangular.ModelBlock->Block_List[i].Size << ");\n";*/
+            mDynamicModelFile << "    [r, dr(" << count_call << ").g1, dr(" << count_call << ").g2, dr(" << count_call << ").g3, b, dr(" << count_call << ").g1_x, dr(" << count_call << ").g1_o]=" << dynamic_basename << "_" <<  block + 1 << "(y, x, params, it_-" << max_lag << ", 1, " << max_lag << ", " << block_recursive << ");\n";
             mDynamicModelFile << "    residual(y_index_eq)=r(:,M_.maximum_lag+1);\n";
             break;
+          default:
+            break;
           }
         tmp_eq.str("");
         tmp.str("");
@@ -1562,43 +1295,47 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
         mDynamicModelFile << tmp1.str();
         tmp1.str("");
       }
-    mDynamicModelFile << "    varargout{1}=residual;\n";
-    mDynamicModelFile << "    varargout{2}=dr;\n";
-    mDynamicModelFile << "    return;\n";
-    mDynamicModelFile << "  end;\n";
-    mDynamicModelFile << "  %it is the deterministic simulation of the block decomposed dynamic model\n";
-    mDynamicModelFile << "  if(options_.stack_solve_algo==1)\n";
-    mDynamicModelFile << "    mthd='Sparse LU';\n";
-    mDynamicModelFile << "  elseif(options_.stack_solve_algo==2)\n";
-    mDynamicModelFile << "    mthd='GMRES';\n";
-    mDynamicModelFile << "  elseif(options_.stack_solve_algo==3)\n";
-    mDynamicModelFile << "    mthd='BICGSTAB';\n";
-    mDynamicModelFile << "  elseif(options_.stack_solve_algo==4)\n";
-    mDynamicModelFile << "    mthd='OPTIMPATH';\n";
-    mDynamicModelFile << "  else\n";
-    mDynamicModelFile << "    mthd='UNKNOWN';\n";
-    mDynamicModelFile << "  end;\n";
-    mDynamicModelFile << "  disp (['-----------------------------------------------------']) ;\n";
-    mDynamicModelFile << "  disp (['MODEL SIMULATION: (method=' mthd ')']) ;\n";
-    mDynamicModelFile << "  fprintf('\\n') ;\n";
-    mDynamicModelFile << "  periods=options_.periods;\n";
-    mDynamicModelFile << "  maxit_=options_.maxit_;\n";
-    mDynamicModelFile << "  solve_tolf=options_.solve_tolf;\n";
-    mDynamicModelFile << "  y=oo_.endo_simul';\n";
-    mDynamicModelFile << "  x=oo_.exo_simul;\n";
+    mDynamicModelFile << "    varargout{1}=residual;" << endl
+                      << "    varargout{2}=dr;" << endl
+                      << "    return;" << endl
+                      << "  end;" << endl
+                      << "  %it is the deterministic simulation of the block decomposed dynamic model" << endl
+                      << "  if(options_.stack_solve_algo==1)" << endl
+                      << "    mthd='Sparse LU';" << endl
+                      << "  elseif(options_.stack_solve_algo==2)" << endl
+                      << "    mthd='GMRES';" << endl
+                      << "  elseif(options_.stack_solve_algo==3)" << endl
+                      << "    mthd='BICGSTAB';" << endl
+                      << "  elseif(options_.stack_solve_algo==4)" << endl
+                      << "    mthd='OPTIMPATH';" << endl
+                      << "  else" << endl
+                      << "    mthd='UNKNOWN';" << endl
+                      << "  end;" << endl
+                      << "  disp (['-----------------------------------------------------']) ;" << endl
+                      << "  disp (['MODEL SIMULATION: (method=' mthd ')']) ;" << endl
+                      << "  fprintf('\\n') ;" << endl
+                      << "  periods=options_.periods;" << endl
+                      << "  maxit_=options_.maxit_;" << endl
+                      << "  solve_tolf=options_.solve_tolf;" << endl
+                      << "  y=oo_.endo_simul';" << endl
+                      << "  x=oo_.exo_simul;" << endl;
 
     prev_Simulation_Type=-1;
     mDynamicModelFile << "  params=M_.params;\n";
     mDynamicModelFile << "  oo_.deterministic_simulation.status = 0;\n";
-    for (i = 0;i < block_triangular.ModelBlock->Size;i++)
+    for (block = 0;block < nb_blocks; block++)
       {
-        k = block_triangular.ModelBlock->Block_List[i].Simulation_Type;
-        if (BlockTriangular::BlockSim(prev_Simulation_Type)==BlockTriangular::BlockSim(k) &&
-            (k==EVALUATE_FORWARD || k==EVALUATE_BACKWARD /*|| k==EVALUATE_FORWARD_R || k==EVALUATE_BACKWARD_R*/))
+        unsigned int block_size = getBlockSize(block);
+        unsigned int block_mfs = getBlockMfs(block);
+        unsigned int block_recursive = block_size - block_mfs;
+        BlockSimulationType simulation_type = getBlockSimulationType(block);
+
+        if (BlockSim(prev_Simulation_Type)==BlockSim(simulation_type) &&
+            (simulation_type==EVALUATE_FORWARD || simulation_type==EVALUATE_BACKWARD ))
           skip_head=true;
         else
           skip_head=false;
-        if ((k == EVALUATE_FORWARD /*|| k == EVALUATE_FORWARD_R*/) && (block_triangular.ModelBlock->Block_List[i].Size))
+        if ((simulation_type == EVALUATE_FORWARD ) && (block_size))
           {
             if (!skip_head)
               {
@@ -1618,17 +1355,15 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
                 mDynamicModelFile << "  oo_.deterministic_simulation.block(blck_num).error = 0;\n";
                 mDynamicModelFile << "  oo_.deterministic_simulation.block(blck_num).iterations = 0;\n";
                 mDynamicModelFile << "  g1=[];g2=[];g3=[];\n";
-                //mDynamicModelFile << "  for it_ = y_kmin+1:(periods+y_kmin)\n";
-                mDynamicModelFile << "  y=" << dynamic_basename << "_" << i + 1 << "(y, x, params, 0, y_kmin, periods);\n";
-                mDynamicModelFile << "  tmp = y(:,M_.block_structure.block(" << i + 1 << ").variable);\n";
+                mDynamicModelFile << "  y=" << dynamic_basename << "_" << block + 1 << "(y, x, params, 0, y_kmin, periods);\n";
+                mDynamicModelFile << "  tmp = y(:,M_.block_structure.block(" << block + 1 << ").variable);\n";
                 mDynamicModelFile << "  if(isnan(tmp) | isinf(tmp))\n";
-                mDynamicModelFile << "    disp(['Inf or Nan value during the evaluation of block " << i <<"']);\n";
+                mDynamicModelFile << "    disp(['Inf or Nan value during the evaluation of block " << block <<"']);\n";
                 mDynamicModelFile << "    return;\n";
                 mDynamicModelFile << "  end;\n";
               }
-            //open_par=true;
           }
-        else if ((k == EVALUATE_BACKWARD /*|| k == EVALUATE_BACKWARD_R*/) && (block_triangular.ModelBlock->Block_List[i].Size))
+        else if ((simulation_type == EVALUATE_BACKWARD ) && (block_size))
           {
             if (!skip_head)
               {
@@ -1648,15 +1383,15 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
                 mDynamicModelFile << "  oo_.deterministic_simulation.block(blck_num).error = 0;\n";
                 mDynamicModelFile << "  oo_.deterministic_simulation.block(blck_num).iterations = 0;\n";
                 mDynamicModelFile << "  g1=[];g2=[];g3=[];\n";
-                mDynamicModelFile << "  " << dynamic_basename << "_" << i + 1 << "(y, x, params, 0, y_kmin, periods);\n";
-                mDynamicModelFile << "  tmp = y(:,M_.block_structure.block(" << i + 1 << ").variable);\n";
+                mDynamicModelFile << "  " << dynamic_basename << "_" << block + 1 << "(y, x, params, 0, y_kmin, periods);\n";
+                mDynamicModelFile << "  tmp = y(:,M_.block_structure.block(" << block + 1 << ").variable);\n";
                 mDynamicModelFile << "  if(isnan(tmp) | isinf(tmp))\n";
-                mDynamicModelFile << "    disp(['Inf or Nan value during the evaluation of block " << i <<"']);\n";
+                mDynamicModelFile << "    disp(['Inf or Nan value during the evaluation of block " << block <<"']);\n";
                 mDynamicModelFile << "    return;\n";
                 mDynamicModelFile << "  end;\n";
               }
           }
-        else if ((k == SOLVE_FORWARD_COMPLETE || k == SOLVE_FORWARD_SIMPLE) && (block_triangular.ModelBlock->Block_List[i].Size))
+        else if ((simulation_type == SOLVE_FORWARD_COMPLETE || simulation_type == SOLVE_FORWARD_SIMPLE) && (block_size))
           {
             if (open_par)
               mDynamicModelFile << "  end\n";
@@ -1664,30 +1399,28 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
             mDynamicModelFile << "  g1=0;\n";
             mDynamicModelFile << "  r=0;\n";
             tmp.str("");
-            for (int ik=block_triangular.ModelBlock->Block_List[i].Nb_Recursives ;ik<block_triangular.ModelBlock->Block_List[i].Size;ik++)
+            for (unsigned int ik = block_recursive; ik < block_size; ik++)
               {
-                tmp << " " << block_triangular.ModelBlock->Block_List[i].Variable[ik]+1;
+                tmp << " " << getBlockVariableID(block, ik)+1;
               }
             mDynamicModelFile << "  y_index = [" << tmp.str() << "];\n";
-            int nze, m;
-            for (nze=0,m=0;m<=block_triangular.ModelBlock->Block_List[i].Max_Lead+block_triangular.ModelBlock->Block_List[i].Max_Lag;m++)
-              nze+=block_triangular.ModelBlock->Block_List[i].IM_lead_lag[m].size;
+            int nze = blocks_derivatives[block].size();
             mDynamicModelFile << "  if(isfield(oo_.deterministic_simulation,'block'))\n";
             mDynamicModelFile << "    blck_num = length(oo_.deterministic_simulation.block)+1;\n";
             mDynamicModelFile << "  else\n";
             mDynamicModelFile << "    blck_num = 1;\n";
             mDynamicModelFile << "  end;\n";
-            mDynamicModelFile << "  y = solve_one_boundary('"  << dynamic_basename << "_" <<  i + 1 << "'" <<
+            mDynamicModelFile << "  y = solve_one_boundary('"  << dynamic_basename << "_" <<  block + 1 << "'" <<
             ", y, x, params, y_index, " << nze <<
-            ", options_.periods, " << block_triangular.ModelBlock->Block_List[i].is_linear <<
+            ", options_.periods, " << blocks_linear[block] <<
               ", blck_num, y_kmin, options_.maxit_, options_.solve_tolf, options_.slowc, " << cutoff << ", options_.stack_solve_algo, 1, 1, 0);\n";
-            mDynamicModelFile << "  tmp = y(:,M_.block_structure.block(" << i + 1 << ").variable);\n";
+            mDynamicModelFile << "  tmp = y(:,M_.block_structure.block(" << block + 1 << ").variable);\n";
             mDynamicModelFile << "  if(isnan(tmp) | isinf(tmp))\n";
-            mDynamicModelFile << "    disp(['Inf or Nan value during the resolution of block " << i <<"']);\n";
+            mDynamicModelFile << "    disp(['Inf or Nan value during the resolution of block " << block <<"']);\n";
             mDynamicModelFile << "    return;\n";
             mDynamicModelFile << "  end;\n";
           }
-        else if ((k == SOLVE_BACKWARD_COMPLETE || k == SOLVE_BACKWARD_SIMPLE) && (block_triangular.ModelBlock->Block_List[i].Size))
+        else if ((simulation_type == SOLVE_BACKWARD_COMPLETE || simulation_type == SOLVE_BACKWARD_SIMPLE) && (block_size))
           {
             if (open_par)
               mDynamicModelFile << "  end\n";
@@ -1695,42 +1428,39 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
             mDynamicModelFile << "  g1=0;\n";
             mDynamicModelFile << "  r=0;\n";
             tmp.str("");
-            for (int ik=block_triangular.ModelBlock->Block_List[i].Nb_Recursives ;ik<block_triangular.ModelBlock->Block_List[i].Size;ik++)
+            for (unsigned int ik = block_recursive; ik < block_size; ik++)
               {
-                 tmp << " " << block_triangular.ModelBlock->Block_List[i].Variable[ik]+1;
+                 tmp << " " << getBlockVariableID(block, ik)+1;
               }
             mDynamicModelFile << "  y_index = [" << tmp.str() << "];\n";
-            int nze, m;
-            for (nze=0,m=0;m<=block_triangular.ModelBlock->Block_List[i].Max_Lead+block_triangular.ModelBlock->Block_List[i].Max_Lag;m++)
-              nze+=block_triangular.ModelBlock->Block_List[i].IM_lead_lag[m].size;
+            int nze = blocks_derivatives[block].size();
+
             mDynamicModelFile << "  if(isfield(oo_.deterministic_simulation,'block'))\n";
             mDynamicModelFile << "    blck_num = length(oo_.deterministic_simulation.block)+1;\n";
             mDynamicModelFile << "  else\n";
             mDynamicModelFile << "    blck_num = 1;\n";
             mDynamicModelFile << "  end;\n";
-            mDynamicModelFile << "  y = solve_one_boundary('"  << dynamic_basename << "_" <<  i + 1 << "'" <<
+            mDynamicModelFile << "  y = solve_one_boundary('"  << dynamic_basename << "_" <<  block + 1 << "'" <<
             ", y, x, params, y_index, " << nze <<
-            ", options_.periods, " << block_triangular.ModelBlock->Block_List[i].is_linear <<
+            ", options_.periods, " << blocks_linear[block] <<
             ", blck_num, y_kmin, options_.maxit_, options_.solve_tolf, options_.slowc, " << cutoff << ", options_.stack_solve_algo, 1, 1, 0);\n";
-            mDynamicModelFile << "  tmp = y(:,M_.block_structure.block(" << i + 1 << ").variable);\n";
+            mDynamicModelFile << "  tmp = y(:,M_.block_structure.block(" << block + 1 << ").variable);\n";
             mDynamicModelFile << "  if(isnan(tmp) | isinf(tmp))\n";
-            mDynamicModelFile << "    disp(['Inf or Nan value during the resolution of block " << i <<"']);\n";
+            mDynamicModelFile << "    disp(['Inf or Nan value during the resolution of block " << block <<"']);\n";
             mDynamicModelFile << "    return;\n";
             mDynamicModelFile << "  end;\n";
           }
-        else if ((k == SOLVE_TWO_BOUNDARIES_COMPLETE || k == SOLVE_TWO_BOUNDARIES_SIMPLE) && (block_triangular.ModelBlock->Block_List[i].Size))
+        else if ((simulation_type == SOLVE_TWO_BOUNDARIES_COMPLETE || simulation_type == SOLVE_TWO_BOUNDARIES_SIMPLE) && (block_size))
           {
             if (open_par)
               mDynamicModelFile << "  end\n";
             open_par=false;
             Nb_SGE++;
-            int nze, m;
-            for (nze=0,m=0;m<=block_triangular.ModelBlock->Block_List[i].Max_Lead+block_triangular.ModelBlock->Block_List[i].Max_Lag;m++)
-              nze+=block_triangular.ModelBlock->Block_List[i].IM_lead_lag[m].size;
+            int nze = blocks_derivatives[block].size();
             mDynamicModelFile << "  y_index=[";
-            for (int ik=block_triangular.ModelBlock->Block_List[i].Nb_Recursives ;ik<block_triangular.ModelBlock->Block_List[i].Size;ik++)
+            for (unsigned int ik = block_recursive; ik < block_size; ik++)
               {
-                mDynamicModelFile << " " << block_triangular.ModelBlock->Block_List[i].Variable[ik]+1;
+                mDynamicModelFile << " " << getBlockVariableID(block, ik)+1;
               }
             mDynamicModelFile << "  ];\n";
             mDynamicModelFile << "  if(isfield(oo_.deterministic_simulation,'block'))\n";
@@ -1738,19 +1468,19 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
             mDynamicModelFile << "  else\n";
             mDynamicModelFile << "    blck_num = 1;\n";
             mDynamicModelFile << "  end;\n";
-            mDynamicModelFile << "  y = solve_two_boundaries('" << dynamic_basename << "_" <<  i + 1 << "'" <<
+            mDynamicModelFile << "  y = solve_two_boundaries('" << dynamic_basename << "_" <<  block + 1 << "'" <<
             ", y, x, params, y_index, " << nze <<
-            ", options_.periods, " << block_triangular.ModelBlock->Block_List[i].Max_Lag <<
-            ", " << block_triangular.ModelBlock->Block_List[i].Max_Lead <<
-            ", " << block_triangular.ModelBlock->Block_List[i].is_linear <<
+            ", options_.periods, " << max_leadlag_block[block].first <<
+            ", " << max_leadlag_block[block].second <<
+            ", " << blocks_linear[block] <<
             ", blck_num, y_kmin, options_.maxit_, options_.solve_tolf, options_.slowc, " << cutoff << ", options_.stack_solve_algo);\n";
-            mDynamicModelFile << "  tmp = y(:,M_.block_structure.block(" << i + 1 << ").variable);\n";
+            mDynamicModelFile << "  tmp = y(:,M_.block_structure.block(" << block + 1 << ").variable);\n";
             mDynamicModelFile << "  if(isnan(tmp) | isinf(tmp))\n";
-            mDynamicModelFile << "    disp(['Inf or Nan value during the resolution of block " << i <<"']);\n";
+            mDynamicModelFile << "    disp(['Inf or Nan value during the resolution of block " << block <<"']);\n";
             mDynamicModelFile << "    return;\n";
             mDynamicModelFile << "  end;\n";
           }
-        prev_Simulation_Type=k;
+        prev_Simulation_Type=simulation_type;
       }
     if (open_par)
       mDynamicModelFile << "  end;\n";
@@ -1760,7 +1490,7 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
 
     mDynamicModelFile.close();
 
-    writeModelEquationsOrdered_M( block_triangular.ModelBlock, dynamic_basename);
+    writeModelEquationsOrdered_M(dynamic_basename);
 
     chdir("..");
   }
@@ -1993,7 +1723,7 @@ DynamicModel::writeDynamicModel(ostream &DynamicOutput, bool use_dll) const
   }
 
 void
-DynamicModel::writeOutput(ostream &output, const string &basename, bool block, bool byte_code, bool use_dll) const
+DynamicModel::writeOutput(ostream &output, const string &basename, bool block_decomposition, bool byte_code, bool use_dll) const
   {
     /* Writing initialisation for M_.lead_lag_incidence matrix
        M_.lead_lag_incidence is a matrix with as many columns as there are
@@ -2035,58 +1765,50 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block, b
              << equation_tags[i].second.second << "' ;" << endl;
     output << "};" << endl;
 
-    //In case of sparse model, writes the block structure of the model
-    if (block)
+    //In case of sparse model, writes the block_decomposition structure of the model
+    if (block_decomposition)
       {
-        //int prev_Simulation_Type=-1;
-        //bool skip_the_head;
-        int k=0;
         int count_lead_lag_incidence = 0;
         int max_lead, max_lag, max_lag_endo, max_lead_endo, max_lag_exo, max_lead_exo;
-        for (int j = 0;j < block_triangular.ModelBlock->Size;j++)
+        unsigned int nb_blocks = getNbBlocks();
+        for (unsigned int block = 0; block < nb_blocks; block++)
           {
             //For a block composed of a single equation determines wether we have to evaluate or to solve the equation
-            //skip_the_head=false;
-            k++;
             count_lead_lag_incidence = 0;
-            int Block_size=block_triangular.ModelBlock->Block_List[j].Size;
-            max_lag =block_triangular.ModelBlock->Block_List[j].Max_Lag ;
-            max_lead=block_triangular.ModelBlock->Block_List[j].Max_Lead;
-            max_lag_endo =block_triangular.ModelBlock->Block_List[j].Max_Lag_Endo ;
-            max_lead_endo=block_triangular.ModelBlock->Block_List[j].Max_Lead_Endo;
-            max_lag_exo =block_triangular.ModelBlock->Block_List[j].Max_Lag_Exo ;
-            max_lead_exo=block_triangular.ModelBlock->Block_List[j].Max_Lead_Exo;
-            bool evaluate=false;
-            vector<int> exogenous;
+            BlockSimulationType simulation_type = getBlockSimulationType(block);
+            int block_size = getBlockSize(block);
+            max_lag  = max_leadlag_block[block].first;
+            max_lead = max_leadlag_block[block].second;
+            max_lag_endo = endo_max_leadlag_block[block].first;
+            max_lead_endo= endo_max_leadlag_block[block].second;
+            max_lag_exo = max(exo_max_leadlag_block[block].first, exo_det_max_leadlag_block[block].first);
+            max_lead_exo= max(exo_max_leadlag_block[block].second, exo_det_max_leadlag_block[block].second);
+            vector<int> exogenous(symbol_table.exo_nbr(), -1);
             vector<int>::iterator it_exogenous;
             exogenous.clear();
             ostringstream tmp_s, tmp_s_eq;
             tmp_s.str("");
             tmp_s_eq.str("");
-            for (int i=0;i<block_triangular.ModelBlock->Block_List[j].Size;i++)
+            for (int i=0;i<block_size;i++)
               {
-                tmp_s << " " << block_triangular.ModelBlock->Block_List[j].Variable[i]+1;
-                tmp_s_eq << " " << block_triangular.ModelBlock->Block_List[j].Equation[i]+1;
+                tmp_s << " " << getBlockVariableID(block, i)+1;
+                tmp_s_eq << " " << getBlockEquationID(block, i)+1;
               }
-            for (int i=0;i<block_triangular.ModelBlock->Block_List[j].nb_exo;i++)
-              {
-                int ii=block_triangular.ModelBlock->Block_List[j].Exogenous[i];
-                for (it_exogenous=exogenous.begin();it_exogenous!=exogenous.end() && *it_exogenous!=ii;it_exogenous++) /*cout << "*it_exogenous=" << *it_exogenous << "\n"*/;
-                if (it_exogenous==exogenous.end() || exogenous.begin()==exogenous.end())
-                  exogenous.push_back(ii);
-              }
-            output << "M_.block_structure.block(" << k << ").num = " << j+1 << ";\n";
-            output << "M_.block_structure.block(" << k << ").Simulation_Type = " << block_triangular.ModelBlock->Block_List[j].Simulation_Type << ";\n";
-            output << "M_.block_structure.block(" << k << ").maximum_lag = " << max_lag << ";\n";
-            output << "M_.block_structure.block(" << k << ").maximum_lead = " << max_lead << ";\n";
-            output << "M_.block_structure.block(" << k << ").maximum_endo_lag = " << max_lag_endo << ";\n";
-            output << "M_.block_structure.block(" << k << ").maximum_endo_lead = " << max_lead_endo << ";\n";
-            output << "M_.block_structure.block(" << k << ").maximum_exo_lag = " << max_lag_exo << ";\n";
-            output << "M_.block_structure.block(" << k << ").maximum_exo_lead = " << max_lead_exo << ";\n";
-            output << "M_.block_structure.block(" << k << ").endo_nbr = " << Block_size << ";\n";
-            output << "M_.block_structure.block(" << k << ").equation = [" << tmp_s_eq.str() << "];\n";
-            output << "M_.block_structure.block(" << k << ").variable = [" << tmp_s.str() << "];\n";
-            output << "M_.block_structure.block(" << k << ").exogenous = [";
+            it_exogenous = exogenous.begin();
+            for(t_lag_var::const_iterator it = exo_block[block].begin(); it != exo_block[block].end(); it++)
+              it_exogenous = set_union(it->second.begin(), it->second.end(), exogenous.begin(), exogenous.end(), it_exogenous);
+            output << "M_.block_structure.block(" << block+1 << ").num = " << block+1 << ";\n";
+            output << "M_.block_structure.block(" << block+1 << ").Simulation_Type = " << simulation_type << ";\n";
+            output << "M_.block_structure.block(" << block+1 << ").maximum_lag = " << max_lag << ";\n";
+            output << "M_.block_structure.block(" << block+1 << ").maximum_lead = " << max_lead << ";\n";
+            output << "M_.block_structure.block(" << block+1 << ").maximum_endo_lag = " << max_lag_endo << ";\n";
+            output << "M_.block_structure.block(" << block+1 << ").maximum_endo_lead = " << max_lead_endo << ";\n";
+            output << "M_.block_structure.block(" << block+1 << ").maximum_exo_lag = " << max_lag_exo << ";\n";
+            output << "M_.block_structure.block(" << block+1 << ").maximum_exo_lead = " << max_lead_exo << ";\n";
+            output << "M_.block_structure.block(" << block+1 << ").endo_nbr = " << block_size << ";\n";
+            output << "M_.block_structure.block(" << block+1 << ").equation = [" << tmp_s_eq.str() << "];\n";
+            output << "M_.block_structure.block(" << block+1 << ").variable = [" << tmp_s.str() << "];\n";
+            output << "M_.block_structure.block(" << block+1 << ").exogenous = [";
             int i=0;
             for (it_exogenous=exogenous.begin();it_exogenous!=exogenous.end();it_exogenous++)
               if (*it_exogenous>=0)
@@ -2095,112 +1817,79 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block, b
                   i++;
                 }
             output << "];\n";
-            output << "M_.block_structure.block(" << k << ").exo_nbr = " << i << ";\n";
+            output << "M_.block_structure.block(" << block+1 << ").exo_nbr = " << i << ";\n";
 
-            output << "M_.block_structure.block(" << k << ").exo_det_nbr = " << block_triangular.ModelBlock->Block_List[j].nb_exo_det << ";\n";
+            output << "M_.block_structure.block(" << block+1 << ").exo_det_nbr = " << exo_det_block.size() << ";\n";
 
             tmp_s.str("");
-
-            bool done_IM=false;
-            if (!evaluate)
-              {
-                output << "M_.block_structure.block(" << k << ").lead_lag_incidence = [];\n";
-                for (int l=-max_lag_endo;l<max_lead_endo+1;l++)
-                  {
-                    bool *tmp_IM;
-                    tmp_IM=block_triangular.incidencematrix.Get_IM(l, eEndogenous);
-                    if (tmp_IM)
-                      {
-                        for (int l_var=0;l_var<block_triangular.ModelBlock->Block_List[j].Size;l_var++)
-                          {
-                            for (int l_equ=0;l_equ<block_triangular.ModelBlock->Block_List[j].Size;l_equ++)
-                              if (tmp_IM[block_triangular.ModelBlock->Block_List[j].Equation[l_equ]*symbol_table.endo_nbr()+block_triangular.ModelBlock->Block_List[j].Variable[l_var]])
-                                {
-                                  count_lead_lag_incidence++;
-                                  if (tmp_s.str().length())
-                                    tmp_s << " ";
-                                  tmp_s << count_lead_lag_incidence;
-                                  done_IM=true;
-                                  break;
-                                }
-                            if (!done_IM)
-                              tmp_s << " 0";
-                            done_IM=false;
-                          }
-                        output << "M_.block_structure.block(" << k << ").lead_lag_incidence = [ M_.block_structure.block(" << k << ").lead_lag_incidence; " << tmp_s.str() << "];\n";
-                        tmp_s.str("");
-                      }
-                  }
-              }
-            else
+            count_lead_lag_incidence = 0;
+            dynamic_jacob_map reordered_dynamic_jacobian;
+            for (t_block_derivatives_equation_variable_laglead_nodeid::const_iterator it = blocks_derivatives[block].begin(); it != blocks_derivatives[block].end(); it++)
+              reordered_dynamic_jacobian[make_pair(it->second.first, make_pair(it->first.second, it->first.first))] = it->second.second;
+            output << "M_.block_structure.block(" << block+1 << ").lead_lag_incidence = [];\n";
+            int last_var = -1;
+            for (int lag=-max_lag_endo;lag<max_lead_endo+1;lag++)
               {
-                bool done_some_where;
-                output << "M_.block_structure.block(" << k << ").lead_lag_incidence = [\n";
-                for (int l=-max_lag_endo;l<max_lead_endo+1;l++)
+                last_var = 0;
+                for (dynamic_jacob_map::const_iterator it = reordered_dynamic_jacobian.begin(); it != reordered_dynamic_jacobian.end(); it++)
                   {
-                    bool not_increm=true;
-                    bool *tmp_IM;
-                    tmp_IM=block_triangular.incidencematrix.Get_IM(l, eEndogenous);
-                    int ii=j;
-                    if (tmp_IM)
+                    if (lag == it->first.first && last_var != it->first.second.first)
                       {
-                        done_some_where = false;
-                        while (ii-j<Block_size)
-                          {
-                            for (int l_var=0;l_var<block_triangular.ModelBlock->Block_List[ii].Size;l_var++)
-                              {
-                                for (int l_equ=0;l_equ<block_triangular.ModelBlock->Block_List[ii].Size;l_equ++)
-                                  if (tmp_IM[block_triangular.ModelBlock->Block_List[ii].Equation[l_equ]*symbol_table.endo_nbr()+block_triangular.ModelBlock->Block_List[ii].Variable[l_var]])
-                                    {
-                                      //if(not_increm && l==-max_lag)
-                                      count_lead_lag_incidence++;
-                                      not_increm=false;
-                                      if (tmp_s.str().length())
-                                        tmp_s << " ";
-                                      //tmp_s << count_lead_lag_incidence+(l+max_lag)*Block_size;
-                                      tmp_s << count_lead_lag_incidence;
-                                      done_IM=true;
-                                      break;
-                                    }
-                                if (!done_IM)
-                                  tmp_s << " 0";
-                                else
-                                  done_some_where = true;
-                                done_IM=false;
-                              }
-                            ii++;
-                          }
-                        output << tmp_s.str() << "\n";
-                        tmp_s.str("");
+                         count_lead_lag_incidence++;
+                         for( int i = last_var; i < it->first.second.first-1; i++)
+                           tmp_s << " 0";
+                         if (tmp_s.str().length())
+                           tmp_s << " ";
+                         tmp_s << count_lead_lag_incidence;
+                         last_var = it->first.second.first;
                       }
                   }
-                output << "];\n";
+                for( int i = last_var + 1; i < block_size; i++)
+                  tmp_s << " 0";
+                output << "M_.block_structure.block(" << block+1 << ").lead_lag_incidence = [ M_.block_structure.block(" << block+1 << ").lead_lag_incidence; " << tmp_s.str() << "]; %lag = " << lag << "\n";
+                tmp_s.str("");
               }
-
           }
-        for (int j=-block_triangular.incidencematrix.Model_Max_Lag_Endo;j<=block_triangular.incidencematrix.Model_Max_Lead_Endo;j++)
-          {
-            bool* IM = block_triangular.incidencematrix.Get_IM(j, eEndogenous);
-            if (IM)
+        string cst_s;
+        int nb_endo = symbol_table.endo_nbr();
+        output << "M_.block_structure.variable_reordered = [";
+        for(int i=0; i<nb_endo; i++)
+          output << " " << variable_reordered[i]+1;
+        output << "];\n";
+        output << "M_.block_structure.equation_reordered = [";
+        for(int i=0; i<nb_endo; i++)
+          output << " " << equation_reordered[i]+1;
+        output << "];\n";
+        map<pair< int, pair<int, int> >,  int>  lag_row_incidence;
+        for (first_derivatives_type::const_iterator it = first_derivatives.begin();
+                 it != first_derivatives.end(); it++)
               {
-                bool new_entry=true;
-                output << "M_.block_structure.incidence(" << block_triangular.incidencematrix.Model_Max_Lag_Endo+j+1 << ").lead_lag = " << j << ";\n";
-                output << "M_.block_structure.incidence(" << block_triangular.incidencematrix.Model_Max_Lag_Endo+j+1 << ").sparse_IM = [";
-                for (int i=0;i<symbol_table.endo_nbr()*symbol_table.endo_nbr();i++)
+                int deriv_id = it->first.second;
+                if (getTypeByDerivID(deriv_id) == eEndogenous)
                   {
-                    if (IM[i])
-                      {
-                        if (!new_entry)
-                          output << " ; ";
-                        else
-                          output << " ";
-                        output << i/symbol_table.endo_nbr()+1 << " " << i % symbol_table.endo_nbr()+1;
-                        new_entry=false;
-                      }
+                    int eq = it->first.first;
+                    int symb = getSymbIDByDerivID(deriv_id);
+                    int var = symbol_table.getTypeSpecificID(symb);
+                    int lag = getLagByDerivID(deriv_id);
+                    int eqr = inv_equation_reordered[eq];
+                    int varr = inv_variable_reordered[var];
+                    lag_row_incidence[make_pair(lag, make_pair(eqr, varr))] = 1;
                   }
-                output << "];\n";
               }
-          }
+         int prev_lag=-1000000;
+         for(map<pair< int, pair<int, int> >,  int> ::const_iterator it=lag_row_incidence.begin(); it != lag_row_incidence.end(); it++)
+           {
+             if(prev_lag != it->first.first)
+               {
+                 if(prev_lag != -1000000)
+                   output << "];\n";
+                 prev_lag = it->first.first;
+                 output << "M_.block_structure.incidence(" << max_endo_lag+it->first.first+1 << ").lead_lag = " << prev_lag << ";\n";
+                 output << "M_.block_structure.incidence(" << max_endo_lag+it->first.first+1 << ").sparse_IM = [";
+               }
+              output << it->first.second.first << " " << it->first.second.second << ";\n";
+           }
+        output << "];\n";
       }
     // Writing initialization for some other variables
     output << "M_.exo_names_orig_ord = [1:" << symbol_table.exo_nbr() << "];" << endl
@@ -2234,139 +1923,6 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block, b
            << "M_.NNZDerivatives(3) = " << NNZDerivatives[2] << ";" << endl;
   }
 
-void
-DynamicModel::evaluateJacobian(const eval_context_type &eval_context, jacob_map *j_m, bool dynamic)
-{
-  int i=0;
-  int j=0;
-  bool *IM=NULL;
-  int a_variable_lag=-9999;
-  for (first_derivatives_type::iterator it = first_derivatives.begin();
-       it != first_derivatives.end(); it++)
-    {
-      //cout << "it->first.second=" << it->first.second << " variable_table.getSymbolID(it->first.second)=" << variable_table.getSymbolID(it->first.second) << " Type=" << variable_table.getType(it->first.second) << " eEndogenous=" << eEndogenous << " eExogenous=" << eExogenous << " variable_table.getLag(it->first.second)=" << variable_table.getLag(it->first.second) << "\n";
-      if (getTypeByDerivID(it->first.second) == eEndogenous)
-        {
-          NodeID Id = it->second;
-          double val = 0;
-          try
-            {
-              val = Id->eval(eval_context);
-            }
-          catch (ExprNode::EvalException &e)
-            {
-              cout << "evaluation of Jacobian failed for equation " << it->first.first+1 << " and variable " << symbol_table.getName(getSymbIDByDerivID(it->first.second)) << "(" << getLagByDerivID(it->first.second) << ") [" << getSymbIDByDerivID(it->first.second) << "] !" << endl;
-              Id->writeOutput(cout, oMatlabDynamicModelSparse, temporary_terms);
-              cout << "\n";
-              cerr << "DynamicModel::evaluateJacobian: evaluation of Jacobian failed for equation " << it->first.first+1 << " and variable " << symbol_table.getName(getSymbIDByDerivID(it->first.second)) << "(" << getLagByDerivID(it->first.second) << ")!" << endl;
-            }
-          int eq=it->first.first;
-          int var = symbol_table.getTypeSpecificID(getSymbIDByDerivID(it->first.second));///symbol_table.getID(eEndogenous,it->first.second);//variable_table.getSymbolID(it->first.second);
-          int k1 = getLagByDerivID(it->first.second);
-          if (a_variable_lag!=k1)
-            {
-              IM=block_triangular.incidencematrix.Get_IM(k1, eEndogenous);
-              a_variable_lag=k1;
-            }
-          if (k1==0 or !dynamic)
-            {
-              j++;
-              (*j_m)[make_pair(eq,var)]+=val;
-            }
-          if (IM[eq*symbol_table.endo_nbr()+var] && (fabs(val) < cutoff))
-            {
-              if (block_triangular.bt_verbose)
-                cout << "the coefficient related to variable " << var << " with lag " << k1 << " in equation " << eq << " is equal to " << val << " and is set to 0 in the incidence matrix (size=" << symbol_table.endo_nbr() << ")\n";
-              block_triangular.incidencematrix.unfill_IM(eq, var, k1, eEndogenous);
-              i++;
-            }
-        }
-    }
-  //Get ride of the elements of the incidence matrix equal to Zero
-  IM=block_triangular.incidencematrix.Get_IM(0, eEndogenous);
-  for (int i=0;i<symbol_table.endo_nbr();i++)
-    for (int j=0;j<symbol_table.endo_nbr();j++)
-      if (IM[i*symbol_table.endo_nbr()+j])
-        if (first_derivatives.find(make_pair(i,getDerivID(symbol_table.getID(eEndogenous, j), 0)))==first_derivatives.end())
-          block_triangular.incidencematrix.unfill_IM(i, j, 0, eEndogenous);
-  if (i>0)
-    {
-      cout << i << " elements among " << first_derivatives.size() << " in the incidence matrices are below the cutoff (" << cutoff << ") and are discarded\n";
-      cout << "the contemporaneous incidence matrix has " << j << " elements\n";
-    }
-}
-
-void
-DynamicModel::BlockLinear(Model_Block *ModelBlock)
-{
-  int i,j,l,m,ll;
-  for (j = 0;j < ModelBlock->Size;j++)
-    {
-      if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_BACKWARD_COMPLETE ||
-          ModelBlock->Block_List[j].Simulation_Type==SOLVE_FORWARD_COMPLETE)
-        {
-          ll=ModelBlock->Block_List[j].Max_Lag;
-          for (i=0;i<ModelBlock->Block_List[j].IM_lead_lag[ll].size;i++)
-            {
-              int eq=ModelBlock->Block_List[j].IM_lead_lag[ll].Equ_Index[i];
-              int var=ModelBlock->Block_List[j].IM_lead_lag[ll].Var_Index[i];
-              //first_derivatives_type::const_iterator it=first_derivatives.find(make_pair(eq,variable_table.getID(var,0)));
-              first_derivatives_type::const_iterator it=first_derivatives.find(make_pair(eq,getDerivID(symbol_table.getID(eEndogenous, var),0)));
-              if (it!= first_derivatives.end())
-                {
-                  NodeID Id = it->second;
-                  set<pair<int, int> > endogenous;
-                  Id->collectEndogenous(endogenous);
-                  if (endogenous.size() > 0)
-                    {
-                      for (l=0;l<ModelBlock->Block_List[j].Size;l++)
-                        {
-                          if (endogenous.find(make_pair(ModelBlock->Block_List[j].Variable[l], 0)) != endogenous.end())
-                            {
-                              ModelBlock->Block_List[j].is_linear=false;
-                              goto follow;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-      else if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_COMPLETE || ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_SIMPLE)
-        {
-          for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++)
-            {
-              int k1=m-ModelBlock->Block_List[j].Max_Lag;
-              for (i=0;i<ModelBlock->Block_List[j].IM_lead_lag[m].size;i++)
-                {
-                  int eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_Index[i];
-                  int var=ModelBlock->Block_List[j].IM_lead_lag[m].Var_Index[i];
-                  //first_derivatives_type::const_iterator it=first_derivatives.find(make_pair(eq,variable_table.getID(var,k1)));
-                  first_derivatives_type::const_iterator it=first_derivatives.find(make_pair(eq,getDerivID(symbol_table.getID(eEndogenous, var),k1)));
-                  NodeID Id = it->second;
-                  if (it!= first_derivatives.end())
-                    {
-                      set<pair<int, int> > endogenous;
-                      Id->collectEndogenous(endogenous);
-                      if (endogenous.size() > 0)
-                        {
-                          for (l=0;l<ModelBlock->Block_List[j].Size;l++)
-                            {
-                              if (endogenous.find(make_pair(ModelBlock->Block_List[j].Variable[l], k1)) != endogenous.end())
-                                {
-                                  ModelBlock->Block_List[j].is_linear=false;
-                                  goto follow;
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-follow:
-      i=0;
-    }
-}
-
 
 map<pair<int, pair<int, int > >, NodeID>
 DynamicModel::collect_first_order_derivatives_endogenous()
@@ -2380,7 +1936,6 @@ DynamicModel::collect_first_order_derivatives_endogenous()
           int eq = it2->first.first;
           int var=symbol_table.getTypeSpecificID(getSymbIDByDerivID(it2->first.second));
           int lag=getLagByDerivID(it2->first.second);
-          //if (lag==0)
           endo_derivatives[make_pair(eq, make_pair(var, lag))] = it2->second;
         }
     }
@@ -2439,28 +1994,39 @@ DynamicModel::computingPass(bool jacobianExo, bool hessian, bool thirdDerivative
 
   if (block)
     {
-      BuildIncidenceMatrix();
+      jacob_map contemporaneous_jacobian, static_jacobian;
 
-      jacob_map j_m;
-      evaluateJacobian(eval_context, &j_m, true);
+      // for each block contains pair<Size, Feddback_variable>
+      vector<pair<int, int> > blocks;
 
+      evaluateAndReduceJacobian(eval_context, contemporaneous_jacobian, static_jacobian, dynamic_jacobian, cutoff, false);
+
+      computePossiblySingularNormalization(contemporaneous_jacobian, cutoff == 0);
+
+      computePrologueAndEpilogue(static_jacobian, equation_reordered, variable_reordered, prologue, epilogue);
 
-      if (block_triangular.bt_verbose)
-        {
-          cout << "The gross incidence matrix \n";
-          block_triangular.incidencematrix.Print_IM(eEndogenous);
-        }
-      t_etype equation_simulation_type;
       map<pair<int, pair<int, int> >, NodeID> first_order_endo_derivatives = collect_first_order_derivatives_endogenous();
 
-      block_triangular.Normalize_and_BlockDecompose_Static_0_Model(j_m, equations, equation_simulation_type, first_order_endo_derivatives, mfs, cutoff);
+      equation_type_and_normalized_equation = equationTypeDetermination(equations, first_order_endo_derivatives, variable_reordered, equation_reordered, mfs);
+
+      cout << "Finding the optimal block decomposition of the model ...\n";
+
+      if (prologue+epilogue < (unsigned int) equation_number())
+        computeBlockDecompositionAndFeedbackVariablesForEachBlock(static_jacobian, dynamic_jacobian, prologue, epilogue, equation_reordered, variable_reordered, blocks, equation_type_and_normalized_equation, false, true, mfs, inv_equation_reordered, inv_variable_reordered);
+
+      block_type_firstequation_size_mfs = reduceBlocksAndTypeDetermination(dynamic_jacobian, prologue, epilogue, blocks, equations, equation_type_and_normalized_equation, variable_reordered, equation_reordered);
+
+      printBlockDecomposition(blocks);
+
+      computeChainRuleJacobian(blocks_derivatives);
 
-      BlockLinear(block_triangular.ModelBlock);
+      blocks_linear = BlockLinear(blocks_derivatives, variable_reordered);
 
-      computeChainRuleJacobian(block_triangular.ModelBlock);
+      collect_block_first_order_derivatives();
 
+      global_temporary_terms = true;
       if (!no_tmp_terms)
-        computeTemporaryTermsOrdered(block_triangular.ModelBlock);
+        computeTemporaryTermsOrdered();
 
     }
   else
@@ -2468,17 +2034,253 @@ DynamicModel::computingPass(bool jacobianExo, bool hessian, bool thirdDerivative
       computeTemporaryTerms(!use_dll);
 }
 
+map<pair<pair<int, pair<int, int> >, pair<int, int> >, int>
+DynamicModel::get_Derivatives(int block)
+{
+  map<pair<pair<int, pair<int, int> >, pair<int, int> >, int> Derivatives;
+  Derivatives.clear();
+  int max_lag  = getBlockMaxLag(block);
+  int max_lead = getBlockMaxLead(block);
+  int block_size = getBlockSize(block);
+  int block_nb_recursive = block_size - getBlockMfs(block);
+  for(int lag = -max_lag; lag <= max_lead; lag++)
+    {
+      for(int eq = 0; eq < block_size; eq++)
+        {
+          int eqr = getBlockEquationID(block, eq);
+          for(int var = 0; var < block_size; var++)
+            {
+              int varr = getBlockVariableID(block, var);
+              if(dynamic_jacobian.find(make_pair(lag, make_pair(eqr, varr))) != dynamic_jacobian.end())
+                {
+                  bool OK = true;
+                  map<pair<pair<int, pair<int, int> >, pair<int, int> >, int>::const_iterator its = Derivatives.find(make_pair(make_pair(lag, make_pair(eq, var)), make_pair(eqr, varr)));
+                  if(its!=Derivatives.end())
+                    {
+                    	if(its->second == 2)
+                    	  OK=false;
+                    }
+
+                  if(OK)
+                    {
+                      if (getBlockEquationType(block, eq) == E_EVALUATE_S and eq<block_nb_recursive)
+                        //It's a normalized equation, we have to recompute the derivative using chain rule derivative function
+                        Derivatives[make_pair(make_pair(lag, make_pair(eq, var)), make_pair(eqr, varr))] = 1;
+                      else
+                        //It's a feedback equation we can use the derivatives
+                        Derivatives[make_pair(make_pair(lag, make_pair(eq, var)), make_pair(eqr, varr))] = 0;
+                    }
+                  if(var<block_nb_recursive)
+                    {
+                      int eqs = getBlockEquationID(block, var);
+                      for(int vars=block_nb_recursive; vars<block_size; vars++)
+                        {
+                          int varrs = getBlockVariableID(block, vars);
+                          //A new derivative needs to be computed using the chain rule derivative function (a feedback variable appears in a recursive equation)
+                          if(Derivatives.find(make_pair(make_pair(lag, make_pair(var, vars)), make_pair(eqs, varrs)))!=Derivatives.end())
+                            Derivatives[make_pair(make_pair(lag, make_pair(eq, vars)), make_pair(eqr, varrs))] = 2;
+                        }
+                    }
+                }
+            }
+        }
+    }
+  return(Derivatives);
+}
+
+void
+DynamicModel::computeChainRuleJacobian(t_blocks_derivatives &blocks_derivatives)
+{
+  map<int, NodeID> recursive_variables;
+  unsigned int nb_blocks = getNbBlocks();
+  blocks_derivatives = t_blocks_derivatives(nb_blocks);
+  for(unsigned int block = 0; block < nb_blocks; block++)
+    {
+      t_block_derivatives_equation_variable_laglead_nodeid tmp_derivatives;
+      recursive_variables.clear();
+      BlockSimulationType simulation_type = getBlockSimulationType(block);
+      int block_size = getBlockSize(block);
+      int block_nb_mfs = getBlockMfs(block);
+      int block_nb_recursives = block_size - block_nb_mfs;
+      if (simulation_type==SOLVE_TWO_BOUNDARIES_COMPLETE or simulation_type==SOLVE_TWO_BOUNDARIES_SIMPLE)
+        {
+          blocks_derivatives.push_back(t_block_derivatives_equation_variable_laglead_nodeid(0));
+          for(int i = 0; i < block_nb_recursives; i++)
+            {
+              if (getBlockEquationType(block, i) == E_EVALUATE_S)
+                recursive_variables[getDerivID(symbol_table.getID(eEndogenous, getBlockVariableID(block, i)), 0)] = getBlockEquationRenormalizedNodeID(block, i);
+              else
+                recursive_variables[getDerivID(symbol_table.getID(eEndogenous, getBlockVariableID(block, i)), 0)] = getBlockEquationNodeID(block, i);
+            }
+          map<pair<pair<int, pair<int, int> >, pair<int, int> >, int> Derivatives = get_Derivatives(block);
+          map<pair<pair<int, pair<int, int> >, pair<int, int> >, int>::const_iterator it = Derivatives.begin();
+          for(int i=0; i<(int)Derivatives.size(); i++)
+            {
+              int Deriv_type = it->second;
+              pair<pair<int, pair<int, int> >, pair<int, int> > it_l(it->first);
+              it++;
+              int lag = it_l.first.first;
+              int eq = it_l.first.second.first;
+              int var = it_l.first.second.second;
+              int eqr = it_l.second.first;
+              int varr = it_l.second.second;
+              if(Deriv_type == 0)
+                first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = first_derivatives[make_pair(eqr, getDerivID(symbol_table.getID(eEndogenous, varr), lag))];
+              else if (Deriv_type == 1)
+                first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = (equation_type_and_normalized_equation[eqr].second)->getChainRuleDerivative(getDerivID(symbol_table.getID(eEndogenous, varr), lag), recursive_variables);
+              else if (Deriv_type == 2)
+                {
+                  if(getBlockEquationType(block, eq) == E_EVALUATE_S && eq<block_nb_recursives)
+                    first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = (equation_type_and_normalized_equation[eqr].second)->getChainRuleDerivative(getDerivID(symbol_table.getID(eEndogenous, varr), lag), recursive_variables);
+                  else
+                    first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = equations[eqr]->getChainRuleDerivative(getDerivID(symbol_table.getID(eEndogenous, varr), lag), recursive_variables);
+                }
+              tmp_derivatives.push_back(make_pair(make_pair(eq, var), make_pair(lag, first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))]) ));
+            }
+        }
+      else if(   simulation_type==SOLVE_BACKWARD_SIMPLE or simulation_type==SOLVE_FORWARD_SIMPLE
+              or simulation_type==SOLVE_BACKWARD_COMPLETE or simulation_type==SOLVE_FORWARD_COMPLETE)
+        {
+          blocks_derivatives.push_back(t_block_derivatives_equation_variable_laglead_nodeid(0));
+          for(int i = 0; i < block_nb_recursives; i++)
+            {
+              if (getBlockEquationType(block, i) == E_EVALUATE_S)
+                recursive_variables[getDerivID(symbol_table.getID(eEndogenous, getBlockVariableID(block,i)), 0)] = getBlockEquationRenormalizedNodeID(block, i);
+              else
+                recursive_variables[getDerivID(symbol_table.getID(eEndogenous, getBlockVariableID(block,i)), 0)] = getBlockEquationNodeID(block, i);
+            }
+          for(int eq = block_nb_recursives; eq < block_size; eq++)
+            {
+              int eqr = getBlockEquationID(block, eq);
+              for(int var = block_nb_recursives; var < block_size; var++)
+                {
+                  int varr = getBlockVariableID(block, var);
+                  NodeID d1 = equations[eqr]->getChainRuleDerivative(getDerivID(symbol_table.getID(eEndogenous, varr), 0), recursive_variables);
+                  if (d1 == Zero)
+                    continue;
+                  first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, 0))] = d1;
+                  tmp_derivatives.push_back(
+                 make_pair(make_pair(eq, var),make_pair(0, first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, 0))])));
+                }
+            }
+        }
+      blocks_derivatives[block] = tmp_derivatives;
+    }
+}
+
+void
+DynamicModel::collect_block_first_order_derivatives()
+{
+  //! vector for an equation or a variable indicates the block number
+  vector<int> equation_2_block, variable_2_block;
+  unsigned int nb_blocks = getNbBlocks();
+  equation_2_block = vector<int>(equation_reordered.size());
+  variable_2_block = vector<int>(variable_reordered.size());
+  for(unsigned int block = 0; block < nb_blocks; block++)
+    {
+      unsigned int block_size = getBlockSize(block);
+      for(unsigned int i = 0; i < block_size; i++)
+        {
+          equation_2_block[getBlockEquationID(block, i)] = block;
+          variable_2_block[getBlockVariableID(block, i)] = block;
+        }
+    }
+  other_endo_block = vector<t_lag_var>(nb_blocks);
+  exo_block = vector<t_lag_var>(nb_blocks);
+  exo_det_block = vector<t_lag_var>(nb_blocks);
+  derivative_endo = vector<t_derivative>(nb_blocks);
+  derivative_other_endo = vector<t_derivative>(nb_blocks);
+  derivative_exo = vector<t_derivative>(nb_blocks);
+  derivative_exo_det = vector<t_derivative>(nb_blocks);
+  endo_max_leadlag_block = vector<pair<int, int> >(nb_blocks, make_pair( 0, 0));
+  other_endo_max_leadlag_block = vector<pair<int, int> >(nb_blocks, make_pair( 0, 0));
+  exo_max_leadlag_block = vector<pair<int, int> >(nb_blocks, make_pair( 0, 0));
+  exo_det_max_leadlag_block = vector<pair<int, int> >(nb_blocks, make_pair( 0, 0));
+  max_leadlag_block = vector<pair<int, int> >(nb_blocks, make_pair( 0, 0));
+  for (first_derivatives_type::iterator it2 = first_derivatives.begin();
+       it2 != first_derivatives.end(); it2++)
+    {
+      int eq = it2->first.first;
+      int var = symbol_table.getTypeSpecificID(getSymbIDByDerivID(it2->first.second));
+      int lag = getLagByDerivID(it2->first.second);
+      int block_eq = equation_2_block[eq];
+      int block_var = variable_2_block[var];
+      t_derivative tmp_derivative ;
+      t_lag_var lag_var;
+      switch(getTypeByDerivID(it2->first.second))
+        {
+          case eEndogenous:
+            if(block_eq == block_var)
+              {
+                if(lag<0 && lag<-endo_max_leadlag_block[block_eq].first)
+                  endo_max_leadlag_block[block_eq] = make_pair(-lag, endo_max_leadlag_block[block_eq].second);
+                if(lag>0 && lag>endo_max_leadlag_block[block_eq].second)
+                  endo_max_leadlag_block[block_eq] = make_pair(endo_max_leadlag_block[block_eq].first, lag);
+                tmp_derivative = derivative_endo[block_eq];
+                tmp_derivative[make_pair(lag, make_pair(eq, var))] = first_derivatives[make_pair(eq, getDerivID(symbol_table.getID(eEndogenous, var), lag))];
+                derivative_endo[block_eq] = tmp_derivative;
+              }
+            else
+              {
+                if(lag<0 && lag<-other_endo_max_leadlag_block[block_eq].first)
+                  other_endo_max_leadlag_block[block_eq] = make_pair(-lag, other_endo_max_leadlag_block[block_eq].second);
+                if(lag>0 && lag>other_endo_max_leadlag_block[block_eq].second)
+                  other_endo_max_leadlag_block[block_eq] = make_pair(other_endo_max_leadlag_block[block_eq].first, lag);
+                tmp_derivative = derivative_other_endo[block_eq];
+                tmp_derivative[make_pair(lag, make_pair(eq, var))] = first_derivatives[make_pair(eq, getDerivID(symbol_table.getID(eEndogenous, var), lag))];
+                derivative_other_endo[block_eq] = tmp_derivative;
+                lag_var = other_endo_block[block_eq];
+                if(lag_var.find(lag) == lag_var.end())
+                  lag_var[lag].clear();
+                lag_var[lag].insert(var);
+                other_endo_block[block_eq] = lag_var;
+              }
+            break;
+          case eExogenous:
+            if(lag<0 && lag<-exo_max_leadlag_block[block_eq].first)
+              exo_max_leadlag_block[block_eq] = make_pair(-lag, exo_max_leadlag_block[block_eq].second);
+            if(lag>0 && lag>exo_max_leadlag_block[block_eq].second)
+              exo_max_leadlag_block[block_eq] = make_pair(exo_max_leadlag_block[block_eq].first, lag);
+            tmp_derivative = derivative_exo[block_eq];
+            tmp_derivative[make_pair(lag, make_pair(eq, var))] = first_derivatives[make_pair(eq, getDerivID(symbol_table.getID(eExogenous, var), lag))];
+            derivative_exo[block_eq] = tmp_derivative ;
+            lag_var = exo_block[block_eq];
+            if(lag_var.find(lag) == lag_var.end())
+              lag_var[lag].clear();
+            lag_var[lag].insert(var);
+            exo_block[block_eq] = lag_var;
+            break;
+          case eExogenousDet:
+            if(lag<0 && lag<-exo_det_max_leadlag_block[block_eq].first)
+              exo_det_max_leadlag_block[block_eq] = make_pair(-lag, exo_det_max_leadlag_block[block_eq].second);
+            if(lag>0 && lag>exo_det_max_leadlag_block[block_eq].second)
+              exo_det_max_leadlag_block[block_eq] = make_pair(exo_det_max_leadlag_block[block_eq].first, lag);
+            tmp_derivative = derivative_exo_det[block_eq];
+            tmp_derivative[make_pair(lag, make_pair(eq, var))] = first_derivatives[make_pair(eq, getDerivID(symbol_table.getID(eExogenous, var), lag))];
+            derivative_exo_det[block_eq] = tmp_derivative ;
+            lag_var = exo_det_block[block_eq];
+            if(lag_var.find(lag) == lag_var.end())
+              lag_var[lag].clear();
+            lag_var[lag].insert(var);
+            exo_det_block[block_eq] = lag_var;
+            break;
+          default:
+            break;
+        }
+      if (lag<0 && lag<-max_leadlag_block[block_eq].first)
+        max_leadlag_block[block_eq] = make_pair(-lag, max_leadlag_block[block_eq].second);
+      if (lag>0 && lag>max_leadlag_block[block_eq].second)
+        max_leadlag_block[block_eq] = make_pair(max_leadlag_block[block_eq].first, lag);
+    }
+
+}
+
 void
 DynamicModel::writeDynamicFile(const string &basename, bool block, bool bytecode, bool use_dll) const
   {
     int r;
     if(block && bytecode)
-      {
-        writeModelEquationsCodeOrdered(basename + "_dynamic", block_triangular.ModelBlock, basename, map_idx);
-        block_triangular.Free_Block(block_triangular.ModelBlock);
-        block_triangular.incidencematrix.Free_IM();
-        //block_triangular.Free_IM_X(block_triangular.First_IM_X);
-      }
+      writeModelEquationsCodeOrdered(basename + "_dynamic", basename, map_idx);
 		else if(block && !bytecode)
 		  {
 #ifdef _WIN32
@@ -2492,9 +2294,6 @@ DynamicModel::writeDynamicFile(const string &basename, bool block, bool bytecode
             exit(EXIT_FAILURE);
           }
         writeSparseDynamicMFile(basename + "_dynamic", basename);
-        block_triangular.Free_Block(block_triangular.ModelBlock);
-        block_triangular.incidencematrix.Free_IM();
-        //block_triangular.Free_IM_X(block_triangular.First_IM_X);
 		  }
 		else if (use_dll)
      	writeDynamicCFile(basename + "_dynamic");
@@ -2521,20 +2320,6 @@ DynamicModel::toStatic(StaticModel &static_model) const
       static_model.addAuxEquation((*it)->toStatic(static_model));
   }
 
-void
-DynamicModel::toStaticDll(StaticDllModel &static_model) const
-  {
-    // Convert model local variables (need to be done first)
-    for (map<int, NodeID>::const_iterator it = local_variables_table.begin();
-         it != local_variables_table.end(); it++)
-      static_model.AddLocalVariable(symbol_table.getName(it->first), it->second->toStatic(static_model));
-
-    // Convert equations
-    for (vector<BinaryOpNode *>::const_iterator it = equations.begin();
-         it != equations.end(); it++)
-      static_model.addEquation((*it)->toStatic(static_model));
-  }
-
 void
 DynamicModel::computeDerivIDs()
 {
@@ -2693,86 +2478,6 @@ DynamicModel::getDynJacobianCol(int deriv_id) const throw (UnknownDerivIDExcepti
 }
 
 
-void
-DynamicModel::computeChainRuleJacobian(Model_Block *ModelBlock)
-{
-  map<int, NodeID> recursive_variables;
-  first_chain_rule_derivatives.clear();
-  for(int blck = 0; blck<ModelBlock->Size; blck++)
-    {
-      recursive_variables.clear();
-      if (ModelBlock->Block_List[blck].Simulation_Type==SOLVE_TWO_BOUNDARIES_COMPLETE or ModelBlock->Block_List[blck].Simulation_Type==SOLVE_TWO_BOUNDARIES_SIMPLE)
-        {
-          ModelBlock->Block_List[blck].Chain_Rule_Derivatives->clear();
-          for(int i = 0; i < ModelBlock->Block_List[blck].Nb_Recursives; i++)
-            {
-              if (ModelBlock->Block_List[blck].Equation_Type[i] == E_EVALUATE_S)
-                recursive_variables[getDerivID(symbol_table.getID(eEndogenous, ModelBlock->Block_List[blck].Variable[i]), 0)] = ModelBlock->Block_List[blck].Equation_Normalized[i];
-              else
-                recursive_variables[getDerivID(symbol_table.getID(eEndogenous, ModelBlock->Block_List[blck].Variable[i]), 0)] = equations[ModelBlock->Block_List[blck].Equation[i]];
-            }
-          map<pair<pair<int, pair<int, int> >, pair<int, int> >, int> Derivatives = block_triangular.get_Derivatives(ModelBlock, blck);
-
-          map<pair<pair<int, pair<int, int> >, pair<int, int> >, int>::const_iterator it = Derivatives.begin();
-          //#pragma omp parallel for shared(it, blck)
-          for(int i=0; i<(int)Derivatives.size(); i++)
-            {
-              int Deriv_type = it->second;
-              pair<pair<int, pair<int, int> >, pair<int, int> > it_l(it->first);
-              it++;
-              int lag = it_l.first.first;
-              int eq = it_l.first.second.first;
-              int var = it_l.first.second.second;
-              int eqr = it_l.second.first;
-              int varr = it_l.second.second;
-              if(Deriv_type == 0)
-                {
-                  first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = first_derivatives[make_pair(eqr, getDerivID(symbol_table.getID(eEndogenous, varr), lag))];
-                }
-              else if (Deriv_type == 1)
-                {
-                  first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = ModelBlock->Block_List[blck].Equation_Normalized[eq]->getChainRuleDerivative(getDerivID(symbol_table.getID(eEndogenous, varr), lag), recursive_variables);
-                }
-              else if (Deriv_type == 2)
-                {
-                  if(ModelBlock->Block_List[blck].Equation_Type[eq] == E_EVALUATE_S && eq<ModelBlock->Block_List[blck].Nb_Recursives)
-                    first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = ModelBlock->Block_List[blck].Equation_Normalized[eq]->getChainRuleDerivative(getDerivID(symbol_table.getID(eEndogenous, varr), lag), recursive_variables);
-                  else
-                    first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = equations[eqr]->getChainRuleDerivative(getDerivID(symbol_table.getID(eEndogenous, varr), lag), recursive_variables);
-                }
-              ModelBlock->Block_List[blck].Chain_Rule_Derivatives->push_back(make_pair( make_pair(lag, make_pair(eq, var)), make_pair(eqr, varr)));
-            }
-        }
-      else if(   ModelBlock->Block_List[blck].Simulation_Type==SOLVE_BACKWARD_SIMPLE or ModelBlock->Block_List[blck].Simulation_Type==SOLVE_FORWARD_SIMPLE
-              or ModelBlock->Block_List[blck].Simulation_Type==SOLVE_BACKWARD_COMPLETE or ModelBlock->Block_List[blck].Simulation_Type==SOLVE_FORWARD_COMPLETE)
-        {
-          ModelBlock->Block_List[blck].Chain_Rule_Derivatives->clear();
-          for(int i = 0; i < ModelBlock->Block_List[blck].Nb_Recursives; i++)
-            {
-              if (ModelBlock->Block_List[blck].Equation_Type[i] == E_EVALUATE_S)
-                recursive_variables[getDerivID(symbol_table.getID(eEndogenous, ModelBlock->Block_List[blck].Variable[i]), 0)] = ModelBlock->Block_List[blck].Equation_Normalized[i];
-              else
-                recursive_variables[getDerivID(symbol_table.getID(eEndogenous, ModelBlock->Block_List[blck].Variable[i]), 0)] = equations[ModelBlock->Block_List[blck].Equation[i]];
-            }
-          for(int eq = ModelBlock->Block_List[blck].Nb_Recursives; eq < ModelBlock->Block_List[blck].Size; eq++)
-            {
-              int eqr = ModelBlock->Block_List[blck].Equation[eq];
-              for(int var = ModelBlock->Block_List[blck].Nb_Recursives; var < ModelBlock->Block_List[blck].Size; var++)
-                {
-                  int varr = ModelBlock->Block_List[blck].Variable[var];
-                  NodeID d1 = equations[eqr]->getChainRuleDerivative(getDerivID(symbol_table.getID(eEndogenous, varr), 0), recursive_variables);
-                  if (d1 == Zero)
-                    continue;
-                  first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, 0))] = d1;
-                  ModelBlock->Block_List[blck].Chain_Rule_Derivatives->push_back(make_pair( make_pair(0, make_pair(eq, var)), make_pair(eqr, varr)));
-                }
-            }
-        }
-    }
-}
-
-
-
 void
 DynamicModel::computeParamsDerivatives()
 {
diff --git a/DynamicModel.hh b/DynamicModel.hh
index 8edd7153a50640c4b8eb12f5c9d445dd27448e66..be88b45ce477e426dde4c9d287d98f93d7d203eb 100644
--- a/DynamicModel.hh
+++ b/DynamicModel.hh
@@ -25,8 +25,6 @@ using namespace std;
 #include <fstream>
 
 #include "StaticModel.hh"
-#include "StaticDllModel.hh"
-#include "BlockTriangular.hh"
 
 //! Stores a dynamic model
 class DynamicModel : public ModelTree
@@ -76,10 +74,15 @@ private:
   //! Temporary terms for the file containing parameters dervicatives
   temporary_terms_type params_derivs_temporary_terms;
 
+  //! Temporary terms for block decomposed models
+  vector< vector<temporary_terms_type> > v_temporary_terms;
+
+  vector<temporary_terms_inuse_type> v_temporary_terms_inuse;
+
+  //! Store the derivatives or the chainrule derivatives:map<pair< equation, pair< variable, lead_lag >, NodeID>
   typedef map< pair< int, pair< int, int> >, NodeID> first_chain_rule_derivatives_type;
   first_chain_rule_derivatives_type first_chain_rule_derivatives;
 
-
   //! Writes dynamic model file (Matlab version)
   void writeDynamicMFile(const string &dynamic_basename) const;
   //! Writes dynamic model file (C version)
@@ -91,37 +94,38 @@ private:
   /*! \todo add third derivatives handling in C output */
   void writeDynamicModel(ostream &DynamicOutput, bool use_dll) const;
   //! Writes the Block reordred structure of the model in M output
-  void writeModelEquationsOrdered_M(Model_Block *ModelBlock, const string &dynamic_basename) const;
+  void writeModelEquationsOrdered_M(const string &dynamic_basename) const;
   //! Writes the code of the Block reordred structure of the model in virtual machine bytecode
-  void writeModelEquationsCodeOrdered(const string file_name, const Model_Block *ModelBlock, const string bin_basename, map_idx_type map_idx) const;
+  void writeModelEquationsCodeOrdered(const string file_name, const string bin_basename, map_idx_type map_idx) const;
   //! Computes jacobian and prepares for equation normalization
   /*! Using values from initval/endval blocks and parameter initializations:
     - computes the jacobian for the model w.r. to contemporaneous variables
     - removes edges of the incidence matrix when derivative w.r. to the corresponding variable is too close to zero (below the cutoff)
   */
-  void evaluateJacobian(const eval_context_type &eval_context, jacob_map *j_m, bool dynamic);
-  void BlockLinear(Model_Block *ModelBlock);
+  //void evaluateJacobian(const eval_context_type &eval_context, jacob_map *j_m, bool dynamic);
+
+  //! return a map on the block jacobian
+  map<pair<pair<int, pair<int, int> >, pair<int, int> >, int> get_Derivatives(int block);
+  //! Computes chain rule derivatives of the Jacobian w.r. to endogenous variables
+  void computeChainRuleJacobian(t_blocks_derivatives &blocks_derivatives);
+
   string reform(string name) const;
   map_idx_type map_idx;
-  //! Build The incidence matrix form the modeltree
-  void BuildIncidenceMatrix();
 
-  void computeTemporaryTermsOrdered(Model_Block *ModelBlock);
+  void computeTemporaryTermsOrdered();
   //! Write derivative code of an equation w.r. to a variable
   void compileDerivative(ofstream &code_file, int eq, int symb_id, int lag, map_idx_type &map_idx) const;
   //! Write chain rule derivative code of an equation w.r. to a variable
   void compileChainRuleDerivative(ofstream &code_file, int eq, int var, int lag, map_idx_type &map_idx) const;
 
   //! Get the type corresponding to a derivation ID
-  SymbolType getTypeByDerivID(int deriv_id) const throw (UnknownDerivIDException);
+  virtual SymbolType getTypeByDerivID(int deriv_id) const throw (UnknownDerivIDException);
   //! Get the lag corresponding to a derivation ID
-  int getLagByDerivID(int deriv_id) const throw (UnknownDerivIDException);
+  virtual int getLagByDerivID(int deriv_id) const throw (UnknownDerivIDException);
   //! Get the symbol ID corresponding to a derivation ID
-  int getSymbIDByDerivID(int deriv_id) const throw (UnknownDerivIDException);
+  virtual int getSymbIDByDerivID(int deriv_id) const throw (UnknownDerivIDException);
   //! Compute the column indices of the dynamic Jacobian
   void computeDynJacobianCols(bool jacobianExo);
-  //! Computes chain rule derivatives of the Jacobian w.r. to endogenous variables
-  void computeChainRuleJacobian(Model_Block *ModelBlock);
   //! Computes derivatives of the Jacobian w.r. to parameters
   void computeParamsDerivatives();
   //! Computes temporary terms for the file containing parameters derivatives
@@ -145,10 +149,50 @@ private:
   //! Write chain rule derivative of a recursive equation w.r. to a variable
   void writeChainRuleDerivative(ostream &output, int eq, int var, int lag, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const;
 
+  //! Collecte the derivatives w.r. to endogenous of the block, to endogenous of previouys blocks and to exogenous
+  void collect_block_first_order_derivatives();
+
+
   //! Factorized code for substitutions of leads/lags
   /*! \param[in] type determines which type of variables is concerned */
   void substituteLeadLagInternal(aux_var_t type);
 
+
+private:
+  //! Indicate if the temporary terms are computed for the overall model (true) or not (false). Default value true
+  bool global_temporary_terms;
+
+  //! vector of block reordered variables and equations
+  vector<int> equation_reordered, variable_reordered, inv_equation_reordered, inv_variable_reordered;
+
+  //! Vector describing equations: BlockSimulationType, if BlockSimulationType == EVALUATE_s then a NodeID on the new normalized equation
+  t_equation_type_and_normalized_equation equation_type_and_normalized_equation;
+
+  //! for each block contains pair< Simulation_Type, pair < Block_Size, Recursive_part_Size > >
+  t_block_type_firstequation_size_mfs block_type_firstequation_size_mfs;
+
+  //! for all blocks derivatives description
+  t_blocks_derivatives blocks_derivatives;
+
+  //! The jacobian without the elements below the cutoff
+  dynamic_jacob_map dynamic_jacobian;
+
+  //! Vector indicating if the block is linear in endogenous variable (true) or not (false)
+  vector<bool> blocks_linear;
+
+  //! Map the derivatives for a block pair<lag, make_pair(make_pair(eq, var)), NodeID>
+  typedef map<pair< int, pair<int, int> >, NodeID> t_derivative;
+  //! Vector of derivative for each blocks
+  vector<t_derivative> derivative_endo, derivative_other_endo, derivative_exo, derivative_exo_det;
+
+  //!List for each block and for each lag-leag all the other endogenous variables and exogenous variables
+  typedef set<int> t_var;
+  typedef map<int, t_var> t_lag_var;
+  vector<t_lag_var> other_endo_block, exo_block, exo_det_block;
+
+  //!Maximum lead and lag for each block on endogenous of the block, endogenous of the previous blocks, exogenous and deterministic exogenous
+  vector<pair<int, int> > endo_max_leadlag_block, other_endo_max_leadlag_block, exo_max_leadlag_block, exo_det_max_leadlag_block, max_leadlag_block;
+
 public:
   DynamicModel(SymbolTable &symbol_table_arg, NumericalConstants &num_constants);
   //! Adds a variable node
@@ -179,8 +223,6 @@ public:
   //! Writes model initialization and lead/lag incidence matrix to output
   void writeOutput(ostream &output, const string &basename, bool block, bool byte_code, bool use_dll) const;
 
-  //! Complete set to block decompose the model
-  BlockTriangular block_triangular;
   //! Adds informations for simulation in a binary file
   void Write_Inf_To_Bin_File(const string &dynamic_basename, const string &bin_basename,
                              const int &num, int &u_count_int, bool &file_open, bool is_two_boundaries) const;
@@ -192,14 +234,12 @@ public:
   /*! It assumes that the static model given in argument has just been allocated */
   void toStatic(StaticModel &static_model) const;
 
-  void toStaticDll(StaticDllModel &static_model) const;
-
   //! Writes LaTeX file with the equations of the dynamic model
   void writeLatexFile(const string &basename) const;
 
   virtual int getDerivID(int symb_id, int lag) const throw (UnknownDerivIDException);
   virtual int getDynJacobianCol(int deriv_id) const throw (UnknownDerivIDException);
-	
+
   //! Returns true indicating that this is a dynamic model
   virtual bool isDynamic() const { return true; };
 
@@ -225,6 +265,40 @@ public:
 
   //! Fills eval context with values of model local variables and auxiliary variables
   void fillEvalContext(eval_context_type &eval_context) const;
+
+
+  //! Return the number of blocks
+  virtual unsigned int getNbBlocks() const {return(block_type_firstequation_size_mfs.size());};
+  //! Determine the simulation type of each block
+  virtual BlockSimulationType getBlockSimulationType(int block_number) const {return(block_type_firstequation_size_mfs[block_number].first.first);};
+  //! Return the first equation number of a block
+  virtual unsigned int getBlockFirstEquation(int block_number) const {return(block_type_firstequation_size_mfs[block_number].first.second);};
+  //! Return the size of the block block_number
+  virtual unsigned int getBlockSize(int block_number) const {return(block_type_firstequation_size_mfs[block_number].second.first);};
+  //! Return the number of feedback variable of the block block_number
+  virtual unsigned int getBlockMfs(int block_number) const {return(block_type_firstequation_size_mfs[block_number].second.second);};
+  //! Return the maximum lag in a block
+  virtual unsigned int getBlockMaxLag(int block_number) const {return(block_lag_lead[block_number].first);};
+  //! Return the maximum lead in a block
+  virtual unsigned int getBlockMaxLead(int block_number) const {return(block_lag_lead[block_number].second);};
+  //! Return the type of equation (equation_number) belonging to the block block_number
+  virtual EquationType getBlockEquationType(int block_number, int equation_number) const {return( equation_type_and_normalized_equation[equation_reordered[block_type_firstequation_size_mfs[block_number].first.second+equation_number]].first);};
+  //! Return true if the equation has been normalized
+  virtual bool isBlockEquationRenormalized(int block_number, int equation_number) const {return( equation_type_and_normalized_equation[equation_reordered[block_type_firstequation_size_mfs[block_number].first.second+equation_number]].first == E_EVALUATE_S);};
+  //! Return the NodeID of the equation equation_number belonging to the block block_number
+  virtual NodeID getBlockEquationNodeID(int block_number, int equation_number) const {return( equations[equation_reordered[block_type_firstequation_size_mfs[block_number].first.second+equation_number]]);};
+  //! Return the NodeID of the renormalized equation equation_number belonging to the block block_number
+  virtual NodeID getBlockEquationRenormalizedNodeID(int block_number, int equation_number) const {return( equation_type_and_normalized_equation[equation_reordered[block_type_firstequation_size_mfs[block_number].first.second+equation_number]].second);};
+  //! Return the original number of equation equation_number belonging to the block block_number
+  virtual int getBlockEquationID(int block_number, int equation_number) const {return( equation_reordered[block_type_firstequation_size_mfs[block_number].first.second+equation_number]);};
+  //! Return the original number of variable variable_number belonging to the block block_number
+  virtual int getBlockVariableID(int block_number, int variable_number) const {return( variable_reordered[block_type_firstequation_size_mfs[block_number].first.second+variable_number]);};
+  //! Return the position of equation_number in the block number belonging to the block block_number
+  virtual int getBlockInitialEquationID(int block_number, int equation_number) const {return((int)inv_equation_reordered[equation_number] - (int)block_type_firstequation_size_mfs[block_number].first.second);};
+  //! Return the position of variable_number in the block number belonging to the block block_number
+  virtual int getBlockInitialVariableID(int block_number, int variable_number) const {return((int)inv_variable_reordered[variable_number] - (int)block_type_firstequation_size_mfs[block_number].first.second);};
+
+
 };
 
 #endif
diff --git a/ExprNode.cc b/ExprNode.cc
index 705254e34057b8348229ca25440162543a397108..820dc9de1d009b4c50787c34d70e26e8712312bb 100644
--- a/ExprNode.cc
+++ b/ExprNode.cc
@@ -32,7 +32,6 @@ using namespace __gnu_cxx;
 
 #include "ExprNode.hh"
 #include "DataTree.hh"
-#include "BlockTriangular.hh"
 #include "ModFile.hh"
 
 ExprNode::ExprNode(DataTree &datatree_arg) : datatree(datatree_arg), preparedForDerivation(false)
@@ -127,9 +126,8 @@ ExprNode::computeTemporaryTerms(map<NodeID, int> &reference_count,
                                 temporary_terms_type &temporary_terms,
                                 map<NodeID, pair<int, int> > &first_occurence,
                                 int Curr_block,
-                                Model_Block *ModelBlock,
-                                int equation,
-                                map_idx_type &map_idx) const
+                                vector<vector<temporary_terms_type> > &v_temporary_terms,
+                                int equation) const
   {
     // Nothing to do for a terminal node
   }
@@ -242,18 +240,17 @@ NumConstNode::computeDerivative(int deriv_id)
 }
 
 void
-NumConstNode::collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const
+NumConstNode::collectTemporary_terms(const temporary_terms_type &temporary_terms, temporary_terms_inuse_type &temporary_terms_inuse, int Curr_Block) const
   {
     temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<NumConstNode *>(this));
     if (it != temporary_terms.end())
-      ModelBlock->Block_List[Curr_Block].Temporary_InUse->insert(idx);
+      temporary_terms_inuse.insert(idx);
   }
 
 void
 NumConstNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
                           const temporary_terms_type &temporary_terms) const
   {
-    //cout << "writeOutput constante\n";
     temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<NumConstNode *>(this));
     if (it != temporary_terms.end())
       if (output_type == oMatlabDynamicModelSparse)
@@ -427,13 +424,13 @@ VariableNode::computeDerivative(int deriv_id)
 }
 
 void
-VariableNode::collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const
+VariableNode::collectTemporary_terms(const temporary_terms_type &temporary_terms, temporary_terms_inuse_type &temporary_terms_inuse, int Curr_Block) const
   {
     temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<VariableNode *>(this));
     if (it != temporary_terms.end())
-      ModelBlock->Block_List[Curr_Block].Temporary_InUse->insert(idx);
+      temporary_terms_inuse.insert(idx);
     if (type== eModelLocalVariable)
-      datatree.local_variables_table[symb_id]->collectTemporary_terms(temporary_terms, ModelBlock, Curr_Block);
+      datatree.local_variables_table[symb_id]->collectTemporary_terms(temporary_terms, temporary_terms_inuse, Curr_Block);
   }
 
 void
@@ -486,7 +483,7 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
 
       case eModelLocalVariable:
       case eModFileLocalVariable:
-        if (output_type==oMatlabDynamicModelSparse || output_type==oMatlabStaticModelSparse)
+        if (output_type==oMatlabDynamicModelSparse || output_type==oMatlabStaticModelSparse || output_type == oMatlabDynamicModelSparseLocalTemporaryTerms)
           {
             output << "(";
             datatree.local_variables_table[symb_id]->writeOutput(output, output_type,temporary_terms);
@@ -510,6 +507,7 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
             output <<  "y" << LEFT_ARRAY_SUBSCRIPT(output_type) << i << RIGHT_ARRAY_SUBSCRIPT(output_type);
             break;
           case oMatlabDynamicModelSparse:
+          case oMatlabDynamicModelSparseLocalTemporaryTerms:
             i = tsid + ARRAY_SUBSCRIPT_OFFSET(output_type);
             if (lag > 0)
               output << "y" << LEFT_ARRAY_SUBSCRIPT(output_type) << "it_+" << lag << ", " << i << RIGHT_ARRAY_SUBSCRIPT(output_type);
@@ -535,6 +533,7 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
           {
           case oMatlabDynamicModel:
           case oMatlabDynamicModelSparse:
+          case oMatlabDynamicModelSparseLocalTemporaryTerms:
             if (lag > 0)
               output <<  "x(it_+" << lag << ", " << i << ")";
             else if (lag < 0)
@@ -572,6 +571,7 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
           {
           case oMatlabDynamicModel:
           case oMatlabDynamicModelSparse:
+          case oMatlabDynamicModelSparseLocalTemporaryTerms:
             if (lag > 0)
               output <<  "x(it_+" << lag << ", " << i << ")";
             else if (lag < 0)
@@ -695,12 +695,11 @@ VariableNode::computeTemporaryTerms(map<NodeID, int> &reference_count,
                                     temporary_terms_type &temporary_terms,
                                     map<NodeID, pair<int, int> > &first_occurence,
                                     int Curr_block,
-                                    Model_Block *ModelBlock,
-                                    int equation,
-                                    map_idx_type &map_idx) const
+                                    vector<vector<temporary_terms_type> > &v_temporary_terms,
+                                    int equation) const
   {
     if (type== eModelLocalVariable)
-      datatree.local_variables_table[symb_id]->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, ModelBlock, equation, map_idx);
+      datatree.local_variables_table[symb_id]->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, v_temporary_terms, equation);
   }
 
 void
@@ -1204,9 +1203,8 @@ UnaryOpNode::computeTemporaryTerms(map<NodeID, int> &reference_count,
                                    temporary_terms_type &temporary_terms,
                                    map<NodeID, pair<int, int> > &first_occurence,
                                    int Curr_block,
-                                   Model_Block *ModelBlock,
-                                   int equation,
-                                   map_idx_type &map_idx) const
+                                   vector< vector<temporary_terms_type> > &v_temporary_terms,
+                                   int equation) const
   {
     NodeID this2 = const_cast<UnaryOpNode *>(this);
     map<NodeID, int>::iterator it = reference_count.find(this2);
@@ -1214,7 +1212,7 @@ UnaryOpNode::computeTemporaryTerms(map<NodeID, int> &reference_count,
       {
         reference_count[this2] = 1;
         first_occurence[this2] = make_pair(Curr_block,equation);
-        arg->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, ModelBlock, equation, map_idx);
+        arg->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, v_temporary_terms, equation);
       }
     else
       {
@@ -1222,19 +1220,19 @@ UnaryOpNode::computeTemporaryTerms(map<NodeID, int> &reference_count,
         if (reference_count[this2] * cost(temporary_terms, false) > MIN_COST_C)
           {
             temporary_terms.insert(this2);
-            ModelBlock->Block_List[first_occurence[this2].first].Temporary_Terms_in_Equation[first_occurence[this2].second]->insert(this2);
+            v_temporary_terms[first_occurence[this2].first][first_occurence[this2].second].insert(this2);
           }
       }
   }
 
 void
-UnaryOpNode::collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const
+UnaryOpNode::collectTemporary_terms(const temporary_terms_type &temporary_terms, temporary_terms_inuse_type &temporary_terms_inuse, int Curr_Block) const
   {
     temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<UnaryOpNode*>(this));
     if (it != temporary_terms.end())
-      ModelBlock->Block_List[Curr_Block].Temporary_InUse->insert(idx);
+      temporary_terms_inuse.insert(idx);
     else
-      arg->collectTemporary_terms(temporary_terms, ModelBlock, Curr_Block);
+      arg->collectTemporary_terms(temporary_terms, temporary_terms_inuse, Curr_Block);
   }
 
 void
@@ -1326,6 +1324,7 @@ UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
             cerr << "Steady State Operator not implemented for oCDynamicModel." << endl;
             exit(EXIT_FAILURE);
           case oMatlabDynamicModelSparse:
+          case oMatlabDynamicModelSparseLocalTemporaryTerms:
             cerr << "Steady State Operator not implemented for oMatlabDynamicModelSparse." << endl;
             exit(EXIT_FAILURE);
           default:
@@ -1989,9 +1988,8 @@ BinaryOpNode::computeTemporaryTerms(map<NodeID, int> &reference_count,
                                     temporary_terms_type &temporary_terms,
                                     map<NodeID, pair<int, int> > &first_occurence,
                                     int Curr_block,
-                                    Model_Block *ModelBlock,
-                                    int equation,
-                                    map_idx_type &map_idx) const
+                                    vector<vector<temporary_terms_type> > &v_temporary_terms,
+                                    int equation) const
   {
     NodeID this2 = const_cast<BinaryOpNode *>(this);
     map<NodeID, int>::iterator it = reference_count.find(this2);
@@ -1999,8 +1997,8 @@ BinaryOpNode::computeTemporaryTerms(map<NodeID, int> &reference_count,
       {
         reference_count[this2] = 1;
         first_occurence[this2] = make_pair(Curr_block, equation);
-        arg1->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, ModelBlock, equation, map_idx);
-        arg2->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, ModelBlock, equation, map_idx);
+        arg1->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, v_temporary_terms, equation);
+        arg2->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, v_temporary_terms, equation);
       }
     else
       {
@@ -2008,7 +2006,7 @@ BinaryOpNode::computeTemporaryTerms(map<NodeID, int> &reference_count,
         if (reference_count[this2] * cost(temporary_terms, false) > MIN_COST_C)
           {
             temporary_terms.insert(this2);
-            ModelBlock->Block_List[first_occurence[this2].first].Temporary_Terms_in_Equation[first_occurence[this2].second]->insert(this2);
+            v_temporary_terms[first_occurence[this2].first][first_occurence[this2].second].insert(this2);
           }
       }
   }
@@ -2092,15 +2090,15 @@ BinaryOpNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_
   }
 
 void
-BinaryOpNode::collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const
+BinaryOpNode::collectTemporary_terms(const temporary_terms_type &temporary_terms, temporary_terms_inuse_type &temporary_terms_inuse, int Curr_Block) const
   {
     temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<BinaryOpNode *>(this));
     if (it != temporary_terms.end())
-      ModelBlock->Block_List[Curr_Block].Temporary_InUse->insert(idx);
+      temporary_terms_inuse.insert(idx);
     else
       {
-        arg1->collectTemporary_terms(temporary_terms, ModelBlock, Curr_Block);
-        arg2->collectTemporary_terms(temporary_terms, ModelBlock, Curr_Block);
+        arg1->collectTemporary_terms(temporary_terms, temporary_terms_inuse, Curr_Block);
+        arg2->collectTemporary_terms(temporary_terms, temporary_terms_inuse, Curr_Block);
       }
   }
 
@@ -2109,7 +2107,6 @@ void
 BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
                           const temporary_terms_type &temporary_terms) const
   {
-    //cout << "writeOutput binary\n";
     // If current node is a temporary term
     temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<BinaryOpNode *>(this));
     if (it != temporary_terms.end())
@@ -2897,9 +2894,8 @@ TrinaryOpNode::computeTemporaryTerms(map<NodeID, int> &reference_count,
                                      temporary_terms_type &temporary_terms,
                                      map<NodeID, pair<int, int> > &first_occurence,
                                      int Curr_block,
-                                     Model_Block *ModelBlock,
-                                     int equation,
-                                     map_idx_type &map_idx) const
+                                     vector<vector<temporary_terms_type> > &v_temporary_terms,
+                                     int equation) const
   {
     NodeID this2 = const_cast<TrinaryOpNode *>(this);
     map<NodeID, int>::iterator it = reference_count.find(this2);
@@ -2907,9 +2903,9 @@ TrinaryOpNode::computeTemporaryTerms(map<NodeID, int> &reference_count,
       {
         reference_count[this2] = 1;
         first_occurence[this2] = make_pair(Curr_block,equation);
-        arg1->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, ModelBlock, equation, map_idx);
-        arg2->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, ModelBlock, equation, map_idx);
-        arg3->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, ModelBlock, equation, map_idx);
+        arg1->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, v_temporary_terms, equation);
+        arg2->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, v_temporary_terms, equation);
+        arg3->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, v_temporary_terms, equation);
       }
     else
       {
@@ -2917,7 +2913,7 @@ TrinaryOpNode::computeTemporaryTerms(map<NodeID, int> &reference_count,
         if (reference_count[this2] * cost(temporary_terms, false) > MIN_COST_C)
           {
             temporary_terms.insert(this2);
-            ModelBlock->Block_List[first_occurence[this2].first].Temporary_Terms_in_Equation[first_occurence[this2].second]->insert(this2);
+            v_temporary_terms[first_occurence[this2].first][first_occurence[this2].second].insert(this2);
           }
       }
   }
@@ -2972,16 +2968,16 @@ TrinaryOpNode::compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms
   }
 
 void
-TrinaryOpNode::collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const
+TrinaryOpNode::collectTemporary_terms(const temporary_terms_type &temporary_terms, temporary_terms_inuse_type &temporary_terms_inuse, int Curr_Block) const
   {
     temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<TrinaryOpNode *>(this));
     if (it != temporary_terms.end())
-      ModelBlock->Block_List[Curr_Block].Temporary_InUse->insert(idx);
+      temporary_terms_inuse.insert(idx);
     else
       {
-        arg1->collectTemporary_terms(temporary_terms, ModelBlock, Curr_Block);
-        arg2->collectTemporary_terms(temporary_terms, ModelBlock, Curr_Block);
-        arg3->collectTemporary_terms(temporary_terms, ModelBlock, Curr_Block);
+        arg1->collectTemporary_terms(temporary_terms, temporary_terms_inuse, Curr_Block);
+        arg2->collectTemporary_terms(temporary_terms, temporary_terms_inuse, Curr_Block);
+        arg3->collectTemporary_terms(temporary_terms, temporary_terms_inuse, Curr_Block);
       }
   }
 
@@ -3206,9 +3202,8 @@ UnknownFunctionNode::computeTemporaryTerms(map<NodeID, int> &reference_count,
     temporary_terms_type &temporary_terms,
     map<NodeID, pair<int, int> > &first_occurence,
     int Curr_block,
-    Model_Block *ModelBlock,
-    int equation,
-    map_idx_type &map_idx) const
+    vector< vector<temporary_terms_type> > &v_temporary_terms,
+    int equation) const
   {
     cerr << "UnknownFunctionNode::computeTemporaryTerms: not implemented" << endl;
     exit(EXIT_FAILURE);
@@ -3223,11 +3218,11 @@ UnknownFunctionNode::collectVariables(SymbolType type_arg, set<pair<int, int> >
 }
 
 void
-UnknownFunctionNode::collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const
+UnknownFunctionNode::collectTemporary_terms(const temporary_terms_type &temporary_terms, temporary_terms_inuse_type &temporary_terms_inuse, int Curr_Block) const
   {
     temporary_terms_type::const_iterator it = temporary_terms.find(const_cast<UnknownFunctionNode *>(this));
     if (it != temporary_terms.end())
-      ModelBlock->Block_List[Curr_Block].Temporary_InUse->insert(idx);
+      temporary_terms_inuse.insert(idx);
     else
       {
         //arg->collectTemporary_terms(temporary_terms, result);
diff --git a/ExprNode.hh b/ExprNode.hh
index 6349e39dacb38eae917ff8cffdf6c0f838000b13..358687c182249f7199bfb6236e3b74ba73e91287 100644
--- a/ExprNode.hh
+++ b/ExprNode.hh
@@ -44,6 +44,9 @@ struct ExprNodeLess;
 /*! They are ordered by index number thanks to ExprNodeLess */
 typedef set<NodeID, ExprNodeLess> temporary_terms_type;
 
+//! set of temporary terms used in a block
+typedef set<int> temporary_terms_inuse_type;
+
 typedef map<int,int> map_idx_type;
 
 //! Type for evaluation contexts
@@ -63,7 +66,8 @@ enum ExprNodeOutputType
     oLatexDynamicModel,				             //!< LaTeX code, dynamic model declarations
     oLatexDynamicSteadyStateOperator,            //!< LaTeX code, dynamic model steady state declarations
 	oMatlabDynamicSteadyStateOperator,           //!< Matlab code, dynamic model steady state declarations
-	oMatlabDynamicModelSparseSteadyStateOperator //!< Matlab code, dynamic block decomposed mode steady state declarations
+	oMatlabDynamicModelSparseSteadyStateOperator, //!< Matlab code, dynamic block decomposed model steady state declarations
+	oMatlabDynamicModelSparseLocalTemporaryTerms  //!< Matlab code, dynamic block decomposed model local temporary_terms
   };
 
 #define IS_MATLAB(output_type) ((output_type) == oMatlabStaticModel     \
@@ -71,6 +75,7 @@ enum ExprNodeOutputType
                                 || (output_type) == oMatlabOutsideModel \
                                 || (output_type) == oMatlabStaticModelSparse \
                                 || (output_type) == oMatlabDynamicModelSparse \
+                                || (output_type) == oMatlabDynamicModelSparseLocalTemporaryTerms \
 								|| (output_type) == oMatlabDynamicSteadyStateOperator \
 								|| (output_type) == oMatlabDynamicModelSparseSteadyStateOperator)
 
@@ -102,7 +107,7 @@ class ExprNode
 {
   friend class DataTree;
   friend class DynamicModel;
-  friend class StaticDllModel;
+  friend class StaticModel;
   friend class ExprNodeLess;
   friend class NumConstNode;
   friend class VariableNode;
@@ -200,14 +205,13 @@ public:
   */
   virtual void collectModelLocalVariables(set<int> &result) const;
 
-  virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const = 0;
+  virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, temporary_terms_inuse_type &temporary_terms_inuse, int Curr_Block) const = 0;
   virtual void computeTemporaryTerms(map<NodeID, int> &reference_count,
                                      temporary_terms_type &temporary_terms,
                                      map<NodeID, pair<int, int> > &first_occurence,
                                      int Curr_block,
-                                     Model_Block *ModelBlock,
-                                     int equation,
-                                     map_idx_type &map_idx) const;
+                                     vector< vector<temporary_terms_type> > &v_temporary_terms,
+                                     int equation) const;
 
   class EvalException
 
@@ -245,7 +249,7 @@ public:
   typedef map<const ExprNode *, const VariableNode *> subst_table_t;
 
   //! Creates auxiliary endo lead variables corresponding to this expression
-  /*! 
+  /*!
     If maximum endogenous lead >= 3, this method will also create intermediary auxiliary var, and will add the equations of the form aux1 = aux2(+1) to the substitution table.
     \pre This expression is assumed to have maximum endogenous lead >= 2
     \param[in,out] subst_table The table to which new auxiliary variables and their correspondance will be added
@@ -255,7 +259,7 @@ public:
   VariableNode *createEndoLeadAuxiliaryVarForMyself(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
 
   //! Creates auxiliary exo lead variables corresponding to this expression
-  /*! 
+  /*!
     If maximum exogenous lead >= 2, this method will also create intermediary auxiliary var, and will add the equations of the form aux1 = aux2(+1) to the substitution table.
     \pre This expression is assumed to have maximum exogenous lead >= 1
     \param[in,out] subst_table The table to which new auxiliary variables and their correspondance will be added
@@ -332,7 +336,7 @@ public:
   virtual void prepareForDerivation();
   virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const;
   virtual void collectVariables(SymbolType type_arg, set<pair<int, int> > &result) const;
-  virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const;
+  virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, temporary_terms_inuse_type &temporary_terms_inuse, int Curr_Block) const;
   virtual double eval(const eval_context_type &eval_context) const throw (EvalException);
   virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const;
   virtual NodeID toStatic(DataTree &static_datatree) const;
@@ -367,10 +371,9 @@ public:
                                      temporary_terms_type &temporary_terms,
                                      map<NodeID, pair<int, int> > &first_occurence,
                                      int Curr_block,
-                                     Model_Block *ModelBlock,
-                                     int equation,
-                                     map_idx_type &map_idx) const;
-  virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const;
+                                     vector< vector<temporary_terms_type> > &v_temporary_terms,
+                                     int equation) const;
+  virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, temporary_terms_inuse_type &temporary_terms_inuse, int Curr_Block) const;
   virtual double eval(const eval_context_type &eval_context) const throw (EvalException);
   virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const;
   virtual NodeID toStatic(DataTree &static_datatree) const;
@@ -409,11 +412,10 @@ public:
                                      temporary_terms_type &temporary_terms,
                                      map<NodeID, pair<int, int> > &first_occurence,
                                      int Curr_block,
-                                     Model_Block *ModelBlock,
-                                     int equation,
-                                     map_idx_type &map_idx) const;
+                                     vector< vector<temporary_terms_type> > &v_temporary_terms,
+                                     int equation) const;
   virtual void collectVariables(SymbolType type_arg, set<pair<int, int> > &result) const;
-  virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const;
+  virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, temporary_terms_inuse_type &temporary_terms_inuse, int Curr_Block) const;
   static double eval_opcode(UnaryOpcode op_code, double v) throw (EvalException);
   virtual double eval(const eval_context_type &eval_context) const throw (EvalException);
   virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const;
@@ -458,11 +460,10 @@ public:
                                      temporary_terms_type &temporary_terms,
                                      map<NodeID, pair<int, int> > &first_occurence,
                                      int Curr_block,
-                                     Model_Block *ModelBlock,
-                                     int equation,
-                                     map_idx_type &map_idx) const;
+                                     vector< vector<temporary_terms_type> > &v_temporary_terms,
+                                     int equation) const;
   virtual void collectVariables(SymbolType type_arg, set<pair<int, int> > &result) const;
-  virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const;
+  virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, temporary_terms_inuse_type &temporary_terms_inuse, int Curr_Block) const;
   static double eval_opcode(double v1, BinaryOpcode op_code, double v2) throw (EvalException);
   virtual double eval(const eval_context_type &eval_context) const throw (EvalException);
   virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const;
@@ -511,11 +512,10 @@ public:
                                      temporary_terms_type &temporary_terms,
                                      map<NodeID, pair<int, int> > &first_occurence,
                                      int Curr_block,
-                                     Model_Block *ModelBlock,
-                                     int equation,
-                                     map_idx_type &map_idx) const;
+                                     vector< vector<temporary_terms_type> > &v_temporary_terms,
+                                     int equation) const;
   virtual void collectVariables(SymbolType type_arg, set<pair<int, int> > &result) const;
-  virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const;
+  virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, temporary_terms_inuse_type &temporary_terms_inuse, int Curr_Block) const;
   static double eval_opcode(double v1, TrinaryOpcode op_code, double v2, double v3) throw (EvalException);
   virtual double eval(const eval_context_type &eval_context) const throw (EvalException);
   virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const;
@@ -552,11 +552,10 @@ public:
                                      temporary_terms_type &temporary_terms,
                                      map<NodeID, pair<int, int> > &first_occurence,
                                      int Curr_block,
-                                     Model_Block *ModelBlock,
-                                     int equation,
-                                     map_idx_type &map_idx) const;
+                                     vector< vector<temporary_terms_type> > &v_temporary_terms,
+                                     int equation) const;
   virtual void collectVariables(SymbolType type_arg, set<pair<int, int> > &result) const;
-  virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const;
+  virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, temporary_terms_inuse_type &temporary_terms_inuse, int Curr_Block) const;
   virtual double eval(const eval_context_type &eval_context) const throw (EvalException);
   virtual void compile(ostream &CompileCode, bool lhs_rhs, const temporary_terms_type &temporary_terms, map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const;
   virtual NodeID toStatic(DataTree &static_datatree) const;
diff --git a/IncidenceMatrix.cc b/IncidenceMatrix.cc
deleted file mode 100644
index f9ce77577ef289fb83d3608f74abf2a32566f6c6..0000000000000000000000000000000000000000
--- a/IncidenceMatrix.cc
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (C) 2007-2009 Dynare Team
- *
- * This file is part of Dynare.
- *
- * Dynare is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Dynare is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <iostream>
-#include <cstdlib>
-#include <cstring>
-
-#include "IncidenceMatrix.hh"
-
-
-IncidenceMatrix::IncidenceMatrix(const SymbolTable &symbol_table_arg) :
-  symbol_table(symbol_table_arg)
-{
-  Model_Max_Lead = Model_Max_Lead_Endo = Model_Max_Lead_Exo = 0;
-  Model_Max_Lag = Model_Max_Lag_Endo = Model_Max_Lag_Exo = 0;
-}
-//------------------------------------------------------------------------------
-//For a lead or a lag build the Incidence Matrix structures
-bool*
-IncidenceMatrix::Build_IM(int lead_lag, SymbolType type)
-{
-  int size;
-  bool *IM;
-  if(type==eEndogenous)
-    {
-      size = symbol_table.endo_nbr() * symbol_table.endo_nbr() * sizeof(IM[0]);
-      List_IM[lead_lag] = IM = (bool*)malloc(size);
-      for(int i = 0; i< symbol_table.endo_nbr() * symbol_table.endo_nbr(); i++) IM[i] = 0;
-      if(lead_lag > 0)
-        {
-          if(lead_lag > Model_Max_Lead_Endo)
-            {
-              Model_Max_Lead_Endo = lead_lag;
-              if(lead_lag > Model_Max_Lead)
-                Model_Max_Lead = lead_lag;
-            }
-        }
-      else
-        {
-          if( -lead_lag > Model_Max_Lag_Endo)
-            {
-              Model_Max_Lag_Endo = -lead_lag;
-              if(-lead_lag > Model_Max_Lag)
-                Model_Max_Lag = -lead_lag;
-            }
-        }
-    }
-  else
-    {  //eExogenous
-      size = symbol_table.endo_nbr() * symbol_table.exo_nbr() * sizeof(IM[0]);
-      List_IM_X[lead_lag] = IM = (bool*)malloc(size);
-      for(int i = 0; i< symbol_table.endo_nbr() * symbol_table.exo_nbr(); i++) IM[i] = 0;
-      if(lead_lag > 0)
-        {
-          if(lead_lag > Model_Max_Lead_Exo)
-            {
-              Model_Max_Lead_Exo = lead_lag;
-              if(lead_lag > Model_Max_Lead)
-                Model_Max_Lead = lead_lag;
-            }
-        }
-      else
-        {
-          if( -lead_lag > Model_Max_Lag_Exo)
-            {
-              Model_Max_Lag_Exo = -lead_lag;
-              if(-lead_lag > Model_Max_Lag)
-                Model_Max_Lag = -lead_lag;
-            }
-        }
-    }
-  return (IM);
-}
-
-
-void
-IncidenceMatrix::Free_IM() const
-{
-  IncidenceList::const_iterator it = List_IM.begin();
-  for(it = List_IM.begin(); it != List_IM.end(); it++)
-    free(it->second);
-  for(it = List_IM_X.begin(); it != List_IM_X.end(); it++)
-    free(it->second);
-}
-
-//------------------------------------------------------------------------------
-// Return the incidence matrix related to a lead or a lag
-bool*
-IncidenceMatrix::Get_IM(int lead_lag, SymbolType type) const
-{
-  IncidenceList::const_iterator it;
-  if(type==eEndogenous)
-    {
-      it = List_IM.find(lead_lag);
-      if(it!=List_IM.end())
-        return(it->second);
-      else
-        return(NULL);
-    }
-  else  //eExogenous
-    {
-      it = List_IM_X.find(lead_lag);
-      if(it!=List_IM_X.end())
-        return(it->second);
-      else
-        return(NULL);
-    }
-}
-
-
-//------------------------------------------------------------------------------
-// Fill the incidence matrix related to a lead or a lag
-void
-IncidenceMatrix::fill_IM(int equation, int variable, int lead_lag, SymbolType type)
-{
-  bool* Cur_IM;
-  Cur_IM = Get_IM(lead_lag, type);
-  if(equation >= symbol_table.endo_nbr())
-    {
-      cout << "Error : The model has more equations (at least " << equation + 1 << ") than declared endogenous variables (" << symbol_table.endo_nbr() << ")\n";
-      exit(EXIT_FAILURE);
-    }
-  if (!Cur_IM)
-    Cur_IM = Build_IM(lead_lag, type);
-  if(type==eEndogenous)
-    Cur_IM[equation*symbol_table.endo_nbr() + variable] = 1;
-  else
-    Cur_IM[equation*symbol_table.exo_nbr() + variable] = 1;
-}
-
-//------------------------------------------------------------------------------
-// unFill the incidence matrix related to a lead or a lag
-void
-IncidenceMatrix::unfill_IM(int equation, int variable, int lead_lag, SymbolType type)
-{
-  bool* Cur_IM;
-  Cur_IM = Get_IM(lead_lag, type);
-  if (!Cur_IM)
-    Cur_IM = Build_IM(lead_lag, type);
-  if(type==eEndogenous)
-    Cur_IM[equation*symbol_table.endo_nbr() + variable] = 0;
-  else
-    Cur_IM[equation*symbol_table.exo_nbr() + variable] = 0;
-}
-
-
-//------------------------------------------------------------------------------
-//Print azn incidence matrix
-void
-IncidenceMatrix::Print_SIM(bool* IM, SymbolType type) const
-{
-  int i, j, n;
-  if(type == eEndogenous)
-    n = symbol_table.endo_nbr();
-  else
-    n = symbol_table.exo_nbr();
-  for(i = 0;i < symbol_table.endo_nbr();i++)
-    {
-      cout << " ";
-      for(j = 0;j < n;j++)
-        cout << IM[i*n + j] << " ";
-      cout << "\n";
-    }
-}
-
-//------------------------------------------------------------------------------
-//Print all incidence matrix
-void
-IncidenceMatrix::Print_IM(SymbolType type) const
-{
-  IncidenceList::const_iterator it;
-  cout << "-------------------------------------------------------------------\n";
-  if(type == eEndogenous)
-    for(int k=-Model_Max_Lag_Endo; k <= Model_Max_Lead_Endo; k++)
-      {
-        it = List_IM.find(k);
-        if(it!=List_IM.end())
-          {
-            cout << "Incidence matrix for lead_lag = " << k << "\n";
-            Print_SIM(it->second, type);
-          }
-      }
-  else // eExogenous
-    for(int k=-Model_Max_Lag_Exo; k <= Model_Max_Lead_Exo; k++)
-      {
-        it = List_IM_X.find(k);
-        if(it!=List_IM_X.end())
-          {
-            cout << "Incidence matrix for lead_lag = " << k << "\n";
-            Print_SIM(it->second, type);
-          }
-      }
-}
-
-
-//------------------------------------------------------------------------------
-// Swap rows and columns of the incidence matrix
-void
-IncidenceMatrix::swap_IM_c(bool *SIM, int pos1, int pos2, int pos3, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM, int n) const
-{
-  int tmp_i, j;
-  bool tmp_b;
-  /* We exchange equation (row)...*/
-  if(pos1 != pos2)
-    {
-      tmp_i = Index_Equ_IM[pos1];
-      Index_Equ_IM[pos1] = Index_Equ_IM[pos2];
-      Index_Equ_IM[pos2] = tmp_i;
-      for(j = 0;j < n;j++)
-        {
-          tmp_b = SIM[pos1 * n + j];
-          SIM[pos1*n + j] = SIM[pos2 * n + j];
-          SIM[pos2*n + j] = tmp_b;
-        }
-    }
-  /* ...and variables (column)*/
-  if(pos1 != pos3)
-    {
-      tmp_i = Index_Var_IM[pos1];
-      Index_Var_IM[pos1] = Index_Var_IM[pos3];
-      Index_Var_IM[pos3] = tmp_i;
-      for(j = 0;j < n;j++)
-        {
-          tmp_b = SIM[j * n + pos1];
-          SIM[j*n + pos1] = SIM[j * n + pos3];
-          SIM[j*n + pos3] = tmp_b;
-        }
-    }
-}
diff --git a/IncidenceMatrix.hh b/IncidenceMatrix.hh
deleted file mode 100644
index 765dd02731c0e56f039e419d0ed5f9efbf8b4e06..0000000000000000000000000000000000000000
--- a/IncidenceMatrix.hh
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2007-2008 Dynare Team
- *
- * This file is part of Dynare.
- *
- * Dynare is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Dynare is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _INCIDENCEMATRIX_HH
-#define _INCIDENCEMATRIX_HH
-
-
-#include <map>
-#include "ExprNode.hh"
-#include "SymbolTable.hh"
-
-
-
-
-
-//! List of incidence matrix (one matrix per lead/lag)
-typedef bool* pbool;
-typedef map<int,pbool> IncidenceList;
-
-//! create and manage the incidence matrix
-class IncidenceMatrix
-{
-public:
-  const SymbolTable &symbol_table;
-  IncidenceMatrix(const SymbolTable &symbol_table_arg);
-  bool* Build_IM(int lead_lag, SymbolType type);
-  bool* Get_IM(int lead_lag, SymbolType type) const;
-  void fill_IM(int equation, int variable_endo, int lead_lag, SymbolType type);
-  void unfill_IM(int equation, int variable_endo, int lead_lag, SymbolType type);
-  void Free_IM() const;
-  void Print_IM(SymbolType type) const;
-  void Print_SIM(bool* IM, SymbolType type) const;
-  void swap_IM_c(bool *SIM, int pos1, int pos2, int pos3, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM, int n) const;
-  int Model_Max_Lead, Model_Max_Lag;
-  int Model_Max_Lead_Endo, Model_Max_Lag_Endo, Model_Max_Lead_Exo, Model_Max_Lag_Exo;
-private:
-  IncidenceList  List_IM, List_IM_X;
-};
-
-
-#endif
diff --git a/Makefile.am b/Makefile.am
index 87d601d646167ccad53b7f5571d60559525cdebe..643e9909930a83cb17986c9377bf002a1695c67e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -16,8 +16,6 @@ dynare_m_SOURCES = \
 	ModelTree.hh \
 	StaticModel.cc \
 	StaticModel.hh \
-	StaticDllModel.cc \
-	StaticDllModel.hh \
 	DynamicModel.cc \
 	DynamicModel.hh \
 	NumericalConstants.cc \
@@ -44,10 +42,6 @@ dynare_m_SOURCES = \
 	ExprNode.hh \
 	MinimumFeedbackSet.cc \
 	MinimumFeedbackSet.hh \
-	IncidenceMatrix.cc \
-	IncidenceMatrix.hh \
-	BlockTriangular.cc \
-	BlockTriangular.hh \
 	DynareMain.cc \
 	DynareMain2.cc \
 	CodeInterpreter.hh \
diff --git a/ModFile.cc b/ModFile.cc
index 42c829b84ccf4fbed6d6bafd5be313177d52e119..badbad11e7b45e3a26baba094662202bb69a11da 100644
--- a/ModFile.cc
+++ b/ModFile.cc
@@ -25,7 +25,6 @@
 
 ModFile::ModFile() : expressions_tree(symbol_table, num_constants),
                      static_model(symbol_table, num_constants),
-                     static_dll_model(symbol_table, num_constants),
                      dynamic_model(symbol_table, num_constants),
                      linear(false), block(false), byte_code(false),
                      use_dll(false)
@@ -187,16 +186,8 @@ ModFile::computingPass(bool no_tmp_terms)
   if (dynamic_model.equation_number() > 0)
     {
       // Compute static model and its derivatives
-      if(byte_code)
-        {
-          dynamic_model.toStaticDll(static_dll_model);
-          static_dll_model.computingPass(global_eval_context, no_tmp_terms, block);
-        }
-      else
-        {
-          dynamic_model.toStatic(static_model);
-          static_model.computingPass(block, false, no_tmp_terms);
-        }
+      dynamic_model.toStatic(static_model);
+      static_model.computingPass(global_eval_context, no_tmp_terms, false, block);
       // Set things to compute for dynamic model
       if (dynamic_model_needed)
         {
@@ -356,22 +347,14 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all
       InitValStatement *ivs = dynamic_cast<InitValStatement *>(*it);
       if (ivs != NULL)
         {
-          if (!byte_code)
-            static_model.writeAuxVarInitval(mOutputFile);
-          else
-            static_dll_model.writeAuxVarInitval(mOutputFile);
+          static_model.writeAuxVarInitval(mOutputFile);
           ivs->writeOutputPostInit(mOutputFile);
         }
 
       // Special treatment for load params and steady state statement: insert initial values for the auxiliary variables
       LoadParamsAndSteadyStateStatement *lpass = dynamic_cast<LoadParamsAndSteadyStateStatement *>(*it);
       if (lpass)
-        {
-          if (!byte_code)
-            static_model.writeAuxVarInitval(mOutputFile);
-          else
-            static_dll_model.writeAuxVarInitval(mOutputFile);
-        }
+        static_model.writeAuxVarInitval(mOutputFile);
     }
 
   // Remove path for block option with M-files
@@ -387,10 +370,8 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all
   // Create static and dynamic files
   if (dynamic_model.equation_number() > 0)
     {
-      if(byte_code)
-        static_dll_model.writeStaticFile(basename, block);
-      else
-        static_model.writeStaticFile(basename, block);
+      static_model.writeStaticFile(basename, block, byte_code);
+
       if(dynamic_model_needed)
         {
           dynamic_model.writeDynamicFile(basename, block, byte_code, use_dll);
diff --git a/ModFile.hh b/ModFile.hh
index e7ba4e8ddfa313d2391e8509c1549b660a667cda..bf128690849f304b1530fbfb92c47761ec7f462b 100644
--- a/ModFile.hh
+++ b/ModFile.hh
@@ -29,7 +29,6 @@ using namespace std;
 #include "NumericalConstants.hh"
 #include "NumericalInitialization.hh"
 #include "StaticModel.hh"
-#include "StaticDllModel.hh"
 #include "DynamicModel.hh"
 #include "Statement.hh"
 
@@ -45,10 +44,8 @@ public:
   NumericalConstants num_constants;
   //! Expressions outside model block
   DataTree expressions_tree;
-  //! Static model
-  StaticModel static_model;
   //! Static Dll model
-  StaticDllModel static_dll_model;
+  StaticModel static_model;
   //! Dynamic model
   DynamicModel dynamic_model;
   //! Option linear
diff --git a/ModelTree.cc b/ModelTree.cc
index bf8ecb96b0dcd30930eadc9a39e434eac7b9a113..91e205828790b403659a0d5dbfe43d7e44c4c1d3 100644
--- a/ModelTree.cc
+++ b/ModelTree.cc
@@ -23,6 +23,812 @@
 #include <fstream>
 
 #include "ModelTree.hh"
+#include "MinimumFeedbackSet.hh"
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/max_cardinality_matching.hpp>
+#include <boost/graph/strong_components.hpp>
+#include <boost/graph/topological_sort.hpp>
+
+using namespace boost;
+using namespace MFS;
+
+void
+ModelTree::computeNormalization(const set<pair<int, int> > &endo_eqs_incidence) throw (NormalizationException)
+{
+  const int n = equation_number();
+
+  assert(n == symbol_table.endo_nbr());
+
+  typedef adjacency_list<vecS, vecS, undirectedS> BipartiteGraph;
+
+  /*
+    Vertices 0 to n-1 are for endogenous (using type specific ID)
+    Vertices n to 2*n-1 are for equations (using equation no.)
+  */
+  BipartiteGraph g(2 * n);
+
+  // Fill in the graph
+  set<pair<int, int> > endo;
+
+  for(set<pair<int, int> >::const_iterator it = endo_eqs_incidence.begin(); it != endo_eqs_incidence.end(); it++)
+    add_edge(it->first + n, it->second, g);
+
+  // Compute maximum cardinality matching
+  vector<int> mate_map(2*n);
+
+#if 1
+  bool check = checked_edmonds_maximum_cardinality_matching(g, &mate_map[0]);
+#else // Alternative way to compute normalization, by giving an initial matching using natural normalizations
+  fill(mate_map.begin(), mate_map.end(), graph_traits<BipartiteGraph>::null_vertex());
+
+  multimap<int, int> natural_endo2eqs;
+  computeNormalizedEquations(natural_endo2eqs);
+
+  for(int i = 0; i < symbol_table.endo_nbr(); i++)
+    {
+      if (natural_endo2eqs.count(i) == 0)
+        continue;
+
+      int j = natural_endo2eqs.find(i)->second;
+
+      put(&mate_map[0], i, n+j);
+      put(&mate_map[0], n+j, i);
+    }
+
+  edmonds_augmenting_path_finder<BipartiteGraph, size_t *, property_map<BipartiteGraph, vertex_index_t>::type> augmentor(g, &mate_map[0], get(vertex_index, g));
+  bool not_maximum_yet = true;
+  while(not_maximum_yet)
+    {
+      not_maximum_yet = augmentor.augment_matching();
+    }
+  augmentor.get_current_matching(&mate_map[0]);
+
+  bool check = maximum_cardinality_matching_verifier<BipartiteGraph, size_t *, property_map<BipartiteGraph, vertex_index_t>::type>::verify_matching(g, &mate_map[0], get(vertex_index, g));
+#endif
+
+  assert(check);
+
+#ifdef DEBUG
+  for(int i = 0; i < n; i++)
+    cout << "Endogenous " << symbol_table.getName(symbol_table.getID(eEndogenous, i))
+         << " matched with equation " << (mate_map[i]-n+1) << endl;
+#endif
+
+  // Create the resulting map, by copying the n first elements of mate_map, and substracting n to them
+  endo2eq.resize(equation_number());
+  transform(mate_map.begin(), mate_map.begin() + n, endo2eq.begin(), bind2nd(minus<int>(), n));
+
+#ifdef DEBUG
+  multimap<int, int> natural_endo2eqs;
+  computeNormalizedEquations(natural_endo2eqs);
+
+  int n1 = 0, n2 = 0;
+
+  for(int i = 0; i < symbol_table.endo_nbr(); i++)
+    {
+      if (natural_endo2eqs.count(i) == 0)
+        continue;
+
+      n1++;
+
+      pair<multimap<int, int>::const_iterator, multimap<int, int>::const_iterator> x = natural_endo2eqs.equal_range(i);
+      if (find_if(x.first, x.second, compose1(bind2nd(equal_to<int>(), endo2eq[i]), select2nd<multimap<int, int>::value_type>())) == x.second)
+        cout << "Natural normalization of variable " << symbol_table.getName(symbol_table.getID(eEndogenous, i))
+             << " not used." << endl;
+      else
+        n2++;
+    }
+
+  cout << "Used " << n2 << " natural normalizations out of " << n1 << ", for a total of " << n << " equations." << endl;
+#endif
+
+  // Check if all variables are normalized
+  vector<int>::const_iterator it = find(mate_map.begin(), mate_map.begin() + n, graph_traits<BipartiteGraph>::null_vertex());
+  if (it != mate_map.begin() + n)
+    throw NormalizationException(symbol_table.getID(eEndogenous, it - mate_map.begin()));
+}
+
+
+void
+ModelTree::computePossiblySingularNormalization(const jacob_map &contemporaneous_jacobian, bool try_symbolic)
+{
+  cout << "Normalizing the model..." << endl;
+
+  set<pair<int, int> > endo_eqs_incidence;
+
+  for(jacob_map::const_iterator it = contemporaneous_jacobian.begin();
+      it != contemporaneous_jacobian.end(); it++)
+    endo_eqs_incidence.insert(make_pair(it->first.first, it->first.second));
+
+  try
+    {
+      computeNormalization(endo_eqs_incidence);
+      return;
+    }
+  catch(NormalizationException &e)
+    {
+      if (try_symbolic)
+        cout << "Normalization failed with cutoff, trying symbolic normalization..." << endl;
+      else
+        {
+          cerr << "ERROR: Could not normalize the model. Variable "
+               << symbol_table.getName(e.symb_id)
+               << " is not in the maximum cardinality matching. Try to decrease the cutoff." << endl;
+          exit(EXIT_FAILURE);
+        }
+    }
+
+  // If no non-singular normalization can be found, try to find a normalization even with a potential singularity
+  if (try_symbolic)
+    {
+      endo_eqs_incidence.clear();
+      set<pair<int, int> > endo;
+      for(int i = 0; i < equation_number(); i++)
+        {
+          endo.clear();
+          equations[i]->collectEndogenous(endo);
+          for(set<pair<int, int> >::const_iterator it = endo.begin(); it != endo.end(); it++)
+            endo_eqs_incidence.insert(make_pair(i, it->first));
+        }
+
+      try
+        {
+          computeNormalization(endo_eqs_incidence);
+        }
+      catch(NormalizationException &e)
+        {
+          cerr << "ERROR: Could not normalize the model even with zero cutoff. Variable "
+               << symbol_table.getName(e.symb_id)
+               << " is not in the maximum cardinality matching." << endl;
+          exit(EXIT_FAILURE);
+        }
+    }
+}
+
+void
+ModelTree::computeNormalizedEquations(multimap<int, int> &endo2eqs) const
+{
+  for(int i = 0; i < equation_number(); i++)
+    {
+      VariableNode *lhs = dynamic_cast<VariableNode *>(equations[i]->get_arg1());
+      if (lhs == NULL)
+        continue;
+
+      int symb_id = lhs->get_symb_id();
+      if (symbol_table.getType(symb_id) != eEndogenous)
+        continue;
+
+      set<pair<int, int> > endo;
+      equations[i]->get_arg2()->collectEndogenous(endo);
+      if (endo.find(make_pair(symbol_table.getTypeSpecificID(symb_id), 0)) != endo.end())
+        continue;
+
+      endo2eqs.insert(make_pair(symbol_table.getTypeSpecificID(symb_id), i));
+      cout << "Endogenous " << symbol_table.getName(symb_id) << " normalized in equation " << (i+1) << endl;
+    }
+}
+
+
+void
+ModelTree::evaluateAndReduceJacobian(const eval_context_type &eval_context, jacob_map &contemporaneous_jacobian, jacob_map &static_jacobian, dynamic_jacob_map &dynamic_jacobian, double cutoff, bool verbose)
+{
+  int nb_elements_contemparenous_Jacobian = 0;
+  set<pair<int, int> > jacobian_elements_to_delete;
+  for (first_derivatives_type::iterator it = first_derivatives.begin();
+       it != first_derivatives.end(); it++)
+    {
+      int deriv_id = it->first.second;
+      if (getTypeByDerivID(deriv_id) == eEndogenous)
+        {
+          NodeID Id = it->second;
+          int eq = it->first.first;
+          int symb = getSymbIDByDerivID(deriv_id);
+          int var = symbol_table.getTypeSpecificID(symb);
+          int lag = getLagByDerivID(deriv_id);
+          double val = 0;
+          try
+            {
+              val = Id->eval(eval_context);
+            }
+          catch (ExprNode::EvalException &e)
+            {
+              cerr << "ERROR: evaluation of Jacobian failed for equation " << eq+1 << " and variable " << symbol_table.getName(symb) << "(" << lag << ") [" << symb << "] !" << endl;
+              Id->writeOutput(cerr, oMatlabDynamicModelSparse, temporary_terms);
+              cerr << endl;
+              exit(EXIT_FAILURE);
+            }
+
+          if (fabs(val) < cutoff)
+            {
+              if (verbose)
+                cout << "the coefficient related to variable " << var << " with lag " << lag << " in equation " << eq << " is equal to " << val << " and is set to 0 in the incidence matrix (size=" << symbol_table.endo_nbr() << ")" << endl;
+              jacobian_elements_to_delete.insert(make_pair(eq, deriv_id));
+            }
+          else
+            {
+              if (lag == 0)
+                {
+                  nb_elements_contemparenous_Jacobian++;
+                  contemporaneous_jacobian[make_pair(eq,var)] = val;
+                }
+              if (static_jacobian.find(make_pair(eq, var)) != static_jacobian.end())
+                static_jacobian[make_pair(eq, var)] += val;
+              else
+                static_jacobian[make_pair(eq, var)] = val;
+              dynamic_jacobian[make_pair(lag, make_pair(eq, var))] = Id;
+            }
+        }
+    }
+
+  // Get rid of the elements of the Jacobian matrix below the cutoff
+  for(set<pair<int, int> >::const_iterator it = jacobian_elements_to_delete.begin(); it != jacobian_elements_to_delete.end(); it++)
+    first_derivatives.erase(*it);
+
+  if (jacobian_elements_to_delete.size()>0)
+    {
+      cout << jacobian_elements_to_delete.size() << " elements among " << first_derivatives.size() << " in the incidence matrices are below the cutoff (" << cutoff << ") and are discarded" << endl
+           << "The contemporaneous incidence matrix has " << nb_elements_contemparenous_Jacobian << " elements" << endl;
+    }
+}
+
+void
+ModelTree::computePrologueAndEpilogue(jacob_map &static_jacobian_arg, vector<int> &equation_reordered, vector<int> &variable_reordered, unsigned int &prologue, unsigned int &epilogue)
+{
+  vector<int> eq2endo(equation_number(),0);
+  equation_reordered.resize(equation_number());
+  variable_reordered.resize(equation_number());
+  bool *IM;
+  int n = equation_number();
+  IM = (bool*)calloc(n*n,sizeof(bool));
+  int i = 0;
+  for(vector<int>::const_iterator it=endo2eq.begin(); it != endo2eq.end(); it++, i++)
+    {
+      eq2endo[*it] = i;
+      equation_reordered[i] = i;
+      variable_reordered[*it] = i;
+    }
+  for (jacob_map::const_iterator it = static_jacobian_arg.begin(); it != static_jacobian_arg.end(); it ++)
+    IM[it->first.first * n + endo2eq[it->first.second]] = true;
+  bool something_has_been_done = true;
+  prologue = 0;
+  int k = 0;
+  // Find the prologue equations and place first the AR(1) shock equations first
+  while (something_has_been_done)
+    {
+      int tmp_prologue = prologue;
+      something_has_been_done = false;
+      for(int i = prologue;i < n; i++)
+        {
+          int nze = 0;
+          for(int j = tmp_prologue; j < n; j++)
+            if(IM[i * n + j])
+              {
+                nze ++;
+                k = j;
+              }
+          if(nze == 1)
+            {
+              for(int j = 0; j < n; j++)
+                {
+                  bool tmp_bool = IM[tmp_prologue * n + j];
+                  IM[tmp_prologue * n + j] = IM[i * n + j];
+                  IM[i * n + j] = tmp_bool;
+                }
+              int tmp = equation_reordered[tmp_prologue];
+              equation_reordered[tmp_prologue] = equation_reordered[i];
+              equation_reordered[i] = tmp;
+              for(int j = 0; j < n; j++)
+                {
+                  bool tmp_bool = IM[j * n + tmp_prologue];
+                  IM[j * n + tmp_prologue] = IM[j * n + k];
+                  IM[j * n + k] = tmp_bool;
+                }
+              tmp = variable_reordered[tmp_prologue];
+              variable_reordered[tmp_prologue] = variable_reordered[k];
+              variable_reordered[k] = tmp;
+              tmp_prologue++;
+              something_has_been_done = true;
+            }
+        }
+      prologue = tmp_prologue;
+    }
+
+  something_has_been_done = true;
+  epilogue = 0;
+  // Find the epilogue equations
+  while (something_has_been_done)
+    {
+      int tmp_epilogue = epilogue;
+      something_has_been_done = false;
+      for(int i = prologue;i < n - (int) epilogue; i++)
+        {
+          int nze = 0;
+          for(int j = prologue; j < n - tmp_epilogue; j++)
+            if(IM[j * n + i])
+              {
+                nze ++;
+                k = j;
+              }
+          if(nze == 1)
+            {
+              for(int j = 0; j < n; j++)
+                {
+                  bool tmp_bool = IM[(n - 1 - tmp_epilogue) * n + j];
+                  IM[(n - 1 - tmp_epilogue) * n + j] = IM[k * n + j];
+                  IM[k * n + j] = tmp_bool;
+                }
+              int tmp = equation_reordered[n - 1 - tmp_epilogue];
+              equation_reordered[n - 1 - tmp_epilogue] = equation_reordered[k];
+              equation_reordered[k] = tmp;
+              for(int j = 0; j < n; j++)
+                {
+                  bool tmp_bool = IM[j * n + n - 1 - tmp_epilogue];
+                  IM[j * n + n - 1 - tmp_epilogue] = IM[j * n + i];
+                  IM[j * n + i] = tmp_bool;
+                }
+              tmp = variable_reordered[n - 1 - tmp_epilogue];
+              variable_reordered[n - 1 - tmp_epilogue] = variable_reordered[i];
+              variable_reordered[i] = tmp;
+              tmp_epilogue++;
+              something_has_been_done = true;
+            }
+        }
+      epilogue = tmp_epilogue;
+    }
+  free(IM);
+}
+
+t_equation_type_and_normalized_equation
+ModelTree::equationTypeDetermination(vector<BinaryOpNode *> &equations, map<pair<int, pair<int, int> >, NodeID> &first_order_endo_derivatives, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM, int mfs)
+{
+  NodeID lhs, rhs;
+  ostringstream tmp_output;
+  BinaryOpNode *eq_node;
+  ostringstream tmp_s;
+  temporary_terms_type temporary_terms;
+  EquationType Equation_Simulation_Type;
+  t_equation_type_and_normalized_equation V_Equation_Simulation_Type(equations.size());
+  for (unsigned int i = 0; i < equations.size(); i++)
+    {
+      temporary_terms.clear();
+      int eq = Index_Equ_IM[i];
+      int var = Index_Var_IM[i];
+      eq_node = equations[eq];
+      lhs = eq_node->get_arg1();
+      rhs = eq_node->get_arg2();
+      Equation_Simulation_Type = E_SOLVE;
+      tmp_s.str("");
+      tmp_output.str("");
+      lhs->writeOutput(tmp_output, oMatlabDynamicModelSparse, temporary_terms);
+      tmp_s << "y(it_, " << Index_Var_IM[i]+1 << ")";
+      map<pair<int, pair<int, int> >, NodeID>::iterator derivative = first_order_endo_derivatives.find(make_pair(eq, make_pair(var, 0)));
+      pair<bool, NodeID> res;
+      if(derivative != first_order_endo_derivatives.end())
+        {
+          set<pair<int, int> > result;
+          derivative->second->collectEndogenous(result);
+          set<pair<int, int> >::const_iterator d_endo_variable = result.find(make_pair(var, 0));
+          //Determine whether the equation could be evaluated rather than to be solved
+          ostringstream tt("");
+          derivative->second->writeOutput(tt, oMatlabDynamicModelSparse, temporary_terms);
+          if (tmp_output.str() == tmp_s.str() and tt.str()=="1")
+            {
+              Equation_Simulation_Type = E_EVALUATE;
+            }
+          else
+            {
+        	    vector<pair<int, pair<NodeID, NodeID> > > List_of_Op_RHS;
+              res =  equations[eq]->normalizeEquation(var, List_of_Op_RHS);
+              if(mfs==2)
+                {
+                  if(d_endo_variable == result.end() && res.second)
+                    Equation_Simulation_Type = E_EVALUATE_S;
+                }
+              else if(mfs==3)
+                {
+                  if(res.second) // The equation could be solved analytically
+                    Equation_Simulation_Type = E_EVALUATE_S;
+                }
+            }
+        }
+      V_Equation_Simulation_Type[eq] = make_pair(Equation_Simulation_Type, dynamic_cast<BinaryOpNode *>(res.second));
+    }
+  return (V_Equation_Simulation_Type);
+}
+
+void
+ModelTree::getVariableLeadLagByBlock(dynamic_jacob_map &dynamic_jacobian, vector<int > &components_set, int nb_blck_sim, int prologue, int epilogue, t_lag_lead_vector &equation_lead_lag, t_lag_lead_vector &variable_lead_lag, vector<int> equation_reordered, vector<int> variable_reordered) const
+{
+  int nb_endo = symbol_table.endo_nbr();
+  variable_lead_lag = t_lag_lead_vector(nb_endo , make_pair(0,0));
+  equation_lead_lag = t_lag_lead_vector(nb_endo , make_pair(0,0));
+  vector<int> variable_blck(nb_endo), equation_blck(nb_endo);
+  for (int i = 0; i < nb_endo; i++)
+    {
+      if (i < prologue)
+        {
+          variable_blck[variable_reordered[i]] = i;
+          equation_blck[equation_reordered[i]] = i;
+        }
+      else if (i < (int)components_set.size() + prologue)
+        {
+          variable_blck[variable_reordered[i]] = components_set[i-prologue] + prologue;
+          equation_blck[equation_reordered[i]] = components_set[i-prologue] + prologue;
+        }
+      else
+        {
+          variable_blck[variable_reordered[i]] = i- (nb_endo - nb_blck_sim - prologue - epilogue);
+          equation_blck[equation_reordered[i]] = i- (nb_endo - nb_blck_sim - prologue - epilogue);
+        }
+    }
+  for (dynamic_jacob_map::const_iterator it = dynamic_jacobian.begin(); it != dynamic_jacobian.end(); it++)
+    {
+      int lag = it->first.first;
+      int j_1 = it->first.second.second;
+      int i_1 = it->first.second.second;
+      if (variable_blck[i_1] == equation_blck[j_1])
+        {
+          if (lag > variable_lead_lag[i_1].second)
+            variable_lead_lag[i_1] = make_pair(variable_lead_lag[i_1].first, lag);
+          if (lag < -variable_lead_lag[i_1].first)
+            variable_lead_lag[i_1] = make_pair(-lag, variable_lead_lag[i_1].second);
+          if (lag > equation_lead_lag[j_1].second)
+            equation_lead_lag[j_1] = make_pair(equation_lead_lag[j_1].first, lag);
+          if (lag < -equation_lead_lag[j_1].first)
+            equation_lead_lag[j_1] = make_pair(-lag, equation_lead_lag[j_1].second);
+        }
+    }
+}
+
+
+void
+ModelTree::computeBlockDecompositionAndFeedbackVariablesForEachBlock(jacob_map &static_jacobian, dynamic_jacob_map &dynamic_jacobian, int prologue, int epilogue, vector<int> &equation_reordered, vector<int> &variable_reordered, vector<pair<int, int> > &blocks, t_equation_type_and_normalized_equation &Equation_Type, bool verbose_, bool select_feedback_variable, int mfs, vector<int> &inv_equation_reordered, vector<int> &inv_variable_reordered) const
+{
+  int nb_var = variable_reordered.size();
+  int n = nb_var - prologue - epilogue;
+  typedef adjacency_list<vecS, vecS, directedS> DirectedGraph;
+
+  GraphvizDigraph G2(n);
+
+  vector<int> reverse_equation_reordered(nb_var), reverse_variable_reordered(nb_var);
+
+  for(int i=0; i<nb_var; i++)
+    {
+      reverse_equation_reordered[equation_reordered[i]] = i;
+      reverse_variable_reordered[variable_reordered[i]] = i;
+    }
+
+  for(jacob_map::const_iterator it = static_jacobian.begin(); it != static_jacobian.end(); it++)
+    if(   reverse_equation_reordered[it->first.first]>=prologue && reverse_equation_reordered[it->first.first]<nb_var - epilogue
+       && reverse_variable_reordered[it->first.second]>=prologue && reverse_variable_reordered[it->first.second]<nb_var - epilogue
+       && it->first.first != endo2eq[it->first.second])
+         add_edge(reverse_equation_reordered[it->first.first]-prologue, reverse_equation_reordered[endo2eq[it->first.second]]-prologue, G2);
+
+  vector<int> endo2block(num_vertices(G2)), discover_time(num_vertices(G2));
+
+  // Compute strongly connected components
+  int num = strong_components(G2, &endo2block[0]);
+
+  blocks = vector<pair<int, int> >(num, make_pair(0, 0));
+
+
+  // Create directed acyclic graph associated to the strongly connected components
+  typedef adjacency_list<vecS, vecS, directedS> DirectedGraph;
+  DirectedGraph dag(num);
+
+
+  for (unsigned int i = 0;i < num_vertices(G2);i++)
+    {
+      GraphvizDigraph::out_edge_iterator it_out, out_end;
+      GraphvizDigraph::vertex_descriptor vi = vertex(i, G2);
+      for (tie(it_out, out_end) = out_edges(vi, G2); it_out != out_end; ++it_out)
+        {
+          int t_b = endo2block[target(*it_out, G2)];
+          int s_b = endo2block[source(*it_out, G2)];
+          if (s_b != t_b)
+            add_edge(s_b, t_b, dag);
+        }
+    }
+
+  // Compute topological sort of DAG (ordered list of unordered SCC)
+  deque<int> ordered2unordered;
+  topological_sort(dag, front_inserter(ordered2unordered)); // We use a front inserter because topological_sort returns the inverse order
+
+  // Construct mapping from unordered SCC to ordered SCC
+  vector<int> unordered2ordered(num);
+  for(int i = 0; i < num; i++)
+    unordered2ordered[ordered2unordered[i]] = i;
+
+
+  //This vector contains for each block:
+  //   - first set = equations belonging to the block,
+  //   - second set = the feeback variables,
+  //   - third vector = the reordered non-feedback variables.
+  vector<pair<set<int>, pair<set<int>, vector<int> > > > components_set(num);
+  for (unsigned int i = 0; i < endo2block.size(); i++)
+    {
+      endo2block[i] = unordered2ordered[endo2block[i]];
+      blocks[endo2block[i]].first++;
+      components_set[endo2block[i]].first.insert(i);
+    }
+
+  t_lag_lead_vector equation_lag_lead, variable_lag_lead;
+
+  getVariableLeadLagByBlock(dynamic_jacobian, endo2block, num, prologue, epilogue, equation_lag_lead, variable_lag_lead, equation_reordered, variable_reordered);
+
+  vector<int> tmp_equation_reordered(equation_reordered), tmp_variable_reordered(variable_reordered);
+  int order = prologue;
+  //Add a loop on vertices which could not be normalized or vertices related to lead variables => force those vertices to belong to the feedback set
+  if(select_feedback_variable)
+    {
+      for (int i = 0; i < n; i++)
+        if (Equation_Type[equation_reordered[i+prologue]].first == E_SOLVE
+            or variable_lag_lead[variable_reordered[i+prologue]].second > 0 or variable_lag_lead[variable_reordered[i+prologue]].first > 0
+            or equation_lag_lead[equation_reordered[i+prologue]].second > 0 or equation_lag_lead[equation_reordered[i+prologue]].first > 0
+            or mfs == 0)
+          add_edge(i, i, G2);
+    }
+  else
+    {
+      for (int i = 0; i < n; i++)
+        if (Equation_Type[equation_reordered[i+prologue]].first == E_SOLVE || mfs == 0)
+          add_edge(i, i, G2);
+    }
+  //For each block, the minimum set of feedback variable is computed
+  // and the non-feedback variables are reordered to get
+  // a sub-recursive block without feedback variables
+
+  for (int i = 0; i < num; i++)
+    {
+      AdjacencyList_type G = GraphvizDigraph_2_AdjacencyList(G2, components_set[i].first);
+      set<int> feed_back_vertices;
+      //Print(G);
+      AdjacencyList_type G1 = Minimal_set_of_feedback_vertex(feed_back_vertices, G);
+      property_map<AdjacencyList_type, vertex_index_t>::type v_index = get(vertex_index, G);
+      components_set[i].second.first = feed_back_vertices;
+      blocks[i].second = feed_back_vertices.size();
+      vector<int> Reordered_Vertice;
+      Reorder_the_recursive_variables(G, feed_back_vertices, Reordered_Vertice);
+
+      //First we have the recursive equations conditional on feedback variables
+      for (vector<int>::iterator its = Reordered_Vertice.begin(); its != Reordered_Vertice.end(); its++)
+        {
+          equation_reordered[order] = tmp_equation_reordered[*its+prologue];
+          variable_reordered[order] = tmp_variable_reordered[*its+prologue];
+          order++;
+        }
+      components_set[i].second.second = Reordered_Vertice;
+      //Second we have the equations related to the feedback variables
+      for (set<int>::iterator its = feed_back_vertices.begin(); its != feed_back_vertices.end(); its++)
+        {
+          equation_reordered[order] = tmp_equation_reordered[v_index[vertex(*its, G)]+prologue];
+          variable_reordered[order] = tmp_variable_reordered[v_index[vertex(*its, G)]+prologue];
+          order++;
+        }
+    }
+  inv_equation_reordered = vector<int>(nb_var);
+  inv_variable_reordered = vector<int>(nb_var);
+  for(int i = 0; i < nb_var ; i++)
+    {
+      inv_variable_reordered[variable_reordered[i]] = i;
+      inv_equation_reordered[equation_reordered[i]] = i;
+    }
+}
+
+void ModelTree::printBlockDecomposition(vector<pair<int, int> > blocks)
+{
+  int largest_block = 0;
+  int Nb_SimulBlocks = 0;
+  int Nb_feedback_variable = 0;
+  unsigned int Nb_TotalBlocks = getNbBlocks();
+  for (unsigned int block = 0; block < Nb_TotalBlocks; block++)
+    {
+      BlockSimulationType simulation_type = getBlockSimulationType(block);
+      if (simulation_type == SOLVE_FORWARD_COMPLETE || simulation_type == SOLVE_BACKWARD_COMPLETE || simulation_type == SOLVE_TWO_BOUNDARIES_COMPLETE)
+        {
+          Nb_SimulBlocks++;
+          int size = getBlockSize(block);
+          if (size > largest_block)
+            {
+              largest_block = size;
+              Nb_feedback_variable = blocks[Nb_SimulBlocks-1].second;
+            }
+        }
+    }
+
+
+  int Nb_RecursBlocks = Nb_TotalBlocks - Nb_SimulBlocks;
+  cout << Nb_TotalBlocks << " block(s) found:" << endl
+       << "  " << Nb_RecursBlocks << " recursive block(s) and " << Nb_SimulBlocks << " simultaneous block(s)." << endl
+       << "  the largest simultaneous block has " << largest_block << " equation(s)" << endl
+       << "                                 and " << Nb_feedback_variable << " feedback variable(s)." << endl;
+}
+
+
+
+t_block_type_firstequation_size_mfs
+ModelTree::reduceBlocksAndTypeDetermination(dynamic_jacob_map &dynamic_jacobian, int prologue, int epilogue, vector<pair<int, int> > &blocks, vector<BinaryOpNode *> &equations, t_equation_type_and_normalized_equation &Equation_Type, vector<int> &variable_reordered, vector<int> &equation_reordered)
+{
+  int i = 0;
+  int count_equ = 0, blck_count_simult = 0;
+  int Blck_Size, MFS_Size;
+  int Lead, Lag;
+  t_block_type_firstequation_size_mfs block_type_size_mfs;
+  BlockSimulationType Simulation_Type, prev_Type = UNKNOWN;
+  int eq = 0;
+  for (i = 0; i < prologue+(int) blocks.size()+epilogue; i++)
+    {
+      int first_count_equ = count_equ;
+      if (i < prologue)
+        {
+          Blck_Size = 1;
+          MFS_Size = 1;
+        }
+      else if (i < prologue+(int) blocks.size())
+        {
+          Blck_Size = blocks[blck_count_simult].first;
+          MFS_Size = blocks[blck_count_simult].second;
+          blck_count_simult++;
+        }
+      else if (i < prologue+(int) blocks.size()+epilogue)
+        {
+          Blck_Size = 1;
+          MFS_Size = 1;
+        }
+
+      Lag = Lead = 0;
+      set<pair<int, int> > endo;
+      for(count_equ  = first_count_equ; count_equ  < Blck_Size+first_count_equ; count_equ++)
+        {
+          endo.clear();
+          equations[equation_reordered[count_equ]]->collectEndogenous(endo);
+          for (set<pair<int, int> >::const_iterator it = endo.begin(); it != endo.end(); it++)
+            {
+              int curr_variable = it->first;
+              int curr_lag = it->second;
+              vector<int>::const_iterator it = find(variable_reordered.begin()+first_count_equ, variable_reordered.begin()+(first_count_equ+Blck_Size), curr_variable);
+              if(it != variable_reordered.begin()+(first_count_equ+Blck_Size))
+                if (dynamic_jacobian.find(make_pair(curr_lag, make_pair(equation_reordered[count_equ], curr_variable))) != dynamic_jacobian.end())
+                  {
+                    if (curr_lag > Lead)
+                      Lead = curr_lag;
+                    else if (-curr_lag > Lag)
+                      Lag = -curr_lag;
+                  }
+            }
+        }
+      if ((Lag > 0) && (Lead > 0))
+        {
+          if (Blck_Size == 1)
+            Simulation_Type = SOLVE_TWO_BOUNDARIES_SIMPLE;
+          else
+            Simulation_Type = SOLVE_TWO_BOUNDARIES_COMPLETE;
+        }
+      else if (Blck_Size > 1)
+        {
+          if (Lead > 0)
+            Simulation_Type = SOLVE_BACKWARD_COMPLETE;
+          else
+            Simulation_Type = SOLVE_FORWARD_COMPLETE;
+        }
+      else
+        {
+          if (Lead > 0)
+            Simulation_Type = SOLVE_BACKWARD_SIMPLE;
+          else
+            Simulation_Type = SOLVE_FORWARD_SIMPLE;
+        }
+      if (Blck_Size == 1)
+        {
+          if (Equation_Type[equation_reordered[eq]].first == E_EVALUATE or Equation_Type[equation_reordered[eq]].first == E_EVALUATE_S)
+            {
+              if (Simulation_Type == SOLVE_BACKWARD_SIMPLE)
+                Simulation_Type = EVALUATE_BACKWARD;
+              else if (Simulation_Type == SOLVE_FORWARD_SIMPLE)
+                Simulation_Type = EVALUATE_FORWARD;
+            }
+          if (i > 0)
+            {
+              if ((prev_Type ==  EVALUATE_FORWARD and Simulation_Type == EVALUATE_FORWARD)
+                  or (prev_Type ==  EVALUATE_BACKWARD and Simulation_Type == EVALUATE_BACKWARD))
+                {
+                  //merge the current block with the previous one
+                  BlockSimulationType c_Type = (block_type_size_mfs[block_type_size_mfs.size()-1]).first.first;
+                  int c_Size = (block_type_size_mfs[block_type_size_mfs.size()-1]).second.first;
+                  int first_equation = (block_type_size_mfs[block_type_size_mfs.size()-1]).first.second;
+                  block_type_size_mfs[block_type_size_mfs.size()-1] = make_pair(make_pair(c_Type, first_equation), make_pair(++c_Size, block_type_size_mfs[block_type_size_mfs.size()-1].second.second));
+                  if(block_lag_lead[block_type_size_mfs.size()-1].first > Lag)
+                    Lag = block_lag_lead[block_type_size_mfs.size()-1].first;
+                  if(block_lag_lead[block_type_size_mfs.size()-1].second > Lead)
+                    Lead = block_lag_lead[block_type_size_mfs.size()-1].second;
+                  block_lag_lead[block_type_size_mfs.size()-1] = make_pair(Lag, Lead);
+                }
+              else
+                {
+                  block_type_size_mfs.push_back(make_pair(make_pair(Simulation_Type, eq), make_pair(Blck_Size, MFS_Size)));
+                  block_lag_lead.push_back(make_pair(Lag, Lead));
+                }
+            }
+          else
+            {
+              block_type_size_mfs.push_back(make_pair(make_pair(Simulation_Type, eq), make_pair(Blck_Size, MFS_Size)));
+              block_lag_lead.push_back(make_pair(Lag, Lead));
+            }
+        }
+      else
+        {
+          block_type_size_mfs.push_back(make_pair(make_pair(Simulation_Type, eq), make_pair(Blck_Size, MFS_Size)));
+          block_lag_lead.push_back(make_pair(Lag, Lead));
+        }
+      prev_Type = Simulation_Type;
+      eq += Blck_Size;
+    }
+  return (block_type_size_mfs);
+}
+
+
+vector<bool>
+ModelTree::BlockLinear(t_blocks_derivatives &blocks_derivatives, vector<int> &variable_reordered)
+{
+  unsigned int nb_blocks = getNbBlocks();
+  vector<bool> blocks_linear(nb_blocks, true);
+  for (unsigned int block = 0;block < nb_blocks; block++)
+    {
+      BlockSimulationType simulation_type = getBlockSimulationType(block);
+      int block_size = getBlockSize(block);
+      t_block_derivatives_equation_variable_laglead_nodeid derivatives_block = blocks_derivatives[block];
+      int first_variable_position = getBlockFirstEquation(block);
+      if (simulation_type==SOLVE_BACKWARD_COMPLETE || simulation_type==SOLVE_FORWARD_COMPLETE)
+        {
+          for (t_block_derivatives_equation_variable_laglead_nodeid::const_iterator it = derivatives_block.begin(); it != derivatives_block.end(); it++)
+            {
+              int lag = it->second.first;
+              if (lag == 0)
+                {
+                  NodeID Id = it->second.second;
+                  set<pair<int, int> > endogenous;
+                  Id->collectEndogenous(endogenous);
+                  if (endogenous.size() > 0)
+                    {
+                      for (int l=0;l<block_size;l++)
+                        {
+                          if (endogenous.find(make_pair(variable_reordered[first_variable_position+l], 0)) != endogenous.end())
+                            {
+                              blocks_linear[block] = false;
+                              goto the_end;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+      else if (simulation_type==SOLVE_TWO_BOUNDARIES_COMPLETE || simulation_type==SOLVE_TWO_BOUNDARIES_SIMPLE)
+        {
+          for (t_block_derivatives_equation_variable_laglead_nodeid::const_iterator it = derivatives_block.begin(); it != derivatives_block.end(); it++)
+            {
+              int lag = it->second.first;
+              NodeID Id = it->second.second;//
+              set<pair<int, int> > endogenous;
+              Id->collectEndogenous(endogenous);
+              if (endogenous.size() > 0)
+                {
+                  for (int l=0;l<block_size;l++)
+                    {
+                      if (endogenous.find(make_pair(variable_reordered[first_variable_position+l], lag)) != endogenous.end())
+                        {
+                          blocks_linear[block] = false;
+                          goto the_end;
+                        }
+                    }
+                }
+            }
+        }
+the_end:;
+    }
+  return(blocks_linear);
+}
+
+
 
 ModelTree::ModelTree(SymbolTable &symbol_table_arg,
                      NumericalConstants &num_constants_arg) :
diff --git a/ModelTree.hh b/ModelTree.hh
index aa2e4c1866c936eb102f1ee3ca748fc943378ce5..e20e8b9e863f8dffe07a2f8d52a3aff8703033f3 100644
--- a/ModelTree.hh
+++ b/ModelTree.hh
@@ -30,9 +30,28 @@ using namespace std;
 
 #include "DataTree.hh"
 
+
+//! Vector describing equations: BlockSimulationType, if BlockSimulationType == EVALUATE_s then a NodeID on the new normalized equation
+typedef vector<pair<EquationType, NodeID > > t_equation_type_and_normalized_equation;
+
+//! Vector describing variables: max_lag in the block, max_lead in the block
+typedef vector<pair< int, int> > t_lag_lead_vector;
+
+//! for each block contains pair< pair<Simulation_Type, first_equation>, pair < Block_Size, Recursive_part_Size > >
+typedef vector<pair< pair< BlockSimulationType, int> , pair<int, int> > > t_block_type_firstequation_size_mfs;
+
+//! for a block contains derivatives pair< pair<block_equation_number, block_variable_number> , pair<lead_lag, NodeID> >
+typedef vector< pair<pair<int, int> , pair< int, NodeID > > > t_block_derivatives_equation_variable_laglead_nodeid;
+
+//! for all blocks derivatives description
+typedef vector<t_block_derivatives_equation_variable_laglead_nodeid> t_blocks_derivatives;
+
 //! Shared code for static and dynamic models
 class ModelTree : public DataTree
 {
+  friend class DynamicModel;
+  friend class StaticModel;
+
 protected:
   //! Stores declared and generated auxiliary equations
   vector<BinaryOpNode *> equations;
@@ -100,6 +119,96 @@ protected:
   //! Writes LaTeX model file
   void writeLatexModelFile(const string &filename, ExprNodeOutputType output_type) const;
 
+  //! Sparse matrix of double to store the values of the Jacobian
+  /*! First index is equation number, second index is endogenous type specific ID */
+  typedef map<pair<int, int>, double> jacob_map;
+
+  //! Sparse matrix of double to store the values of the Jacobian
+  /*! First index is lag, second index is equation number, third index is endogenous type specific ID */
+  typedef map<pair<int, pair<int, int> >, NodeID> dynamic_jacob_map;
+
+  //! Normalization of equations
+  /*! Maps endogenous type specific IDs to equation numbers */
+  vector<int> endo2eq;
+
+  //! number of equation in the prologue and in the epilogue
+  unsigned int epilogue, prologue;
+
+  //! for each block contains pair< max_lag, max_lead>
+  t_lag_lead_vector block_lag_lead;
+
+  //! Exception thrown when normalization fails
+  class NormalizationException
+  {
+  public:
+    //! A variable missing from the maximum cardinal matching
+    int symb_id;
+    NormalizationException(int symb_id_arg) : symb_id(symb_id_arg) { }
+  };
+
+  //! Compute the matching between endogenous and variable using the jacobian contemporaneous_jacobian
+  /*! \param endo_eqs_incidence A set indicating which endogenous appear in which equation. First element of pairs is equation number, second is type specific endo ID */
+  void computeNormalization(const set<pair<int, int> > &endo_eqs_incidence) throw (NormalizationException);
+  //! Try to compute the matching between endogenous and variable using a decreasing cutoff
+  /*! applied to the jacobian contemporaneous_jacobian and stop when a matching is found.*/
+  /*! if no matching is found with a cutoff close to zero an error message is printout */
+  void computePossiblySingularNormalization(const jacob_map &contemporaneous_jacobian, bool try_symbolic);
+  //! Try to normalized each unnormalized equation (matched endogenous variable only on the LHS)
+  void computeNormalizedEquations(multimap<int, int> &endo2eqs) const;
+  //! Evaluate the jacobian and suppress all the elements below the cutoff
+  void evaluateAndReduceJacobian(const eval_context_type &eval_context, jacob_map &contemporaneous_jacobian, jacob_map &static_jacobian, dynamic_jacob_map &dynamic_jacobian, double cutoff, bool verbose);
+  //! Search the equations and variables belonging to the prologue and the epilogue of the model
+  void computePrologueAndEpilogue(jacob_map &static_jacobian, vector<int> &equation_reordered, vector<int> &variable_reordered, unsigned int &prologue, unsigned int &epilogue);
+  //! Determine the type of each equation of model and try to normalized the unnormalized equation using computeNormalizedEquations
+  t_equation_type_and_normalized_equation equationTypeDetermination(vector<BinaryOpNode *> &equations, map<pair<int, pair<int, int> >, NodeID> &first_order_endo_derivatives, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM, int mfs);
+  //! Compute the block decomposition and for a non-recusive block find the minimum feedback set
+  void computeBlockDecompositionAndFeedbackVariablesForEachBlock(jacob_map &static_jacobian, dynamic_jacob_map &dynamic_jacobian, int prologue, int epilogue, vector<int> &Index_Equ_IM, vector<int> &Index_Var_IM, vector<pair<int, int> > &blocks, t_equation_type_and_normalized_equation &Equation_Type, bool verbose_, bool select_feedback_variable, int mfs, vector<int> &inv_equation_reordered, vector<int> &inv_variable_reordered) const;
+  //! Reduce the number of block merging the same type equation in the prologue and the epilogue and determine the type of each block
+  t_block_type_firstequation_size_mfs reduceBlocksAndTypeDetermination(dynamic_jacob_map &dynamic_jacobian, int prologue, int epilogue, vector<pair<int, int> > &blocks, vector<BinaryOpNode *> &equations, t_equation_type_and_normalized_equation &Equation_Type, vector<int> &Index_Var_IM, vector<int> &Index_Equ_IM);
+  //! Determine the maximum number of lead and lag for the endogenous variable in a bloc
+  void getVariableLeadLagByBlock(dynamic_jacob_map &dynamic_jacobian, vector<int > &components_set, int nb_blck_sim, int prologue, int epilogue, t_lag_lead_vector &equation_lead_lag, t_lag_lead_vector &variable_lead_lag, vector<int> equation_reordered, vector<int> variable_reordered) const;
+  //! Print an abstract of the block structure of the model
+  void printBlockDecomposition(vector<pair<int, int> > blocks);
+  //! Determine for each block if it is linear or not
+  vector<bool> BlockLinear(t_blocks_derivatives &blocks_derivatives, vector<int> &variable_reordered);
+
+
+  virtual SymbolType getTypeByDerivID(int deriv_id) const throw (UnknownDerivIDException) = 0;
+  virtual int getLagByDerivID(int deriv_id) const throw (UnknownDerivIDException) = 0;
+  virtual int getSymbIDByDerivID(int deriv_id) const throw (UnknownDerivIDException) = 0;
+
+  //! Determine the simulation type of each block
+  virtual BlockSimulationType getBlockSimulationType(int block_number) const = 0;
+  //! Return the number of blocks
+  virtual unsigned int getNbBlocks() const = 0;
+  //! Return the first equation number of a block
+  virtual unsigned int getBlockFirstEquation(int block_number) const = 0;
+  //! Return the size of the block block_number
+  virtual unsigned int getBlockSize(int block_number) const = 0;
+  //! Return the number of feedback variable of the block block_number
+  virtual unsigned int getBlockMfs(int block_number) const = 0;
+  //! Return the maximum lag in a block
+  virtual unsigned int getBlockMaxLag(int block_number) const = 0;
+  //! Return the maximum lead in a block
+  virtual unsigned int getBlockMaxLead(int block_number) const = 0;
+  //! Return the type of equation (equation_number) belonging to the block block_number
+  virtual EquationType getBlockEquationType(int block_number, int equation_number) const = 0;
+  //! Return true if the equation has been normalized
+  virtual bool isBlockEquationRenormalized(int block_number, int equation_number) const = 0;
+  //! Return the NodeID of the equation equation_number belonging to the block block_number
+  virtual NodeID getBlockEquationNodeID(int block_number, int equation_number) const = 0;
+  //! Return the NodeID of the renormalized equation equation_number belonging to the block block_number
+  virtual NodeID getBlockEquationRenormalizedNodeID(int block_number, int equation_number) const = 0;
+  //! Return the original number of equation equation_number belonging to the block block_number
+  virtual int getBlockEquationID(int block_number, int equation_number) const = 0;
+  //! Return the original number of variable variable_number belonging to the block block_number
+  virtual int getBlockVariableID(int block_number, int variable_number) const = 0;
+  //! Return the position of equation_number in the block number belonging to the block block_number
+  virtual int getBlockInitialEquationID(int block_number, int equation_number) const = 0;
+  //! Return the position of variable_number in the block number belonging to the block block_number
+  virtual int getBlockInitialVariableID(int block_number, int variable_number) const = 0;
+
+
 public:
   ModelTree(SymbolTable &symbol_table_arg, NumericalConstants &num_constants);
   //! Declare a node as an equation of the model
@@ -110,6 +219,74 @@ public:
   void addAuxEquation(NodeID eq);
   //! Returns the number of equations in the model
   int equation_number() const;
+
+  inline static std::string c_Equation_Type(int type)
+   {
+     char c_Equation_Type[4][13]=
+     {
+     "E_UNKNOWN   ",
+     "E_EVALUATE  ",
+     "E_EVALUATE_S",
+     "E_SOLVE     "
+     };
+   return(c_Equation_Type[type]);
+   };
+
+  inline static std::string BlockType0(BlockType type)
+    {
+      switch (type)
+        {
+        case SIMULTANS:
+          return ("SIMULTANEOUS TIME SEPARABLE  ");
+          break;
+        case PROLOGUE:
+          return ("PROLOGUE                     ");
+          break;
+        case EPILOGUE:
+          return ("EPILOGUE                     ");
+          break;
+        case SIMULTAN:
+          return ("SIMULTANEOUS TIME UNSEPARABLE");
+          break;
+        default:
+          return ("UNKNOWN                      ");
+          break;
+        }
+   };
+
+ inline static std::string BlockSim(int type)
+   {
+     switch (type)
+       {
+       case EVALUATE_FORWARD:
+         return ("EVALUATE FORWARD             ");
+         break;
+       case EVALUATE_BACKWARD:
+         return ("EVALUATE BACKWARD            ");
+         break;
+       case SOLVE_FORWARD_SIMPLE:
+         return ("SOLVE FORWARD SIMPLE         ");
+         break;
+       case SOLVE_BACKWARD_SIMPLE:
+         return ("SOLVE BACKWARD SIMPLE        ");
+         break;
+       case SOLVE_TWO_BOUNDARIES_SIMPLE:
+         return ("SOLVE TWO BOUNDARIES SIMPLE  ");
+         break;
+       case SOLVE_FORWARD_COMPLETE:
+         return ("SOLVE FORWARD COMPLETE       ");
+         break;
+       case SOLVE_BACKWARD_COMPLETE:
+         return ("SOLVE BACKWARD COMPLETE      ");
+         break;
+       case SOLVE_TWO_BOUNDARIES_COMPLETE:
+         return ("SOLVE TWO BOUNDARIES COMPLETE");
+         break;
+       default:
+         return ("UNKNOWN                      ");
+         break;
+       }
+   };
 };
 
 #endif
diff --git a/ParsingDriver.cc b/ParsingDriver.cc
index 95641aef3353062d1d8b5a3d7a019db7d2404b58..72b636504996b030e8733c9c13b2ef044a5bc6c3 100644
--- a/ParsingDriver.cc
+++ b/ParsingDriver.cc
@@ -377,7 +377,7 @@ ParsingDriver::cutoff(string *value)
 {
   double val = atof(value->c_str());
   mod_file->dynamic_model.cutoff = val;
-  mod_file->static_dll_model.cutoff = val;
+  mod_file->static_model.cutoff = val;
   delete value;
 }
 
@@ -386,7 +386,7 @@ ParsingDriver::mfs(string *value)
 {
   int val = atoi(value->c_str());
   mod_file->dynamic_model.mfs = val;
-  mod_file->static_dll_model.mfs = val;
+  mod_file->static_model.mfs = val;
   delete value;
 }
 
@@ -731,9 +731,6 @@ ParsingDriver::option_num(const string &name_option, const string &opt)
   if (options_list.num_options.find(name_option) != options_list.num_options.end())
     error("option " + name_option + " declared twice");
 
-  if ((name_option == "periods") && mod_file->block)
-    mod_file->dynamic_model.block_triangular.periods = atoi(opt.c_str());
-
   options_list.num_options[name_option] = opt;
 }
 
diff --git a/StaticDllModel.cc b/StaticDllModel.cc
deleted file mode 100644
index a07bebc85314843c21a962b90603c6e768f99cd2..0000000000000000000000000000000000000000
--- a/StaticDllModel.cc
+++ /dev/null
@@ -1,1050 +0,0 @@
-/*
- * Copyright (C) 2003-2009 Dynare Team
- *
- * This file is part of Dynare.
- *
- * Dynare is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Dynare is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <iostream>
-#include <cmath>
-#include <cstdlib>
-#include <cassert>
-#include <cstdio>
-#include <cerrno>
-#include "StaticDllModel.hh"
-
-// For mkdir() and chdir()
-#ifdef _WIN32
-# include <direct.h>
-#else
-# include <unistd.h>
-# include <sys/stat.h>
-# include <sys/types.h>
-#endif
-
-StaticDllModel::StaticDllModel(SymbolTable &symbol_table_arg,
-                           NumericalConstants &num_constants_arg) :
-    ModelTree(symbol_table_arg, num_constants_arg),
-    cutoff(1e-15),
-    mfs(0),
-    block_triangular(symbol_table_arg, num_constants_arg)
-{
-}
-
-void
-StaticDllModel::compileDerivative(ofstream &code_file, int eq, int symb_id, int lag, map_idx_type &map_idx) const
-{
-  //first_derivatives_type::const_iterator it = first_derivatives.find(make_pair(eq, getDerivID(symb_id, lag)));
-  //first_derivatives_type::const_iterator it = first_derivatives.find(make_pair(eq, getDerivID(symbol_table.getID(eEndogenous, symb_id), lag)));
-  first_derivatives_type::const_iterator it = first_derivatives.find(make_pair(eq, symbol_table.getID(eEndogenous, symb_id)));
-  if (it != first_derivatives.end())
-    (it->second)->compile(code_file, false, temporary_terms, map_idx, false, false);
-  else
-    {
-      FLDZ_ fldz;
-      fldz.write(code_file);
-    }
-}
-
-
-void
-StaticDllModel::compileChainRuleDerivative(ofstream &code_file, int eqr, int varr, int lag, map_idx_type &map_idx) const
-{
-  map<pair<int, pair<int, int> >, NodeID>::const_iterator it = first_chain_rule_derivatives.find(make_pair(eqr, make_pair(varr, lag)));
-  if (it != first_chain_rule_derivatives.end())
-    (it->second)->compile(code_file, false, temporary_terms, map_idx, false, false);
-  else
-    {
-      FLDZ_ fldz;
-      fldz.write(code_file);
-    }
-}
-
-
-void
-StaticDllModel::BuildIncidenceMatrix()
-{
-  set<pair<int, int> > endogenous, exogenous;
-  for (int eq = 0; eq < (int) equations.size(); eq++)
-    {
-      BinaryOpNode *eq_node = equations[eq];
-      endogenous.clear();
-      NodeID Id = eq_node->get_arg1();
-      Id->collectEndogenous(endogenous);
-      Id = eq_node->get_arg2();
-      Id->collectEndogenous(endogenous);
-      for (set<pair<int, int> >::iterator it_endogenous=endogenous.begin();it_endogenous!=endogenous.end();it_endogenous++)
-        {
-          block_triangular.incidencematrix.fill_IM(eq, it_endogenous->first, 0, eEndogenous);
-        }
-      exogenous.clear();
-      Id = eq_node->get_arg1();
-      Id->collectExogenous(exogenous);
-      Id = eq_node->get_arg2();
-      Id->collectExogenous(exogenous);
-      for (set<pair<int, int> >::iterator it_exogenous=exogenous.begin();it_exogenous!=exogenous.end();it_exogenous++)
-        {
-          block_triangular.incidencematrix.fill_IM(eq, it_exogenous->first, 0, eExogenous);
-        }
-    }
-}
-
-void
-StaticDllModel::computeTemporaryTermsOrdered(Model_Block *ModelBlock)
-{
-  map<NodeID, pair<int, int> > first_occurence;
-  map<NodeID, int> reference_count;
-  int i, j, eqr, varr, lag;
-  temporary_terms_type vect;
-  ostringstream tmp_output;
-  BinaryOpNode *eq_node;
-  first_derivatives_type::const_iterator it;
-  first_chain_rule_derivatives_type::const_iterator it_chr;
-  ostringstream tmp_s;
-
-  temporary_terms.clear();
-  map_idx.clear();
-  for (j = 0;j < ModelBlock->Size;j++)
-    {
-      // Compute the temporary terms reordered
-      for (i = 0;i < ModelBlock->Block_List[j].Size;i++)
-        {
-          if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE_S && i<ModelBlock->Block_List[j].Nb_Recursives && ModelBlock->Block_List[j].Equation_Normalized[i])
-              ModelBlock->Block_List[j].Equation_Normalized[i]->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, j, ModelBlock, i, map_idx);
-					else
-					  {
-					  	eq_node = equations[ModelBlock->Block_List[j].Equation[i]];
-              eq_node->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, j, ModelBlock, i, map_idx);
-					  }
-        }
-			for(i=0; i<(int)ModelBlock->Block_List[j].Chain_Rule_Derivatives->size();i++)
-				{
-          pair< pair<int, pair<int, int> >, pair<int, int> > it = ModelBlock->Block_List[j].Chain_Rule_Derivatives->at(i);
-          lag=it.first.first;
-          int eqr=it.second.first;
-          int varr=it.second.second;
-          it_chr=first_chain_rule_derivatives.find(make_pair(eqr, make_pair( varr, lag)));
-          it_chr->second->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, j, ModelBlock, ModelBlock->Block_List[j].Size-1, map_idx);
-				}
-
-    }
-  for (j = 0;j < ModelBlock->Size;j++)
-    {
-      // Collecte the temporary terms reordered
-      for (i = 0;i < ModelBlock->Block_List[j].Size;i++)
-        {
-        	if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE_S && i<ModelBlock->Block_List[j].Nb_Recursives && ModelBlock->Block_List[j].Equation_Normalized[i])
-              ModelBlock->Block_List[j].Equation_Normalized[i]->collectTemporary_terms(temporary_terms, ModelBlock, j);
-					else
-					  {
-					  	eq_node = equations[ModelBlock->Block_List[j].Equation[i]];
-              eq_node->collectTemporary_terms(temporary_terms, ModelBlock, j);
-					  }
-
-        }
-			for(i=0; i<(int)ModelBlock->Block_List[j].Chain_Rule_Derivatives->size();i++)
-        {
-          pair< pair<int, pair<int, int> >, pair<int, int> > it = ModelBlock->Block_List[j].Chain_Rule_Derivatives->at(i);
-          lag=it.first.first;
-          eqr=it.second.first;
-          varr=it.second.second;
-          it_chr=first_chain_rule_derivatives.find(make_pair(eqr, make_pair( varr, lag)));
-          it_chr->second->collectTemporary_terms(temporary_terms, ModelBlock, j);
-        }
-    }
-  // Add a mapping form node ID to temporary terms order
-  j=0;
-  for (temporary_terms_type::const_iterator it = temporary_terms.begin();
-       it != temporary_terms.end(); it++)
-    map_idx[(*it)->idx]=j++;
-}
-
-void
-StaticDllModel::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const string &static_basename) const
-  {
-    int i,j,k,m;
-    string tmp_s, sps;
-    ostringstream tmp_output, tmp1_output, global_output;
-    NodeID lhs=NULL, rhs=NULL;
-    BinaryOpNode *eq_node;
-    map<NodeID, int> reference_count;
-    ofstream  output;
-    int nze, nze_exo, nze_other_endo;
-    vector<int> feedback_variables;
-    //For each block
-    for (j = 0;j < ModelBlock->Size;j++)
-      {
-        //recursive_variables.clear();
-        feedback_variables.clear();
-        //For a block composed of a single equation determines wether we have to evaluate or to solve the equation
-        nze = nze_exo = nze_other_endo = 0;
-        for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++)
-          nze+=ModelBlock->Block_List[j].IM_lead_lag[m].size;
-        tmp1_output.str("");
-        tmp1_output << static_basename << "_" << j+1 << ".m";
-        output.open(tmp1_output.str().c_str(), ios::out | ios::binary);
-        output << "%\n";
-        output << "% " << tmp1_output.str() << " : Computes static model for Dynare\n";
-        output << "%\n";
-        output << "% Warning : this file is generated automatically by Dynare\n";
-        output << "%           from model file (.mod)\n\n";
-        output << "%/\n";
-        if (ModelBlock->Block_List[j].Simulation_Type==EVALUATE_BACKWARD
-            ||ModelBlock->Block_List[j].Simulation_Type==EVALUATE_FORWARD)
-          output << "function y = " << static_basename << "_" << j+1 << "(y, x, params)\n";
-        else if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_FORWARD_COMPLETE
-                 ||   ModelBlock->Block_List[j].Simulation_Type==SOLVE_BACKWARD_COMPLETE
-                 ||   ModelBlock->Block_List[j].Simulation_Type==SOLVE_BACKWARD_SIMPLE
-                 ||   ModelBlock->Block_List[j].Simulation_Type==SOLVE_FORWARD_SIMPLE)
-          output << "function [residual, y, g1] = " << static_basename << "_" << j+1 << "(y, x, params)\n";
-        output << "  % ////////////////////////////////////////////////////////////////////////" << endl
-        << "  % //" << string("                     Block ").substr(int(log10(j + 1))) << j + 1 << " " << BlockTriangular::BlockType0(ModelBlock->Block_List[j].Type)
-        << "          //" << endl
-        << "  % //                     Simulation type "
-        << BlockTriangular::BlockSim(ModelBlock->Block_List[j].Simulation_Type) << "  //" << endl
-        << "  % ////////////////////////////////////////////////////////////////////////" << endl;
-        //The Temporary terms
-        if (ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_BACKWARD
-            && ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_FORWARD)
-          output << "    g1 = spalloc(" << ModelBlock->Block_List[j].Size-ModelBlock->Block_List[j].Nb_Recursives
-                 << ", " << ModelBlock->Block_List[j].Size-ModelBlock->Block_List[j].Nb_Recursives << ", " << nze << ");\n";
-
-        if (ModelBlock->Block_List[j].Temporary_InUse->size())
-          {
-            tmp_output.str("");
-            for (temporary_terms_inuse_type::const_iterator it = ModelBlock->Block_List[j].Temporary_InUse->begin();
-                 it != ModelBlock->Block_List[j].Temporary_InUse->end(); it++)
-              tmp_output << " T" << *it;
-            output << "  global" << tmp_output.str() << ";\n";
-          }
-        if (ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_BACKWARD && ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_FORWARD)
-          output << "  residual=zeros(" << ModelBlock->Block_List[j].Size-ModelBlock->Block_List[j].Nb_Recursives << ",1);\n";
-        // The equations
-        for (i = 0;i < ModelBlock->Block_List[j].Size;i++)
-          {
-            temporary_terms_type tt2;
-            tt2.clear();
-            if (ModelBlock->Block_List[j].Temporary_Terms_in_Equation[i]->size())
-              output << "  " << sps << "% //Temporary variables" << endl;
-            for (temporary_terms_type::const_iterator it = ModelBlock->Block_List[j].Temporary_Terms_in_Equation[i]->begin();
-                 it != ModelBlock->Block_List[j].Temporary_Terms_in_Equation[i]->end(); it++)
-              {
-                output << "  " <<  sps;
-                (*it)->writeOutput(output, oMatlabStaticModelSparse, temporary_terms);
-                output << " = ";
-                (*it)->writeOutput(output, oMatlabStaticModelSparse, tt2);
-                // Insert current node into tt2
-                tt2.insert(*it);
-                output << ";" << endl;
-              }
-            string sModel = symbol_table.getName(symbol_table.getID(eEndogenous, ModelBlock->Block_List[j].Variable[i])) ;
-            eq_node = equations[ModelBlock->Block_List[j].Equation[i]];
-            lhs = eq_node->get_arg1();
-            rhs = eq_node->get_arg2();
-            tmp_output.str("");
-            /*if((ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_BACKWARD or ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_FORWARD) and (i<ModelBlock->Block_List[j].Nb_Recursives))
-              lhs->writeOutput(tmp_output, oMatlabStaticModelSparse, temporary_terms);
-            else*/
-						lhs->writeOutput(tmp_output, oMatlabStaticModelSparse, temporary_terms);
-            switch (ModelBlock->Block_List[j].Simulation_Type)
-              {
-              case EVALUATE_BACKWARD:
-              case EVALUATE_FORWARD:
-evaluation:     if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_COMPLETE || ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_SIMPLE)
-                  output << "    % equation " << ModelBlock->Block_List[j].Equation[i]+1 << " variable : " << sModel
-                  << " (" << ModelBlock->Block_List[j].Variable[i]+1 << ") " << block_triangular.c_Equation_Type(ModelBlock->Block_List[j].Equation_Type[i]) << endl;
-                output << "    ";
-                if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE)
-                  {
-                    output << tmp_output.str();
-                    output << " = ";
-  									rhs->writeOutput(output, oMatlabStaticModelSparse, temporary_terms);
-                  }
-                else if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE_S)
-                  {
-                    output << "%" << tmp_output.str();
-                    output << " = ";
-                    if (ModelBlock->Block_List[j].Equation_Normalized[i])
-                      {
-                        rhs->writeOutput(output, oMatlabStaticModelSparse, temporary_terms);
-                        output << "\n    ";
-                        tmp_output.str("");
-                        eq_node = (BinaryOpNode *)ModelBlock->Block_List[j].Equation_Normalized[i];
-                        lhs = eq_node->get_arg1();
-                        rhs = eq_node->get_arg2();
-                        lhs->writeOutput(output, oMatlabStaticModelSparse, temporary_terms);
-                        output << " = ";
-											  rhs->writeOutput(output, oMatlabStaticModelSparse, temporary_terms);
-                      }
-                  }
-                else
-                  {
-                    cerr << "Type missmatch for equation " << ModelBlock->Block_List[j].Equation[i]+1  << "\n";
-                    exit(EXIT_FAILURE);
-                  }
-                output << ";\n";
-                break;
-              case SOLVE_BACKWARD_SIMPLE:
-              case SOLVE_FORWARD_SIMPLE:
-              case SOLVE_BACKWARD_COMPLETE:
-              case SOLVE_FORWARD_COMPLETE:
-                if (i<ModelBlock->Block_List[j].Nb_Recursives)
-                  goto evaluation;
-                feedback_variables.push_back(ModelBlock->Block_List[j].Variable[i]);
-                output << "  % equation " << ModelBlock->Block_List[j].Equation[i]+1 << " variable : " << sModel
-                << " (" << ModelBlock->Block_List[j].Variable[i]+1 << ") " << block_triangular.c_Equation_Type(ModelBlock->Block_List[j].Equation_Type[i]) << endl;
-                output << "  " << "residual(" << i+1-ModelBlock->Block_List[j].Nb_Recursives << ") = (";
-                goto end;
-              default:
-end:
-                output << tmp_output.str();
-                output << ") - (";
-                rhs->writeOutput(output, oMatlabStaticModelSparse, temporary_terms);
-                output << ");\n";
-              }
-          }
-        // The Jacobian if we have to solve the block
-        output << "  " << sps << "% Jacobian  " << endl;
-        switch (ModelBlock->Block_List[j].Simulation_Type)
-          {
-          case EVALUATE_BACKWARD:
-          case EVALUATE_FORWARD:
-            break;
-          case SOLVE_BACKWARD_SIMPLE:
-          case SOLVE_FORWARD_SIMPLE:
-          case SOLVE_BACKWARD_COMPLETE:
-          case SOLVE_FORWARD_COMPLETE:
-            for(i=0; i<(int)ModelBlock->Block_List[j].Chain_Rule_Derivatives->size();i++)
-              {
-                pair< pair<int, pair<int, int> >, pair<int, int> > it = ModelBlock->Block_List[j].Chain_Rule_Derivatives->at(i);
-                k=it.first.first;
-                int eq=it.first.second.first;
-                int var=it.first.second.second;
-                int eqr=it.second.first;
-                int varr=it.second.second;
-                output << "    g1(" << eq+1-ModelBlock->Block_List[j].Nb_Recursives << ", "
-                       << var+1-ModelBlock->Block_List[j].Nb_Recursives  << ") = ";
-                writeChainRuleDerivative(output, eqr, varr, k, oMatlabStaticModelSparse, temporary_terms);
-                output << "; % variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, varr))
-                       << " " << varr+1 << ", equation=" << eqr+1 << endl;
-              }
-            break;
-          default:
-            break;
-          }
-        output.close();
-      }
-  }
-
-void
-StaticDllModel::writeModelEquationsCodeOrdered(const string file_name, const Model_Block *ModelBlock, const string bin_basename, map_idx_type map_idx) const
-  {
-    struct Uff_l
-      {
-        int u, var, lag;
-        Uff_l *pNext;
-      };
-
-    struct Uff
-      {
-        Uff_l *Ufl, *Ufl_First;
-      };
-
-    int i,j,k,v;
-    string tmp_s;
-    ostringstream tmp_output;
-    ofstream code_file;
-    NodeID lhs=NULL, rhs=NULL;
-    BinaryOpNode *eq_node;
-    Uff Uf[symbol_table.endo_nbr()];
-    map<NodeID, int> reference_count;
-    vector<int> feedback_variables;
-    bool file_open=false;
-    string main_name=file_name;
-    main_name+=".cod";
-    code_file.open(main_name.c_str(), ios::out | ios::binary | ios::ate );
-    if (!code_file.is_open())
-      {
-        cout << "Error : Can't open file \"" << main_name << "\" for writing\n";
-        exit(EXIT_FAILURE);
-      }
-    //Temporary variables declaration
-    FDIMT_ fdimt(temporary_terms.size());
-    fdimt.write(code_file);
-
-    for (j = 0; j < ModelBlock->Size ;j++)
-      {
-        feedback_variables.clear();
-        if (j>0)
-          {
-            FENDBLOCK_ fendblock;
-            fendblock.write(code_file);
-          }
-        int count_u;
-
-        int u_count_int=0;
-        if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_BACKWARD_COMPLETE || ModelBlock->Block_List[j].Simulation_Type==SOLVE_FORWARD_COMPLETE)
-          {
-            Write_Inf_To_Bin_File(file_name, bin_basename, j, u_count_int,file_open);
-            file_open=true;
-          }
-
-        FBEGINBLOCK_ fbeginblock(ModelBlock->Block_List[j].Size - ModelBlock->Block_List[j].Nb_Recursives,
-                                 ModelBlock->Block_List[j].Simulation_Type,
-                                 ModelBlock->Block_List[j].Variable,
-                                 ModelBlock->Block_List[j].Equation,
-                                 ModelBlock->Block_List[j].Own_Derivative,
-                                 ModelBlock->Block_List[j].is_linear,
-                                 symbol_table.endo_nbr(),
-                                 0,
-                                 0,
-                                 u_count_int
-                                 );
-        fbeginblock.write(code_file);
-            // The equations
-            //cout << block_triangular.BlockSim(ModelBlock->Block_List[j].Simulation_Type) << "  j=" << j << endl;
-            for (i = 0;i < ModelBlock->Block_List[j].Size;i++)
-              {
-                //The Temporary terms
-                temporary_terms_type tt2;
-                tt2.clear();
-                for (temporary_terms_type::const_iterator it = ModelBlock->Block_List[j].Temporary_Terms_in_Equation[i]->begin();
-                     it != ModelBlock->Block_List[j].Temporary_Terms_in_Equation[i]->end(); it++)
-                  {
-                    (*it)->compile(code_file, false, tt2, map_idx, false, false);
-                    FSTPST_ fstpst((int)(map_idx.find((*it)->idx))->second);
-                    fstpst.write(code_file);
-                    // Insert current node into tt2
-                    tt2.insert(*it);
-                  }
-                switch (ModelBlock->Block_List[j].Simulation_Type)
-                  {
-evaluation:
-                  case EVALUATE_BACKWARD:
-                  case EVALUATE_FORWARD:
-                    if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE)
-                      {
-                      	eq_node = equations[ModelBlock->Block_List[j].Equation[i]];
-                        lhs = eq_node->get_arg1();
-                        rhs = eq_node->get_arg2();
-                        rhs->compile(code_file, false, temporary_terms, map_idx, false, false);
-                        lhs->compile(code_file, true, temporary_terms, map_idx, false, false);
-                      }
-                    else if (ModelBlock->Block_List[j].Equation_Type[i] == E_EVALUATE_S)
-                      {
-                        eq_node = (BinaryOpNode*)ModelBlock->Block_List[j].Equation_Normalized[i];
-                        lhs = eq_node->get_arg1();
-                        rhs = eq_node->get_arg2();
-                        rhs->compile(code_file, false, temporary_terms, map_idx, false, false);
-                        lhs->compile(code_file, true, temporary_terms, map_idx, false, false);
-                      }
-                    break;
-                  case SOLVE_BACKWARD_COMPLETE:
-                  case SOLVE_FORWARD_COMPLETE:
-                    if (i<ModelBlock->Block_List[j].Nb_Recursives)
-                      goto evaluation;
-                    feedback_variables.push_back(ModelBlock->Block_List[j].Variable[i]);
-                    v=ModelBlock->Block_List[j].Equation[i];
-                    Uf[v].Ufl=NULL;
-                    goto end;
-                  default:
-end:
-                    eq_node = equations[ModelBlock->Block_List[j].Equation[i]];
-                    lhs = eq_node->get_arg1();
-                    rhs = eq_node->get_arg2();
-                    lhs->compile(code_file, false, temporary_terms, map_idx, false, false);
-                    rhs->compile(code_file, false, temporary_terms, map_idx, false, false);
-                    FBINARY_ fbinary(oMinus);
-                    fbinary.write(code_file);
-
-                    FSTPR_ fstpr(i - ModelBlock->Block_List[j].Nb_Recursives);
-                    fstpr.write(code_file);
-                  }
-              }
-            FENDEQU_ fendequ;
-            fendequ.write(code_file);
-            //code_file.write(&FENDEQU, sizeof(FENDEQU));
-            // The Jacobian if we have to solve the block
-            if (ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_BACKWARD
-                && ModelBlock->Block_List[j].Simulation_Type!=EVALUATE_FORWARD)
-              {
-                switch (ModelBlock->Block_List[j].Simulation_Type)
-                  {
-                  case SOLVE_BACKWARD_SIMPLE:
-                  case SOLVE_FORWARD_SIMPLE:
-                    compileDerivative(code_file, ModelBlock->Block_List[j].Equation[0], ModelBlock->Block_List[j].Variable[0], 0, map_idx);
-                      {
-                        FSTPG_ fstpg;
-                        fstpg.write(code_file);
-                      }
-                    break;
-
-                  case SOLVE_BACKWARD_COMPLETE:
-                  case SOLVE_FORWARD_COMPLETE:
-										count_u = feedback_variables.size();
-                    for(i=0; i<(int)ModelBlock->Block_List[j].Chain_Rule_Derivatives->size();i++)
-											{
-                        pair< pair<int, pair<int, int> >, pair<int, int> > it = ModelBlock->Block_List[j].Chain_Rule_Derivatives->at(i);
-                        k=it.first.first;
-                        int eq=it.first.second.first;
-                        int var=it.first.second.second;
-                        int eqr=it.second.first;
-                        int varr=it.second.second;
-                        int v=ModelBlock->Block_List[j].Equation[eq];
-                        if(eq>=ModelBlock->Block_List[j].Nb_Recursives and var>=ModelBlock->Block_List[j].Nb_Recursives)
-												  {
-												  	if (!Uf[v].Ufl)
-                              {
-                                Uf[v].Ufl=(Uff_l*)malloc(sizeof(Uff_l));
-                                Uf[v].Ufl_First=Uf[v].Ufl;
-                              }
-                            else
-                              {
-                                Uf[v].Ufl->pNext=(Uff_l*)malloc(sizeof(Uff_l));
-                                Uf[v].Ufl=Uf[v].Ufl->pNext;
-                              }
-                            Uf[v].Ufl->pNext=NULL;
-                            Uf[v].Ufl->u=count_u;
-                            Uf[v].Ufl->var=varr;
-                            Uf[v].Ufl->lag=k;
-                            compileChainRuleDerivative(code_file, eqr, varr, k, map_idx);
-                            FSTPSU_ fstpsu(count_u);
-                            fstpsu.write(code_file);
-                            count_u++;
-												  }
-											}
-                    for (i = 0;i < ModelBlock->Block_List[j].Size;i++)
-                      {
-                      	if(i>=ModelBlock->Block_List[j].Nb_Recursives)
-                      	  {
-                            FLDR_ fldr(i-ModelBlock->Block_List[j].Nb_Recursives);
-                            fldr.write(code_file);
-
-                            FLDZ_ fldz;
-                            fldz.write(code_file);
-
-                            v=ModelBlock->Block_List[j].Equation[i];
-                            for (Uf[v].Ufl=Uf[v].Ufl_First; Uf[v].Ufl; Uf[v].Ufl=Uf[v].Ufl->pNext)
-                              {
-                                FLDSU_ fldsu(Uf[v].Ufl->u);
-                                fldsu.write(code_file);
-                                FLDSV_ fldsv(eEndogenous, Uf[v].Ufl->var);
-                                fldsv.write(code_file);
-
-                                FBINARY_ fbinary(oTimes);
-                                fbinary.write(code_file);
-
-                                FCUML_ fcuml;
-                                fcuml.write(code_file);
-                              }
-                            Uf[v].Ufl=Uf[v].Ufl_First;
-                            while (Uf[v].Ufl)
-                              {
-                                Uf[v].Ufl_First=Uf[v].Ufl->pNext;
-                                free(Uf[v].Ufl);
-                                Uf[v].Ufl=Uf[v].Ufl_First;
-                              }
-                            FBINARY_ fbinary(oMinus);
-                            fbinary.write(code_file);
-                            FSTPSU_ fstpsu(i - ModelBlock->Block_List[j].Nb_Recursives);
-                            fstpsu.write(code_file);
-                      	  }
-                      }
-                    break;
-                  default:
-                    break;
-                  }
-              }
-      }
-    FENDBLOCK_ fendblock;
-    fendblock.write(code_file);
-    FEND_ fend;
-    fend.write(code_file);
-    code_file.close();
-  }
-
-
-
-void
-StaticDllModel::Write_Inf_To_Bin_File(const string &static_basename, const string &bin_basename, const int &num,
-                                    int &u_count_int, bool &file_open) const
-  {
-    int j;
-    std::ofstream SaveCode;
-    if (file_open)
-      SaveCode.open((bin_basename + "_static.bin").c_str(), ios::out | ios::in | ios::binary | ios ::ate );
-    else
-      SaveCode.open((bin_basename + "_static.bin").c_str(), ios::out | ios::binary);
-    if (!SaveCode.is_open())
-      {
-        cout << "Error : Can't open file \"" << bin_basename << "_static.bin\" for writing\n";
-        exit(EXIT_FAILURE);
-      }
-    u_count_int=0;
-    int Size = block_triangular.ModelBlock->Block_List[num].Size - block_triangular.ModelBlock->Block_List[num].Nb_Recursives;
-    for(int i=0; i<(int)block_triangular.ModelBlock->Block_List[num].Chain_Rule_Derivatives->size();i++)
-			{
-        //Chain_Rule_Derivatives.insert(make_pair( make_pair(eq, eqr), make_pair(var, make_pair(varr, lag))));
-        pair< pair<int, pair<int, int> >, pair<int, int> > it = block_triangular.ModelBlock->Block_List[num].Chain_Rule_Derivatives->at(i);
-        int k=it.first.first;
-        int eq=it.first.second.first;
-
-        int var_init=it.first.second.second;
-        /*int eqr=it.second.first;
-        int varr=it.second.second;*/
-        if(eq>=block_triangular.ModelBlock->Block_List[num].Nb_Recursives and var_init>=block_triangular.ModelBlock->Block_List[num].Nb_Recursives)
-					{
-            int v=eq-block_triangular.ModelBlock->Block_List[num].Nb_Recursives;
-            SaveCode.write(reinterpret_cast<char *>(&v), sizeof(v));
-						int var=it.first.second.second-block_triangular.ModelBlock->Block_List[num].Nb_Recursives + k * Size;
-				    SaveCode.write(reinterpret_cast<char *>(&var), sizeof(var));
-            SaveCode.write(reinterpret_cast<char *>(&k), sizeof(k));
-            int u = u_count_int + Size;
-            SaveCode.write(reinterpret_cast<char *>(&u), sizeof(u));
-            //cout << "eq=" << v << ", var=" << var << ", lag=" << k << " u=" << u << "\n";
-            u_count_int++;
-					}
-			}
-		/*cout << "u_count_int=" << u_count_int << endl;
-		cout << "block_triangular.ModelBlock->Block_List[" << num << "].Nb_Recursives=" << block_triangular.ModelBlock->Block_List[num].Nb_Recursives << " block_triangular.ModelBlock->Block_List[" << num << "].Size=" << block_triangular.ModelBlock->Block_List[num].Size << endl;*/
-    for (j=block_triangular.ModelBlock->Block_List[num].Nb_Recursives;j<block_triangular.ModelBlock->Block_List[num].Size;j++)
-      {
-        int varr=block_triangular.ModelBlock->Block_List[num].Variable[j];
-        //cout << "j=" << j << " varr=" << varr << "\n";
-        SaveCode.write(reinterpret_cast<char *>(&varr), sizeof(varr));
-      }
-    for (j=block_triangular.ModelBlock->Block_List[num].Nb_Recursives;j<block_triangular.ModelBlock->Block_List[num].Size;j++)
-      {
-        int eqr1=block_triangular.ModelBlock->Block_List[num].Equation[j];
-        SaveCode.write(reinterpret_cast<char *>(&eqr1), sizeof(eqr1));
-      }
-    SaveCode.close();
-  }
-
-
-void
-StaticDllModel::evaluateJacobian(const eval_context_type &eval_context, jacob_map *j_m, bool dynamic)
-{
-  int i=0;
-  int j=0;
-  bool *IM=NULL;
-  int a_variable_lag=-9999;
-  for (first_derivatives_type::iterator it = first_derivatives.begin();
-       it != first_derivatives.end(); it++)
-    {
-      //cout << "it->first.second=" << it->first.second << " variable_table.getSymbolID(it->first.second)=" << variable_table.getSymbolID(it->first.second) << " Type=" << variable_table.getType(it->first.second) << " eEndogenous=" << eEndogenous << " eExogenous=" << eExogenous << " variable_table.getLag(it->first.second)=" << variable_table.getLag(it->first.second) << "\n";
-      /*if (getTypeByDerivID(it->first.second) == eEndogenous)
-        {*/
-          NodeID Id = it->second;
-          double val = 0;
-          try
-            {
-              val = Id->eval(eval_context);
-            }
-          catch (ExprNode::EvalException &e)
-            {
-              //cout << "evaluation of Jacobian failed for equation " << it->first.first+1 << " and variable " << symbol_table.getName(getSymbIDByDerivID(it->first.second)) << "(" << getLagByDerivID(it->first.second) << ") [" << getSymbIDByDerivID(it->first.second) << "] !" << endl;
-              cout << "evaluation of Jacobian failed for equation " << it->first.first+1 << " and variable " << symbol_table.getName(it->first.second) << "(" << 0 << ") [" << it->first.second << "] !" << endl;
-              Id->writeOutput(cout, oMatlabStaticModelSparse, temporary_terms);
-              cout << "\n";
-              //cerr << "StaticDllModel::evaluateJacobian: evaluation of Jacobian failed for equation " << it->first.first+1 << " and variable " << symbol_table.getName(getSymbIDByDerivID(it->first.second)) << "(" << getLagByDerivID(it->first.second) << ")!" << endl;
-              cerr << "StaticDllModel::evaluateJacobian: evaluation of Jacobian failed for equation " << it->first.first+1 << " and variable " << symbol_table.getName(it->first.second) << "(" << 0 << ")!" << endl;
-            }
-          int eq=it->first.first;
-          //int var = symbol_table.getTypeSpecificID(getSymbIDByDerivID(it->first.second));///symbol_table.getID(eEndogenous,it->first.second);//variable_table.getSymbolID(it->first.second);
-          int var = symbol_table.getTypeSpecificID(it->first.second);///symbol_table.getID(eEndogenous,it->first.second);//variable_table.getSymbolID(it->first.second);
-          int k1 = 0;//getLagByDerivID(it->first.second);
-          if (a_variable_lag!=k1)
-            {
-              IM=block_triangular.incidencematrix.Get_IM(k1, eEndogenous);
-              a_variable_lag=k1;
-            }
-          if (k1==0 or !dynamic)
-            {
-              j++;
-              (*j_m)[make_pair(eq,var)]+=val;
-            }
-          /*if (IM[eq*symbol_table.endo_nbr()+var] && (fabs(val) < cutoff))
-            {
-              //if (block_triangular.bt_verbose)
-                cout << "the coefficient related to variable " << var << " with lag " << k1 << " in equation " << eq << " is equal to " << val << " and is set to 0 in the incidence matrix (size=" << symbol_table.endo_nbr() << ")\n";
-              block_triangular.incidencematrix.unfill_IM(eq, var, k1, eEndogenous);
-              i++;
-            }*/
-        /*}*/
-    }
-  //Get ride of the elements of the incidence matrix equal to Zero
-  IM=block_triangular.incidencematrix.Get_IM(0, eEndogenous);
-  /*for (int i=0;i<symbol_table.endo_nbr();i++)
-    for (int j=0;j<symbol_table.endo_nbr();j++)
-      if (IM[i*symbol_table.endo_nbr()+j])
-        //if (first_derivatives.find(make_pair(i,getDerivID(symbol_table.getID(eEndogenous, j), 0)))==first_derivatives.end())
-        if (first_derivatives.find(make_pair(i,symbol_table.getID(eEndogenous, j)))==first_derivatives.end())
-          {
-            block_triangular.incidencematrix.unfill_IM(i, j, 0, eEndogenous);
-            cout << "eliminating equation " << i << " and variable " << j << " in the incidence matrix\n";
-          }*/
-  if (i>0)
-    {
-      cout << i << " elements among " << first_derivatives.size() << " in the incidence matrices are below the cutoff (" << cutoff << ") and are discarded\n";
-      cout << "the contemporaneous incidence matrix has " << j << " elements\n";
-    }
-}
-
-void
-StaticDllModel::BlockLinear(Model_Block *ModelBlock)
-{
-  int i,j,l,m,ll;
-  for (j = 0;j < ModelBlock->Size;j++)
-    {
-      if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_BACKWARD_COMPLETE ||
-          ModelBlock->Block_List[j].Simulation_Type==SOLVE_FORWARD_COMPLETE)
-        {
-          ll=ModelBlock->Block_List[j].Max_Lag;
-          for (i=0;i<ModelBlock->Block_List[j].IM_lead_lag[ll].size;i++)
-            {
-              int eq=ModelBlock->Block_List[j].IM_lead_lag[ll].Equ_Index[i];
-              int var=ModelBlock->Block_List[j].IM_lead_lag[ll].Var_Index[i];
-              //first_derivatives_type::const_iterator it=first_derivatives.find(make_pair(eq,variable_table.getID(var,0)));
-              //first_derivatives_type::const_iterator it=first_derivatives.find(make_pair(eq,getDerivID(symbol_table.getID(eEndogenous, var),0)));
-              first_derivatives_type::const_iterator it=first_derivatives.find(make_pair(eq,symbol_table.getID(eEndogenous, var)));
-              if (it!= first_derivatives.end())
-                {
-                  NodeID Id = it->second;
-                  set<pair<int, int> > endogenous;
-                  Id->collectEndogenous(endogenous);
-                  if (endogenous.size() > 0)
-                    {
-                      for (l=0;l<ModelBlock->Block_List[j].Size;l++)
-                        {
-                          if (endogenous.find(make_pair(ModelBlock->Block_List[j].Variable[l], 0)) != endogenous.end())
-                            {
-                              ModelBlock->Block_List[j].is_linear=false;
-                              goto follow;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-      else if (ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_COMPLETE || ModelBlock->Block_List[j].Simulation_Type==SOLVE_TWO_BOUNDARIES_SIMPLE)
-        {
-          for (m=0;m<=ModelBlock->Block_List[j].Max_Lead+ModelBlock->Block_List[j].Max_Lag;m++)
-            {
-              int k1=m-ModelBlock->Block_List[j].Max_Lag;
-              for (i=0;i<ModelBlock->Block_List[j].IM_lead_lag[m].size;i++)
-                {
-                  int eq=ModelBlock->Block_List[j].IM_lead_lag[m].Equ_Index[i];
-                  int var=ModelBlock->Block_List[j].IM_lead_lag[m].Var_Index[i];
-                  //first_derivatives_type::const_iterator it=first_derivatives.find(make_pair(eq,variable_table.getID(var,k1)));
-                  //first_derivatives_type::const_iterator it=first_derivatives.find(make_pair(eq,getDerivID(symbol_table.getID(eEndogenous, var),k1)));
-                  first_derivatives_type::const_iterator it=first_derivatives.find(make_pair(eq,symbol_table.getID(eEndogenous, var)));
-                  NodeID Id = it->second;
-                  if (it!= first_derivatives.end())
-                    {
-                      set<pair<int, int> > endogenous;
-                      Id->collectEndogenous(endogenous);
-                      if (endogenous.size() > 0)
-                        {
-                          for (l=0;l<ModelBlock->Block_List[j].Size;l++)
-                            {
-                              if (endogenous.find(make_pair(ModelBlock->Block_List[j].Variable[l], k1)) != endogenous.end())
-                                {
-                                  ModelBlock->Block_List[j].is_linear=false;
-                                  goto follow;
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-follow:
-      i=0;
-    }
-}
-
-
-map<pair<int, pair<int, int > >, NodeID>
-StaticDllModel::collect_first_order_derivatives_endogenous()
-{
-  map<pair<int, pair<int, int > >, NodeID> endo_derivatives;
-  for (first_derivatives_type::iterator it2 = first_derivatives.begin();
-       it2 != first_derivatives.end(); it2++)
-    {
-      //if (getTypeByDerivID(it2->first.second)==eEndogenous)
-      /*if (it2->first.second)==eEndogenous)
-        {*/
-          int eq = it2->first.first;
-          //int var=symbol_table.getTypeSpecificID(getSymbIDByDerivID(it2->first.second));
-          int var=symbol_table.getTypeSpecificID(it2->first.second);
-          //int lag=getLagByDerivID(it2->first.second);
-          int lag = 0;
-          //if (lag==0)
-          endo_derivatives[make_pair(eq, make_pair(var, lag))] = it2->second;
-        //}
-    }
-  return  endo_derivatives;
-}
-
-
-
-void
-StaticDllModel::computingPass(const eval_context_type &eval_context, bool no_tmp_terms, bool block)
-{
-  assert(block);
-
-  // Compute derivatives w.r. to all endogenous, and possibly exogenous and exogenous deterministic
-  set<int> vars;
-  /*for (deriv_id_table_t::const_iterator it = deriv_id_table.begin();
-       it != deriv_id_table.end(); it++)
-    {
-      SymbolType type = symbol_table.getType(it->first.first);
-      if (type == eEndogenous)
-        vars.insert(it->second);
-    }*/
-  for(int i = 0; i < symbol_table.endo_nbr(); i++)
-    vars.insert(symbol_table.getID(eEndogenous, i));
-
-  // Launch computations
-  cout << "Computing static model derivatives:" << endl
-  << " - order 1" << endl;
-  computeJacobian(vars);
-  //cout << "mode=" << mode << " eSparseDLLMode=" << eSparseDLLMode << " eSparseMode=" << eSparseMode << "\n";
-      BuildIncidenceMatrix();
-
-
-      jacob_map j_m;
-      evaluateJacobian(eval_context, &j_m, true);
-
-      if (block_triangular.bt_verbose)
-        {
-          cout << "The gross incidence matrix \n";
-          block_triangular.incidencematrix.Print_IM(eEndogenous);
-        }
-      t_etype equation_simulation_type;
-      map<pair<int, pair<int, int> >, NodeID> first_order_endo_derivatives = collect_first_order_derivatives_endogenous();
-
-      block_triangular.Normalize_and_BlockDecompose_Static_0_Model(j_m, equations, equation_simulation_type, first_order_endo_derivatives, mfs, cutoff);
-      /*for (int j = 0;j < block_triangular.ModelBlock->Size;j++)
-        {
-          for (int i = 0;i < block_triangular.ModelBlock->Block_List[j].Size;i++)
-            {
-        	    if (i<block_triangular.ModelBlock->Block_List[j].Nb_Recursives )
-        	    	cout << "block=" << j << " R i=" << i << " equation=" << block_triangular.ModelBlock->Block_List[j].Equation[i]+1 << " variable=" << block_triangular.ModelBlock->Block_List[j].Variable[i]+1 << endl;
-							else
-							  cout << "block=" << j << " S i=" << i << " equation=" << block_triangular.ModelBlock->Block_List[j].Equation[i]+1 << " variable=" << block_triangular.ModelBlock->Block_List[j].Variable[i]+1 << endl;
-            }
-        }*/
-
-      BlockLinear(block_triangular.ModelBlock);
-
-      computeChainRuleJacobian(block_triangular.ModelBlock);
-
-      if (!no_tmp_terms)
-        computeTemporaryTermsOrdered(block_triangular.ModelBlock);
-
-}
-
-void
-StaticDllModel::writeStaticFile(const string &basename, bool block) const
-  {
-    int r;
-
-		assert(block);
-
-#ifdef _WIN32
-    r = mkdir(basename.c_str());
-#else
-    r = mkdir(basename.c_str(), 0777);
-#endif
-    if (r < 0 && errno != EEXIST)
-      {
-        perror("ERROR");
-        exit(EXIT_FAILURE);
-      }
-    writeModelEquationsCodeOrdered(basename + "_static", block_triangular.ModelBlock, basename, map_idx);
-    block_triangular.Free_Block(block_triangular.ModelBlock);
-    block_triangular.incidencematrix.Free_IM();
-  }
-
-SymbolType
-StaticDllModel::getTypeByDerivID(int deriv_id) const throw (UnknownDerivIDException)
-{
-  return symbol_table.getType(getSymbIDByDerivID(deriv_id));
-}
-
-int
-StaticDllModel::getLagByDerivID(int deriv_id) const throw (UnknownDerivIDException)
-{
-  if (deriv_id < 0 || deriv_id >= (int) inv_deriv_id_table.size())
-    throw UnknownDerivIDException();
-
-  return inv_deriv_id_table[deriv_id].second;
-}
-
-int
-StaticDllModel::getSymbIDByDerivID(int deriv_id) const throw (UnknownDerivIDException)
-{
-  if (deriv_id < 0 || deriv_id >= (int) inv_deriv_id_table.size())
-    throw UnknownDerivIDException();
-
-  return inv_deriv_id_table[deriv_id].first;
-}
-
-int
-StaticDllModel::getDerivID(int symb_id, int lag) const throw (UnknownDerivIDException)
-{
-  if (symbol_table.getType(symb_id) == eEndogenous)
-    return symb_id;
-  else
-    return -1;
-}
-
-void
-StaticDllModel::computeChainRuleJacobian(Model_Block *ModelBlock)
-{
-  map<int, NodeID> recursive_variables;
-  first_chain_rule_derivatives.clear();
-  for(int blck = 0; blck<ModelBlock->Size; blck++)
-    {
-      recursive_variables.clear();
-      if (ModelBlock->Block_List[blck].Simulation_Type==SOLVE_TWO_BOUNDARIES_COMPLETE or ModelBlock->Block_List[blck].Simulation_Type==SOLVE_TWO_BOUNDARIES_SIMPLE)
-        {
-          ModelBlock->Block_List[blck].Chain_Rule_Derivatives->clear();
-          for(int i = 0; i < ModelBlock->Block_List[blck].Nb_Recursives; i++)
-            {
-              if (ModelBlock->Block_List[blck].Equation_Type[i] == E_EVALUATE_S)
-                //recursive_variables[getDerivID(symbol_table.getID(eEndogenous, ModelBlock->Block_List[blck].Variable[i]), 0)] = ModelBlock->Block_List[blck].Equation_Normalized[i];
-                recursive_variables[symbol_table.getID(eEndogenous, ModelBlock->Block_List[blck].Variable[i])] = ModelBlock->Block_List[blck].Equation_Normalized[i];
-              else
-                //recursive_variables[getDerivID(symbol_table.getID(eEndogenous, ModelBlock->Block_List[blck].Variable[i]), 0)] = equations[ModelBlock->Block_List[blck].Equation[i]];
-                recursive_variables[symbol_table.getID(eEndogenous, ModelBlock->Block_List[blck].Variable[i])] = equations[ModelBlock->Block_List[blck].Equation[i]];
-            }
-          map<pair<pair<int, pair<int, int> >, pair<int, int> >, int> Derivatives = block_triangular.get_Derivatives(ModelBlock, blck);
-
-          map<pair<pair<int, pair<int, int> >, pair<int, int> >, int>::const_iterator it = Derivatives.begin();
-          //#pragma omp parallel for shared(it, blck)
-          for(int i=0; i<(int)Derivatives.size(); i++)
-            {
-            	int Deriv_type = it->second;
-            	pair<pair<int, pair<int, int> >, pair<int, int> > it_l(it->first);
-            	it++;
-            	int lag = it_l.first.first;
-            	int eq = it_l.first.second.first;
-            	int var = it_l.first.second.second;
-            	int eqr = it_l.second.first;
-            	int varr = it_l.second.second;
-            	if(Deriv_type == 0)
-            	  {
-            	    //first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = first_derivatives[make_pair(eqr, getDerivID(symbol_table.getID(eEndogenous, varr), lag))];
-            	    first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = first_derivatives[make_pair(eqr, symbol_table.getID(eEndogenous, varr))];
-            	  }
-							else if (Deriv_type == 1)
-							  {
-							    first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = ModelBlock->Block_List[blck].Equation_Normalized[eq]->getChainRuleDerivative(symbol_table.getID(eEndogenous, varr), recursive_variables);
-							  }
-							else if (Deriv_type == 2)
-							  {
-							  	if(ModelBlock->Block_List[blck].Equation_Type[eq] == E_EVALUATE_S && eq<ModelBlock->Block_List[blck].Nb_Recursives)
-   						      first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = ModelBlock->Block_List[blck].Equation_Normalized[eq]->getChainRuleDerivative(symbol_table.getID(eEndogenous, varr), recursive_variables);
-									else
-									  //first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = equations[eqr]->getChainRuleDerivative(getDerivID(symbol_table.getID(eEndogenous, varr), lag), recursive_variables);
-									  first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = equations[eqr]->getChainRuleDerivative(symbol_table.getID(eEndogenous, varr), recursive_variables);
-							  }
-							ModelBlock->Block_List[blck].Chain_Rule_Derivatives->push_back(make_pair( make_pair(lag, make_pair(eq, var)), make_pair(eqr, varr)));
-            }
-        }
-      else if(   ModelBlock->Block_List[blck].Simulation_Type==SOLVE_BACKWARD_SIMPLE or ModelBlock->Block_List[blck].Simulation_Type==SOLVE_FORWARD_SIMPLE
-              or ModelBlock->Block_List[blck].Simulation_Type==SOLVE_BACKWARD_COMPLETE or ModelBlock->Block_List[blck].Simulation_Type==SOLVE_FORWARD_COMPLETE)
-        {
-          ModelBlock->Block_List[blck].Chain_Rule_Derivatives->clear();
-          for(int i = 0; i < ModelBlock->Block_List[blck].Nb_Recursives; i++)
-            {
-              if (ModelBlock->Block_List[blck].Equation_Type[i] == E_EVALUATE_S)
-                //recursive_variables[getDerivID(symbol_table.getID(eEndogenous, ModelBlock->Block_List[blck].Variable[i]), 0)] = ModelBlock->Block_List[blck].Equation_Normalized[i];
-                recursive_variables[symbol_table.getID(eEndogenous, ModelBlock->Block_List[blck].Variable[i])] = ModelBlock->Block_List[blck].Equation_Normalized[i];
-              else
-                //recursive_variables[getDerivID(symbol_table.getID(eEndogenous, ModelBlock->Block_List[blck].Variable[i]), 0)] = equations[ModelBlock->Block_List[blck].Equation[i]];
-                recursive_variables[symbol_table.getID(eEndogenous, ModelBlock->Block_List[blck].Variable[i])] = equations[ModelBlock->Block_List[blck].Equation[i]];
-            }
-          for(int eq = ModelBlock->Block_List[blck].Nb_Recursives; eq < ModelBlock->Block_List[blck].Size; eq++)
-            {
-              int eqr = ModelBlock->Block_List[blck].Equation[eq];
-              for(int var = ModelBlock->Block_List[blck].Nb_Recursives; var < ModelBlock->Block_List[blck].Size; var++)
-                {
-                  int varr = ModelBlock->Block_List[blck].Variable[var];
-                  //NodeID d1 = equations[eqr]->getChainRuleDerivative(getDerivID(symbol_table.getID(eEndogenous, varr), 0), recursive_variables);
-                  NodeID d1 = equations[eqr]->getChainRuleDerivative(symbol_table.getID(eEndogenous, varr), recursive_variables);
-                  if (d1 == Zero)
-                    continue;
-                  first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, 0))] = d1;
-                  ModelBlock->Block_List[blck].Chain_Rule_Derivatives->push_back(make_pair( make_pair(0, make_pair(eq, var)), make_pair(eqr, varr)));
-                }
-            }
-        }
-    }
-}
-
-void
-StaticDllModel::writeChainRuleDerivative(ostream &output, int eqr, int varr, int lag,
-                           ExprNodeOutputType output_type,
-                           const temporary_terms_type &temporary_terms) const
-{
-  map<pair<int, pair<int, int> >, NodeID>::const_iterator it = first_chain_rule_derivatives.find(make_pair(eqr, make_pair(varr, lag)));
-  if (it != first_chain_rule_derivatives.end())
-    (it->second)->writeOutput(output, output_type, temporary_terms);
-  else
-    output << 0;
-}
-
-
-void
-StaticDllModel::writeLatexFile(const string &basename) const
-  {
-    writeLatexModelFile(basename + "_static.tex", oLatexStaticModel);
-  }
-
-void
-StaticDllModel::jacobianHelper(ostream &output, int eq_nb, int col_nb, ExprNodeOutputType output_type) const
-{
-  output << LEFT_ARRAY_SUBSCRIPT(output_type);
-  if (IS_MATLAB(output_type))
-    output << eq_nb + 1 << ", " << col_nb + 1;
-  else
-    output << eq_nb + col_nb * equations.size();
-  output << RIGHT_ARRAY_SUBSCRIPT(output_type);
-}
-
-void
-StaticDllModel::hessianHelper(ostream &output, int row_nb, int col_nb, ExprNodeOutputType output_type) const
-{
-  output << LEFT_ARRAY_SUBSCRIPT(output_type);
-  if (IS_MATLAB(output_type))
-    output << row_nb + 1 << ", " << col_nb + 1;
-  else
-    output << row_nb + col_nb * NNZDerivatives[1];
-  output << RIGHT_ARRAY_SUBSCRIPT(output_type);
-}
-
-void
-StaticDllModel::writeAuxVarInitval(ostream &output) const
-{
-  for(int i = 0; i < (int) aux_equations.size(); i++)
-    {
-      dynamic_cast<ExprNode *>(aux_equations[i])->writeOutput(output);
-      output << ";" << endl;
-    }
-}
diff --git a/StaticDllModel.hh b/StaticDllModel.hh
deleted file mode 100644
index 8bfc4330408c4b64ccb2735ddc92b68e8e31cc41..0000000000000000000000000000000000000000
--- a/StaticDllModel.hh
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2003-2009 Dynare Team
- *
- * This file is part of Dynare.
- *
- * Dynare is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Dynare is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _STATICDLLMODEL_HH
-#define _STATICDLLMODEL_HH
-
-using namespace std;
-
-#include <fstream>
-
-#include "StaticModel.hh"
-#include "BlockTriangular.hh"
-
-//! Stores a static model
-class StaticDllModel : public ModelTree
-{
-private:
-  typedef map<pair<int, int>, int> deriv_id_table_t;
-  //! Maps a pair (symbol_id, lag) to a deriv ID
-  deriv_id_table_t deriv_id_table;
-  //! Maps a deriv ID to a pair (symbol_id, lag)
-  vector<pair<int, int> > inv_deriv_id_table;
-
-  //! Temporary terms for the file containing parameters dervicatives
-  temporary_terms_type params_derivs_temporary_terms;
-
-  typedef map< pair< int, pair< int, int> >, NodeID> first_chain_rule_derivatives_type;
-  first_chain_rule_derivatives_type first_chain_rule_derivatives;
-
-
-  //! Writes static model file (Matlab version)
-  void writeStaticMFile(const string &static_basename) const;
-  //! Writes static model file (C version)
-  /*! \todo add third derivatives handling */
-  void writeStaticCFile(const string &static_basename) const;
-  //! Writes the Block reordred structure of the model in M output
-  void writeModelEquationsOrdered_M(Model_Block *ModelBlock, const string &static_basename) const;
-  //! Writes the code of the Block reordred structure of the model in virtual machine bytecode
-  void writeModelEquationsCodeOrdered(const string file_name, const Model_Block *ModelBlock, const string bin_basename, map_idx_type map_idx) const;
-  //! Computes jacobian and prepares for equation normalization
-  /*! Using values from initval/endval blocks and parameter initializations:
-    - computes the jacobian for the model w.r. to contemporaneous variables
-    - removes edges of the incidence matrix when derivative w.r. to the corresponding variable is too close to zero (below the cutoff)
-  */
-  void evaluateJacobian(const eval_context_type &eval_context, jacob_map *j_m, bool dynamic);
-  void BlockLinear(Model_Block *ModelBlock);
-  map_idx_type map_idx;
-  //! Build The incidence matrix form the modeltree
-  void BuildIncidenceMatrix();
-
-  void computeTemporaryTermsOrdered(Model_Block *ModelBlock);
-  //! Write derivative code of an equation w.r. to a variable
-  void compileDerivative(ofstream &code_file, int eq, int symb_id, int lag, map_idx_type &map_idx) const;
-  //! Write chain rule derivative code of an equation w.r. to a variable
-  void compileChainRuleDerivative(ofstream &code_file, int eq, int var, int lag, map_idx_type &map_idx) const;
-
-  //! Get the type corresponding to a derivation ID
-  SymbolType getTypeByDerivID(int deriv_id) const throw (UnknownDerivIDException);
-  //! Get the lag corresponding to a derivation ID
-  int getLagByDerivID(int deriv_id) const throw (UnknownDerivIDException);
-  //! Get the symbol ID corresponding to a derivation ID
-  int getSymbIDByDerivID(int deriv_id) const throw (UnknownDerivIDException);
-  //! Compute the column indices of the static Jacobian
-  void computeStatJacobianCols();
-  //! Computes chain rule derivatives of the Jacobian w.r. to endogenous variables
-  void computeChainRuleJacobian(Model_Block *ModelBlock);
-  //! Collect only the first derivatives
-  map<pair<int, pair<int, int> >, NodeID> collect_first_order_derivatives_endogenous();
-
-  //! Helper for writing the Jacobian elements in MATLAB and C
-  /*! Writes either (i+1,j+1) or [i+j*no_eq] */
-  void jacobianHelper(ostream &output, int eq_nb, int col_nb, ExprNodeOutputType output_type) const;
-
-  //! Helper for writing the sparse Hessian elements in MATLAB and C
-  /*! Writes either (i+1,j+1) or [i+j*NNZDerivatives[1]] */
-  void hessianHelper(ostream &output, int row_nb, int col_nb, ExprNodeOutputType output_type) const;
-
-  //! Write chain rule derivative of a recursive equation w.r. to a variable
-  void writeChainRuleDerivative(ostream &output, int eq, int var, int lag, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const;
-
-
-public:
-  StaticDllModel(SymbolTable &symbol_table_arg, NumericalConstants &num_constants);
-  //! Absolute value under which a number is considered to be zero
-  double cutoff;
-  //! Compute the minimum feedback set in the static model:
-  /*!   0 : all endogenous variables are considered as feedback variables
-				1 : the variables belonging to a non linear equation are considered as feedback variables
-        2 : the variables belonging to a non normalizable non linear equation are considered as feedback variables
-        default value = 0 */
-  int mfs;
-  //! the file containing the model and the derivatives code
-  ofstream code_file;
-  //! Execute computations (variable sorting + derivation)
-  /*!
-    \param jacobianExo whether derivatives w.r. to exo and exo_det should be in the Jacobian (derivatives w.r. to endo are always computed)
-    \param hessian whether 2nd derivatives w.r. to exo, exo_det and endo should be computed (implies jacobianExo = true)
-    \param thirdDerivatives whether 3rd derivatives w.r. to endo/exo/exo_det should be computed (implies jacobianExo = true)
-    \param paramsDerivatives whether 2nd derivatives w.r. to a pair (endo/exo/exo_det, parameter) should be computed (implies jacobianExo = true)
-    \param eval_context evaluation context for normalization
-    \param no_tmp_terms if true, no temporary terms will be computed in the static files
-  */
-  void computingPass(const eval_context_type &eval_context, bool no_tmp_terms, bool block);
-  //! Complete set to block decompose the model
-  BlockTriangular block_triangular;
-  //! Adds informations for simulation in a binary file
-  void Write_Inf_To_Bin_File(const string &static_basename, const string &bin_basename,
-                             const int &num, int &u_count_int, bool &file_open) const;
-  //! Writes static model file
-  void writeStaticFile(const string &basename, bool block) const;
-
-  //! Writes LaTeX file with the equations of the static model
-  void writeLatexFile(const string &basename) const;
-
-  //! Writes initializations in oo_.steady_state for the auxiliary variables
-  void writeAuxVarInitval(ostream &output) const;
-
-  virtual int getDerivID(int symb_id, int lag) const throw (UnknownDerivIDException);
-};
-
-#endif
diff --git a/StaticModel.cc b/StaticModel.cc
index 6a55954490bd2cccb50eb81de98f8c02764a67ab..941f5279743a8386547bc987d3f2f48e3745dfd4 100644
--- a/StaticModel.cc
+++ b/StaticModel.cc
@@ -17,43 +17,770 @@
  * along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <iostream>
+#include <cmath>
 #include <cstdlib>
 #include <cassert>
-
-#include <deque>
+#include <cstdio>
+#include <cerrno>
 #include <algorithm>
-#include <iterator>
-#include <functional>
-
-#ifdef DEBUG
-// For select2nd()
-# ifdef __GNUC__
-#  include <ext/functional>
-using namespace __gnu_cxx;
-# endif
+#include "StaticModel.hh"
+
+// For mkdir() and chdir()
+#ifdef _WIN32
+# include <direct.h>
+#else
+# include <unistd.h>
+# include <sys/stat.h>
+# include <sys/types.h>
 #endif
 
-#include <boost/graph/adjacency_list.hpp>
-#include <boost/graph/max_cardinality_matching.hpp>
-#include <boost/graph/strong_components.hpp>
-#include <boost/graph/topological_sort.hpp>
+StaticModel::StaticModel(SymbolTable &symbol_table_arg,
+                           NumericalConstants &num_constants_arg) :
+    ModelTree(symbol_table_arg, num_constants_arg),
+    global_temporary_terms(true),
+    cutoff(1e-15),
+    mfs(0)
+{
+}
 
-#include "StaticModel.hh"
-#include "MinimumFeedbackSet.hh"
+void
+StaticModel::compileDerivative(ofstream &code_file, int eq, int symb_id, int lag, map_idx_type &map_idx) const
+{
+  first_derivatives_type::const_iterator it = first_derivatives.find(make_pair(eq, symbol_table.getID(eEndogenous, symb_id)));
+  if (it != first_derivatives.end())
+    (it->second)->compile(code_file, false, temporary_terms, map_idx, false, false);
+  else
+    {
+      FLDZ_ fldz;
+      fldz.write(code_file);
+    }
+}
 
-using namespace boost;
 
-StaticModel::StaticModel(SymbolTable &symbol_table_arg,
-                         NumericalConstants &num_constants_arg) :
-  ModelTree(symbol_table_arg, num_constants_arg)
+void
+StaticModel::compileChainRuleDerivative(ofstream &code_file, int eqr, int varr, int lag, map_idx_type &map_idx) const
+{
+  map<pair<int, pair<int, int> >, NodeID>::const_iterator it = first_chain_rule_derivatives.find(make_pair(eqr, make_pair(varr, lag)));
+  if (it != first_chain_rule_derivatives.end())
+    (it->second)->compile(code_file, false, temporary_terms, map_idx, false, false);
+  else
+    {
+      FLDZ_ fldz;
+      fldz.write(code_file);
+    }
+}
+
+void
+StaticModel::computeTemporaryTermsOrdered()
+{
+  map<NodeID, pair<int, int> > first_occurence;
+  map<NodeID, int> reference_count;
+  BinaryOpNode *eq_node;
+  first_derivatives_type::const_iterator it;
+  first_chain_rule_derivatives_type::const_iterator it_chr;
+  ostringstream tmp_s;
+  v_temporary_terms.clear();
+  map_idx.clear();
+
+  unsigned int nb_blocks = getNbBlocks();
+  v_temporary_terms = vector< vector<temporary_terms_type> >(nb_blocks);
+
+  v_temporary_terms_inuse = vector<temporary_terms_inuse_type> (nb_blocks);
+
+  temporary_terms.clear();
+  if(!global_temporary_terms)
+    {
+      for (unsigned int block = 0; block < nb_blocks; block++)
+        {
+
+          reference_count.clear();
+          temporary_terms.clear();
+          unsigned int block_size = getBlockSize(block);
+          unsigned int block_nb_mfs = getBlockMfs(block);
+          unsigned int block_nb_recursives = block_size - block_nb_mfs;
+          v_temporary_terms[block] = vector<temporary_terms_type>(block_size);
+          for (unsigned int i = 0; i < block_size; i++)
+            {
+              if (i<block_nb_recursives && isBlockEquationRenormalized( block, i))
+                getBlockEquationRenormalizedNodeID( block, i)->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, block, v_temporary_terms,  i);
+              else
+                {
+                  eq_node = (BinaryOpNode*)getBlockEquationNodeID(block, i);
+                  eq_node->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, block, v_temporary_terms,  i);
+                }
+            }
+          for (t_block_derivatives_equation_variable_laglead_nodeid::const_iterator it = blocks_derivatives[block].begin(); it != (blocks_derivatives[block]).end(); it++)
+            {
+              NodeID id=it->second.second;
+              id->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, block, v_temporary_terms,  block_size-1);
+            }
+          set<int> temporary_terms_in_use;
+          temporary_terms_in_use.clear();
+          v_temporary_terms_inuse[block] = temporary_terms_in_use;
+        }
+    }
+  else
+    {
+      for (unsigned int block = 0; block < nb_blocks; block++)
+        {
+          // Compute the temporary terms reordered
+          unsigned int block_size = getBlockSize(block);
+          unsigned int block_nb_mfs = getBlockMfs(block);
+          unsigned int block_nb_recursives = block_size - block_nb_mfs;
+          v_temporary_terms[block] = vector<temporary_terms_type>(block_size);
+          for (unsigned int i = 0; i < block_size; i++)
+            {
+              if (i<block_nb_recursives && isBlockEquationRenormalized( block, i))
+                getBlockEquationRenormalizedNodeID( block, i)->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, block, v_temporary_terms,  i);
+              else
+                {
+                  eq_node = (BinaryOpNode*)getBlockEquationNodeID(block, i);
+                  eq_node->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, block, v_temporary_terms, i);
+                }
+            }
+          for (t_block_derivatives_equation_variable_laglead_nodeid::const_iterator it = blocks_derivatives[block].begin(); it != (blocks_derivatives[block]).end(); it++)
+            {
+              NodeID id=it->second.second;
+              id->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, block, v_temporary_terms, block_size-1);
+            }
+
+        }
+      for (unsigned int block = 0; block < nb_blocks; block++)
+        {
+          // Collecte the temporary terms reordered
+          unsigned int block_size = getBlockSize(block);
+          unsigned int block_nb_mfs = getBlockMfs(block);
+          unsigned int block_nb_recursives = block_size - block_nb_mfs;
+          set<int> temporary_terms_in_use;
+          for (unsigned int i = 0; i < block_size; i++)
+            {
+              if (i<block_nb_recursives && isBlockEquationRenormalized( block, i))
+                  getBlockEquationRenormalizedNodeID( block, i)->collectTemporary_terms(temporary_terms, temporary_terms_in_use, block);
+              else
+                {
+                  eq_node = (BinaryOpNode*)getBlockEquationNodeID(block, i);
+                  eq_node->collectTemporary_terms(temporary_terms, temporary_terms_in_use, block);
+                }
+            }
+          for (t_block_derivatives_equation_variable_laglead_nodeid::const_iterator it = blocks_derivatives[block].begin(); it != (blocks_derivatives[block]).end(); it++)
+            {
+              NodeID id=it->second.second;
+              id->collectTemporary_terms(temporary_terms, temporary_terms_in_use, block);
+            }
+          for(int i = 0; i < (int) getBlockSize(block); i++)
+            for (temporary_terms_type::const_iterator it = v_temporary_terms[block][i].begin();
+                   it != v_temporary_terms[block][i].end(); it++)
+                   (*it)->collectTemporary_terms(temporary_terms, temporary_terms_in_use, block);
+          v_temporary_terms_inuse[block] = temporary_terms_in_use;
+        }
+    }
+  // Add a mapping form node ID to temporary terms order
+  int j=0;
+  for (temporary_terms_type::const_iterator it = temporary_terms.begin();
+    it != temporary_terms.end(); it++)
+  map_idx[(*it)->idx]=j++;
+}
+
+
+void
+StaticModel::writeModelEquationsOrdered_M(const string &static_basename) const
+  {
+    string tmp_s, sps;
+    ostringstream tmp_output, tmp1_output, global_output;
+    NodeID lhs=NULL, rhs=NULL;
+    BinaryOpNode *eq_node;
+    map<NodeID, int> reference_count;
+    temporary_terms_type local_temporary_terms;
+    ofstream  output;
+    int nze;
+    vector<int> feedback_variables;
+    ExprNodeOutputType local_output_type;
+
+    if(global_temporary_terms)
+      {
+        local_output_type = oMatlabStaticModelSparse;
+        local_temporary_terms = temporary_terms;
+      }
+    else
+      local_output_type = oMatlabDynamicModelSparseLocalTemporaryTerms;
+
+    //----------------------------------------------------------------------
+    //For each block
+    for (unsigned int block = 0; block < getNbBlocks(); block++)
+      {
+        //recursive_variables.clear();
+        feedback_variables.clear();
+        //For a block composed of a single equation determines wether we have to evaluate or to solve the equation
+        nze = derivative_endo[block].size();
+        BlockSimulationType simulation_type = getBlockSimulationType(block);
+        unsigned int block_size = getBlockSize(block);
+        unsigned int block_mfs = getBlockMfs(block);
+        unsigned int block_recursive = block_size - block_mfs;
+
+        tmp1_output.str("");
+        tmp1_output << static_basename << "_" << block+1 << ".m";
+        output.open(tmp1_output.str().c_str(), ios::out | ios::binary);
+        output << "%\n";
+        output << "% " << tmp1_output.str() << " : Computes static model for Dynare\n";
+        output << "%\n";
+        output << "% Warning : this file is generated automatically by Dynare\n";
+        output << "%           from model file (.mod)\n\n";
+        output << "%/\n";
+        if (simulation_type == EVALUATE_BACKWARD || simulation_type ==EVALUATE_FORWARD)
+          output << "function y = " << static_basename << "_" << block+1 << "(y, x, params)\n";
+        else
+          output << "function [residual, y, g1] = " << static_basename << "_" << block+1 << "(y, x, params)\n";
+
+        BlockType block_type;
+        if(simulation_type == SOLVE_FORWARD_COMPLETE ||simulation_type == SOLVE_BACKWARD_COMPLETE)
+          block_type = SIMULTANS;
+        else if((simulation_type == SOLVE_FORWARD_SIMPLE ||simulation_type == SOLVE_BACKWARD_SIMPLE ||
+                 simulation_type == EVALUATE_BACKWARD    || simulation_type == EVALUATE_FORWARD)
+                && getBlockFirstEquation(block) < prologue)
+          block_type = PROLOGUE;
+        else if((simulation_type == SOLVE_FORWARD_SIMPLE ||simulation_type == SOLVE_BACKWARD_SIMPLE ||
+                 simulation_type == EVALUATE_BACKWARD    || simulation_type == EVALUATE_FORWARD)
+                && getBlockFirstEquation(block) >= equations.size() - epilogue)
+          block_type = EPILOGUE;
+        else
+          block_type = SIMULTANS;
+        output << "  % ////////////////////////////////////////////////////////////////////////" << endl
+        << "  % //" << string("                     Block ").substr(int(log10(block + 1))) << block + 1 << " " << BlockType0(block_type)
+        << "          //" << endl
+        << "  % //                     Simulation type "
+        << BlockSim(simulation_type) << "  //" << endl
+        << "  % ////////////////////////////////////////////////////////////////////////" << endl;
+        output << "  global options_;" << endl;
+        //The Temporary terms
+        if (simulation_type != EVALUATE_BACKWARD  && simulation_type != EVALUATE_FORWARD)
+          output << "  g1 = zeros(" << block_mfs << ", " << block_mfs << ");" << endl;
+
+
+        if (v_temporary_terms_inuse[block].size())
+          {
+            tmp_output.str("");
+            for (temporary_terms_inuse_type::const_iterator it = v_temporary_terms_inuse[block].begin();
+                 it != v_temporary_terms_inuse[block].end(); it++)
+              tmp_output << " T" << *it;
+            output << "  global" << tmp_output.str() << ";\n";
+          }
+
+        if (simulation_type!=EVALUATE_BACKWARD && simulation_type!=EVALUATE_FORWARD)
+          output << "  residual=zeros(" << block_mfs << ",1);\n";
+
+
+        // The equations
+        for (unsigned int i = 0; i < block_size; i++)
+          {
+            if(!global_temporary_terms)
+              local_temporary_terms = v_temporary_terms[block][i];
+            temporary_terms_type tt2;
+            tt2.clear();
+            if (v_temporary_terms[block].size())
+              {
+                output << "  " << "% //Temporary variables" << endl;
+                for (temporary_terms_type::const_iterator it = v_temporary_terms[block][i].begin();
+                     it != v_temporary_terms[block][i].end(); it++)
+                  {
+                    output << "  " <<  sps;
+                    (*it)->writeOutput(output, local_output_type, local_temporary_terms);
+                    output << " = ";
+                    (*it)->writeOutput(output, local_output_type, tt2);
+                    // Insert current node into tt2
+                    tt2.insert(*it);
+                    output << ";" << endl;
+                  }
+              }
+
+            int variable_ID = getBlockVariableID(block, i);
+            int equation_ID = getBlockEquationID(block, i);
+            EquationType equ_type = getBlockEquationType(block, i);
+            string sModel = symbol_table.getName(symbol_table.getID(eEndogenous, variable_ID)) ;
+            eq_node = (BinaryOpNode*)getBlockEquationNodeID(block,i);
+            lhs = eq_node->get_arg1();
+            rhs = eq_node->get_arg2();
+            tmp_output.str("");
+						lhs->writeOutput(tmp_output, local_output_type, local_temporary_terms);
+            switch (simulation_type)
+              {
+              case EVALUATE_BACKWARD:
+              case EVALUATE_FORWARD:
+evaluation:
+                  output << "  % equation " << getBlockEquationID(block, i)+1 << " variable : " << sModel
+                         << " (" << variable_ID+1 << ") " << c_Equation_Type(equ_type) << endl;
+                output << "  ";
+                if (equ_type == E_EVALUATE)
+                  {
+                    output << tmp_output.str();
+                    output << " = ";
+                    rhs->writeOutput(output, local_output_type, local_temporary_terms);
+                  }
+                else if (equ_type == E_EVALUATE_S)
+                  {
+                    output << "%" << tmp_output.str();
+                    output << " = ";
+                    if (isBlockEquationRenormalized(block, i))
+                      {
+                        rhs->writeOutput(output, local_output_type, local_temporary_terms);
+                        output << "\n  ";
+                        tmp_output.str("");
+                        eq_node = (BinaryOpNode *)getBlockEquationRenormalizedNodeID(block, i);
+                        lhs = eq_node->get_arg1();
+                        rhs = eq_node->get_arg2();
+                        lhs->writeOutput(output, local_output_type, local_temporary_terms);
+                        output << " = ";
+                        rhs->writeOutput(output, local_output_type, local_temporary_terms);
+                      }
+                  }
+                else
+                  {
+                    cerr << "Type missmatch for equation " << equation_ID+1  << "\n";
+                    exit(EXIT_FAILURE);
+                  }
+                output << ";\n";
+                break;
+              case SOLVE_BACKWARD_SIMPLE:
+              case SOLVE_FORWARD_SIMPLE:
+              case SOLVE_BACKWARD_COMPLETE:
+              case SOLVE_FORWARD_COMPLETE:
+                if (i<block_recursive)
+                  goto evaluation;
+                feedback_variables.push_back(variable_ID);
+                output << "  % equation " << equation_ID+1 << " variable : " << sModel
+                << " (" << variable_ID+1 << ") " << c_Equation_Type(equ_type) << endl;
+                output << "  " << "residual(" << i+1-block_recursive << ") = (";
+                goto end;
+              default:
+end:
+                output << tmp_output.str();
+                output << ") - (";
+                rhs->writeOutput(output, local_output_type, local_temporary_terms);
+                output << ");\n";
+              }
+          }
+        // The Jacobian if we have to solve the block
+        if (simulation_type==SOLVE_BACKWARD_SIMPLE   || simulation_type==SOLVE_FORWARD_SIMPLE ||
+            simulation_type==SOLVE_BACKWARD_COMPLETE || simulation_type==SOLVE_FORWARD_COMPLETE)
+          output << "  " << sps << "% Jacobian  " << endl;
+        switch (simulation_type)
+          {
+          case SOLVE_BACKWARD_SIMPLE:
+          case SOLVE_FORWARD_SIMPLE:
+          case SOLVE_BACKWARD_COMPLETE:
+          case SOLVE_FORWARD_COMPLETE:
+            for (t_block_derivatives_equation_variable_laglead_nodeid::const_iterator it = blocks_derivatives[block].begin(); it != (blocks_derivatives[block]).end(); it++)
+              {
+                unsigned int eq = it->first.first;
+                unsigned int var = it->first.second;
+                unsigned int eqr = getBlockEquationID(block, eq);
+                unsigned int varr = getBlockVariableID(block, var);
+                NodeID id = it->second.second;
+                output << "    g1(" << eq+1-block_recursive << ", " << var+1-block_recursive << ") = ";
+                id->writeOutput(output, local_output_type, local_temporary_terms);
+                output << "; % variable=" << symbol_table.getName(symbol_table.getID(eEndogenous, varr))
+                    << "(" << 0
+                    << ") " << varr+1
+                    << ", equation=" << eqr+1 << endl;
+              }
+            break;
+          default:
+            break;
+          }
+        output.close();
+      }
+  }
+
+void
+StaticModel::writeModelEquationsCodeOrdered(const string file_name, const string bin_basename, map_idx_type map_idx) const
+  {
+    struct Uff_l
+      {
+        int u, var, lag;
+        Uff_l *pNext;
+      };
+
+    struct Uff
+      {
+        Uff_l *Ufl, *Ufl_First;
+      };
+
+    int i,v;
+    string tmp_s;
+    ostringstream tmp_output;
+    ofstream code_file;
+    NodeID lhs=NULL, rhs=NULL;
+    BinaryOpNode *eq_node;
+    Uff Uf[symbol_table.endo_nbr()];
+    map<NodeID, int> reference_count;
+    vector<int> feedback_variables;
+    bool file_open=false;
+
+    string main_name=file_name;
+    main_name+=".cod";
+    code_file.open(main_name.c_str(), ios::out | ios::binary | ios::ate );
+    if (!code_file.is_open())
+      {
+        cout << "Error : Can't open file \"" << main_name << "\" for writing\n";
+        exit(EXIT_FAILURE);
+      }
+    //Temporary variables declaration
+
+    FDIMT_ fdimt(temporary_terms.size());
+    fdimt.write(code_file);
+
+    for (unsigned int block = 0; block < getNbBlocks(); block++)
+      {
+        feedback_variables.clear();
+        if (block>0)
+          {
+            FENDBLOCK_ fendblock;
+            fendblock.write(code_file);
+          }
+        int count_u;
+        int u_count_int=0;
+        BlockSimulationType simulation_type = getBlockSimulationType(block);
+        unsigned int block_size = getBlockSize(block);
+        unsigned int block_mfs = getBlockMfs(block);
+        unsigned int block_recursive = block_size - block_mfs;
+
+        if (simulation_type==SOLVE_TWO_BOUNDARIES_SIMPLE || simulation_type==SOLVE_TWO_BOUNDARIES_COMPLETE ||
+            simulation_type==SOLVE_BACKWARD_COMPLETE || simulation_type==SOLVE_FORWARD_COMPLETE)
+          {
+            Write_Inf_To_Bin_File(file_name, bin_basename, block, u_count_int,file_open);
+            file_open=true;
+          }
+
+        FBEGINBLOCK_ fbeginblock(block_mfs,
+                                 simulation_type,
+                                 getBlockFirstEquation(block),
+                                 block_size,
+                                 variable_reordered,
+                                 equation_reordered,
+                                 blocks_linear[block],
+                                 symbol_table.endo_nbr(),
+                                 0,
+                                 0,
+                                 u_count_int
+                                 );
+        fbeginblock.write(code_file);
+
+        // The equations
+        for (i = 0;i < (int) block_size;i++)
+          {
+            //The Temporary terms
+            temporary_terms_type tt2;
+            tt2.clear();
+            if (v_temporary_terms[block].size())
+              {
+                for (temporary_terms_type::const_iterator it = v_temporary_terms[block][i].begin();
+                     it != v_temporary_terms[block][i].end(); it++)
+                  {
+                    (*it)->compile(code_file, false, tt2, map_idx, false, false);
+                    FSTPST_ fstpst((int)(map_idx.find((*it)->idx)->second));
+                    fstpst.write(code_file);
+                    // Insert current node into tt2
+                    tt2.insert(*it);
+                  }
+              }
+
+            int variable_ID, equation_ID;
+            EquationType equ_type;
+            switch (simulation_type)
+              {
+evaluation:
+              case EVALUATE_BACKWARD:
+              case EVALUATE_FORWARD:
+                equ_type = getBlockEquationType(block, i);
+                if (equ_type == E_EVALUATE)
+                  {
+                    eq_node = (BinaryOpNode*)getBlockEquationNodeID(block,i);
+                    lhs = eq_node->get_arg1();
+                    rhs = eq_node->get_arg2();
+                    rhs->compile(code_file, false, temporary_terms, map_idx, false, false);
+                    lhs->compile(code_file, true, temporary_terms, map_idx, false, false);
+                  }
+                else if (equ_type == E_EVALUATE_S)
+                  {
+                    eq_node = (BinaryOpNode*)getBlockEquationRenormalizedNodeID(block,i);
+                    lhs = eq_node->get_arg1();
+                    rhs = eq_node->get_arg2();
+                    rhs->compile(code_file, false, temporary_terms, map_idx, false, false);
+                    lhs->compile(code_file, true, temporary_terms, map_idx, false, false);
+                  }
+                break;
+              case SOLVE_BACKWARD_COMPLETE:
+              case SOLVE_FORWARD_COMPLETE:
+                if (i< (int) block_recursive)
+                  goto evaluation;
+                variable_ID = getBlockVariableID(block, i);
+                equation_ID = getBlockEquationID(block, i);
+                feedback_variables.push_back(variable_ID);
+                Uf[equation_ID].Ufl=NULL;
+                goto end;
+              default:
+end:
+                eq_node = (BinaryOpNode*)getBlockEquationNodeID(block, i);
+                lhs = eq_node->get_arg1();
+                rhs = eq_node->get_arg2();
+                lhs->compile(code_file, false, temporary_terms, map_idx, false, false);
+                rhs->compile(code_file, false, temporary_terms, map_idx, false, false);
+
+                FBINARY_ fbinary(oMinus);
+                fbinary.write(code_file);
+
+                FSTPR_ fstpr(i - block_recursive);
+                fstpr.write(code_file);
+              }
+          }
+        FENDEQU_ fendequ;
+        fendequ.write(code_file);
+        // The Jacobian if we have to solve the block
+        if    (simulation_type != EVALUATE_BACKWARD
+            && simulation_type != EVALUATE_FORWARD)
+          {
+            switch (simulation_type)
+              {
+              case SOLVE_BACKWARD_SIMPLE:
+              case SOLVE_FORWARD_SIMPLE:
+                compileDerivative(code_file, getBlockEquationID(block, 0), getBlockVariableID(block, 0), 0, map_idx);
+                  {
+                    FSTPG_ fstpg(0);
+                    fstpg.write(code_file);
+                  }
+                break;
+
+              case SOLVE_BACKWARD_COMPLETE:
+              case SOLVE_FORWARD_COMPLETE:
+                count_u = feedback_variables.size();
+                for (t_block_derivatives_equation_variable_laglead_nodeid::const_iterator it = blocks_derivatives[block].begin(); it != (blocks_derivatives[block]).end(); it++)
+                  {
+                    unsigned int eq = it->first.first;
+                    unsigned int var = it->first.second;
+                    unsigned int eqr = getBlockEquationID(block, eq);
+                    unsigned int varr = getBlockVariableID(block, var);
+                    if(eq>=block_recursive and var>=block_recursive)
+                      {
+                        if (!Uf[eqr].Ufl)
+                          {
+                            Uf[eqr].Ufl=(Uff_l*)malloc(sizeof(Uff_l));
+                            Uf[eqr].Ufl_First=Uf[eqr].Ufl;
+                          }
+                        else
+                          {
+                            Uf[eqr].Ufl->pNext=(Uff_l*)malloc(sizeof(Uff_l));
+                            Uf[eqr].Ufl=Uf[eqr].Ufl->pNext;
+                          }
+                        Uf[eqr].Ufl->pNext=NULL;
+                        Uf[eqr].Ufl->u=count_u;
+                        Uf[eqr].Ufl->var=varr;
+                        compileChainRuleDerivative(code_file, eqr, varr, 0, map_idx);
+                        FSTPSU_ fstpsu(count_u);
+                        fstpsu.write(code_file);
+                        count_u++;
+                      }
+                  }
+                for (i = 0;i < (int) block_size;i++)
+                  {
+                    if(i>= (int) block_recursive)
+                      {
+                        FLDR_ fldr(i-block_recursive);
+                        fldr.write(code_file);
+
+                        FLDZ_ fldz;
+                        fldz.write(code_file);
+
+                        v=getBlockEquationID(block, i);
+                        for (Uf[v].Ufl=Uf[v].Ufl_First; Uf[v].Ufl; Uf[v].Ufl=Uf[v].Ufl->pNext)
+                          {
+                            FLDSU_ fldsu(Uf[v].Ufl->u);
+                            fldsu.write(code_file);
+                            FLDSV_ fldsv(eEndogenous, Uf[v].Ufl->var);
+                            fldsv.write(code_file);
+
+                            FBINARY_ fbinary(oTimes);
+                            fbinary.write(code_file);
+
+                            FCUML_ fcuml;
+                            fcuml.write(code_file);
+                          }
+                        Uf[v].Ufl=Uf[v].Ufl_First;
+                        while (Uf[v].Ufl)
+                          {
+                            Uf[v].Ufl_First=Uf[v].Ufl->pNext;
+                            free(Uf[v].Ufl);
+                            Uf[v].Ufl=Uf[v].Ufl_First;
+                          }
+                        FBINARY_ fbinary(oMinus);
+                        fbinary.write(code_file);
+
+                        FSTPSU_ fstpsu(i - block_recursive);
+                        fstpsu.write(code_file);
+
+                      }
+                  }
+                break;
+              default:
+                break;
+              }
+          }
+      }
+    FENDBLOCK_ fendblock;
+    fendblock.write(code_file);
+    FEND_ fend;
+    fend.write(code_file);
+    code_file.close();
+  }
+
+
+void
+StaticModel::Write_Inf_To_Bin_File(const string &static_basename, const string &bin_basename, const int &num,
+                                    int &u_count_int, bool &file_open) const
+  {
+    int j;
+    std::ofstream SaveCode;
+    if (file_open)
+      SaveCode.open((bin_basename + "_static.bin").c_str(), ios::out | ios::in | ios::binary | ios ::ate );
+    else
+      SaveCode.open((bin_basename + "_static.bin").c_str(), ios::out | ios::binary);
+    if (!SaveCode.is_open())
+      {
+        cout << "Error : Can't open file \"" << bin_basename << "_static.bin\" for writing\n";
+        exit(EXIT_FAILURE);
+      }
+    u_count_int=0;
+    unsigned int block_size = getBlockSize(num);
+    unsigned int block_mfs = getBlockMfs(num);
+    unsigned int block_recursive = block_size - block_mfs;
+    for (t_block_derivatives_equation_variable_laglead_nodeid::const_iterator it = blocks_derivatives[num].begin(); it != (blocks_derivatives[num]).end(); it++)
+      {
+        unsigned int eq = it->first.first;
+        unsigned int var = it->first.second;
+        int lag = 0;
+        if(eq>=block_recursive and var>=block_recursive)
+					{
+            int v = eq - block_recursive;
+            SaveCode.write(reinterpret_cast<char *>(&v), sizeof(v));
+						int varr = var - block_recursive;
+				    SaveCode.write(reinterpret_cast<char *>(&varr), sizeof(varr));
+            SaveCode.write(reinterpret_cast<char *>(&lag), sizeof(lag));
+            int u = u_count_int + block_mfs;
+            SaveCode.write(reinterpret_cast<char *>(&u), sizeof(u));
+            u_count_int++;
+					}
+      }
+
+    for (j = block_recursive; j < (int) block_size; j++)
+      {
+        unsigned int varr=getBlockVariableID(num, j);
+        SaveCode.write(reinterpret_cast<char *>(&varr), sizeof(varr));
+      }
+    for (j = block_recursive; j < (int) block_size; j++)
+      {
+        unsigned int eqr=getBlockEquationID(num, j);
+        SaveCode.write(reinterpret_cast<char *>(&eqr), sizeof(eqr));
+      }
+    SaveCode.close();
+  }
+
+map<pair<int, pair<int, int > >, NodeID>
+StaticModel::collect_first_order_derivatives_endogenous()
 {
+  map<pair<int, pair<int, int > >, NodeID> endo_derivatives;
+  for (first_derivatives_type::iterator it2 = first_derivatives.begin();
+       it2 != first_derivatives.end(); it2++)
+    {
+      if (getTypeByDerivID(it2->first.second)==eEndogenous)
+        {
+          int eq = it2->first.first;
+          int var=symbol_table.getTypeSpecificID(it2->first.second);
+          int lag = 0;
+          endo_derivatives[make_pair(eq, make_pair(var, lag))] = it2->second;
+        }
+    }
+  return  endo_derivatives;
+}
+
+void
+StaticModel::computingPass(const eval_context_type &eval_context, bool no_tmp_terms, bool hessian, bool block)
+{
+   // Compute derivatives w.r. to all endogenous, and possibly exogenous and exogenous deterministic
+  set<int> vars;
+
+  for(int i = 0; i < symbol_table.endo_nbr(); i++)
+    vars.insert(symbol_table.getID(eEndogenous, i));
+
+  // Launch computations
+  cout << "Computing static model derivatives:" << endl
+  << " - order 1" << endl;
+  first_derivatives.clear();
+
+  computeJacobian(vars);
+
+  if (hessian)
+    {
+      cout << " - order 2" << endl;
+      computeHessian(vars);
+    }
+
+
+  if (block)
+    {
+      jacob_map contemporaneous_jacobian, static_jacobian;
+
+      // for each block contains pair<Size, Feddback_variable>
+      vector<pair<int, int> > blocks;
+
+      evaluateAndReduceJacobian(eval_context, contemporaneous_jacobian, static_jacobian, dynamic_jacobian, cutoff, false);
+
+      computePossiblySingularNormalization(contemporaneous_jacobian, cutoff == 0);
+
+      computePrologueAndEpilogue(static_jacobian, equation_reordered, variable_reordered, prologue, epilogue);
+
+      map<pair<int, pair<int, int> >, NodeID> first_order_endo_derivatives = collect_first_order_derivatives_endogenous();
+
+      equation_type_and_normalized_equation = equationTypeDetermination(equations, first_order_endo_derivatives, variable_reordered, equation_reordered, mfs);
+
+      cout << "Finding the optimal block decomposition of the model ...\n";
+
+      if (prologue+epilogue < (unsigned int) equation_number())
+        computeBlockDecompositionAndFeedbackVariablesForEachBlock(static_jacobian, dynamic_jacobian, prologue, epilogue, equation_reordered, variable_reordered, blocks, equation_type_and_normalized_equation, false, false, mfs, inv_equation_reordered, inv_variable_reordered);
+
+      block_type_firstequation_size_mfs = reduceBlocksAndTypeDetermination(dynamic_jacobian, prologue, epilogue, blocks, equations, equation_type_and_normalized_equation, variable_reordered, equation_reordered);
+
+      printBlockDecomposition(blocks);
+
+      computeChainRuleJacobian(blocks_derivatives);
+
+      blocks_linear = BlockLinear(blocks_derivatives, variable_reordered);
+
+      collect_block_first_order_derivatives();
+
+      global_temporary_terms = true;
+      if (!no_tmp_terms)
+        computeTemporaryTermsOrdered();
+
+    }
+  else
+    if (!no_tmp_terms)
+      computeTemporaryTerms(true);
 }
 
 void
-StaticModel::writeStaticMFile(ostream &output, const string &func_name) const
+StaticModel::writeStaticMFile(const string &func_name) const
 {
   // Writing comments and function definition command
-  output << "function [residual, g1, g2] = " << func_name << "(y, x, params)" << endl
+  string filename = func_name + "_static.m";
+
+  ofstream output;
+  output.open(filename.c_str(), ios::out | ios::binary);
+  if (!output.is_open())
+    {
+      cerr << "ERROR: Can't open file " << filename << " for writing" << endl;
+      exit(EXIT_FAILURE);
+    }
+
+  output << "function [residual, g1, g2] = " << func_name + "_static(y, x, params)" << endl
          << "%" << endl
          << "% Status : Computes static model for Dynare" << endl
          << "%" << endl
@@ -152,505 +879,354 @@ StaticModel::writeStaticMFile(ostream &output, const string &func_name) const
     output << "  g2 = sparse([],[],[]," << equations.size() << "," << g2ncols << ");" << endl;
 
   output << "end;" << endl; // Close the if nargout >= 3 statement
-}
-
-void
-StaticModel::writeStaticFile(const string &basename, bool block) const
-{
-  string filename = basename + "_static.m";
-
-  ofstream output;
-  output.open(filename.c_str(), ios::out | ios::binary);
-  if (!output.is_open())
-    {
-      cerr << "ERROR: Can't open file " << filename << " for writing" << endl;
-      exit(EXIT_FAILURE);
-    }
-
-  if (block)
-    writeStaticBlockMFSFile(output, basename + "_static");
-  else
-    writeStaticMFile(output, basename + "_static");
-
   output.close();
 }
 
-void
-StaticModel::computingPass(bool block, bool hessian, bool no_tmp_terms)
-{
 
 
-  // Compute derivatives w.r. to all endogenous
-  set<int> vars;
-  for(int i = 0; i < symbol_table.endo_nbr(); i++)
-    vars.insert(symbol_table.getID(eEndogenous, i));
-
-  // Launch computations
-  cout << "Computing static model derivatives:" << endl
-       << " - order 1" << endl;
-  computeJacobian(vars);
-
-  if (hessian)
-    {
-      cout << " - order 2" << endl;
-      computeHessian(vars);
-    }
+void
+StaticModel::writeStaticFile(const string &basename, bool block, bool bytecode) const
+  {
+    int r;
 
-  if (block)
-    {
-      computeNormalization();
-      computeSortedBlockDecomposition();
-      computeMFS();
-      computeSortedRecursive();
-      computeBlockMFSJacobian();
-    }
-  else if (!no_tmp_terms)
-    computeTemporaryTerms(true);
-}
+		//assert(block);
 
-int
-StaticModel::getDerivID(int symb_id, int lag) const throw (UnknownDerivIDException)
-{
-  if (symbol_table.getType(symb_id) == eEndogenous)
-    return symb_id;
-  else
-    return -1;
-}
+#ifdef _WIN32
+    r = mkdir(basename.c_str());
+#else
+    r = mkdir(basename.c_str(), 0777);
+#endif
+    if (r < 0 && errno != EEXIST)
+      {
+        perror("ERROR");
+        exit(EXIT_FAILURE);
+      }
+    if(block && bytecode)
+      writeModelEquationsCodeOrdered(basename + "_static", basename, map_idx);
+    else if(block && !bytecode)
+      {
+        chdir(basename.c_str());
+        writeModelEquationsOrdered_M(basename + "_static");
+        chdir("..");
+        writeStaticBlockMFSFile(basename);
+      }
+    else
+      writeStaticMFile(basename);
+  }
 
 void
-StaticModel::computeNormalization()
+StaticModel::writeStaticBlockMFSFile(const string &basename) const
 {
-  const int n = equation_number();
+ string filename = basename + "_static.m";
 
-  assert(n == symbol_table.endo_nbr());
-
-  typedef adjacency_list<vecS, vecS, undirectedS> BipartiteGraph;
-
-  /*
-    Vertices 0 to n-1 are for endogenous (using type specific ID)
-    Vertices n to 2*n-1 are for equations (using equation no.)
-  */
-  BipartiteGraph g(2 * n);
-
-  // Fill in the graph
-  set<pair<int, int> > endo;
-  for(int i = 0; i < n; i++)
+  ofstream output;
+  output.open(filename.c_str(), ios::out | ios::binary);
+  if (!output.is_open())
     {
-      endo.clear();
-      equations[i]->collectEndogenous(endo);
-      for(set<pair<int, int> >::const_iterator it = endo.begin();
-          it != endo.end(); it++)
-        add_edge(i + n, it->first, g);
+      cerr << "ERROR: Can't open file " << filename << " for writing" << endl;
+      exit(EXIT_FAILURE);
     }
 
-  // Compute maximum cardinality matching
-  vector<int> mate_map(2*n);
-
-#if 1
-  bool check = checked_edmonds_maximum_cardinality_matching(g, &mate_map[0]);
-#else // Alternative way to compute normalization, by giving an initial matching using natural normalizations
-  fill(mate_map.begin(), mate_map.end(), graph_traits<BipartiteGraph>::null_vertex());
-
-  multimap<int, int> natural_endo2eqs;
-  computeNormalizedEquations(natural_endo2eqs);
+  string func_name = basename + "_static";
 
-  for(int i = 0; i < symbol_table.endo_nbr(); i++)
-    {
-      if (natural_endo2eqs.count(i) == 0)
-        continue;
+  output << "function [residual, g1, y] = " << func_name << "(nblock, y, x, params)" << endl
+         << "  residual = [];" << endl
+         << "  g1 = [];" << endl
+         << "  switch nblock" << endl;
 
-      int j = natural_endo2eqs.find(i)->second;
+  unsigned int nb_blocks = getNbBlocks();
 
-      put(&mate_map[0], i, n+j);
-      put(&mate_map[0], n+j, i);
-    }
 
-  edmonds_augmenting_path_finder<BipartiteGraph, size_t *, property_map<BipartiteGraph, vertex_index_t>::type> augmentor(g, &mate_map[0], get(vertex_index, g));
-  bool not_maximum_yet = true;
-  while(not_maximum_yet)
+  for(int b = 0; b < (int) nb_blocks; b++)
     {
-      not_maximum_yet = augmentor.augment_matching();
-    }
-  augmentor.get_current_matching(&mate_map[0]);
 
-  bool check = maximum_cardinality_matching_verifier<BipartiteGraph, size_t *, property_map<BipartiteGraph, vertex_index_t>::type>::verify_matching(g, &mate_map[0], get(vertex_index, g));
-#endif
+      set<int> local_var;
 
-  assert(check);
+      output << "    case " << b+1 << endl;
 
-  // Check if all variables are normalized
-  vector<int>::const_iterator it = find(mate_map.begin(), mate_map.begin() + n, graph_traits<BipartiteGraph>::null_vertex());
-  if (it != mate_map.begin() + n)
-    {
-      cerr << "ERROR: Could not normalize static model. Variable "
-           << symbol_table.getName(symbol_table.getID(eEndogenous, it - mate_map.begin()))
-           << " is not in the maximum cardinality matching." << endl;
-      exit(EXIT_FAILURE);
+      BlockSimulationType simulation_type = getBlockSimulationType(b);
+
+      if (simulation_type == EVALUATE_BACKWARD || simulation_type ==EVALUATE_FORWARD)
+          output << "      y = " << func_name << "_" << b+1 << "(y, x, params);\n";
+        else
+          output << "      [residual, y, g1] = " << func_name << "_" << b+1 << "(y, x, params);\n";
     }
+  output << "  end" << endl
+         << "end" << endl;
+  output.close();
 
-#ifdef DEBUG
-  for(int i = 0; i < n; i++)
-    cout << "Endogenous " << symbol_table.getName(symbol_table.getID(eEndogenous, i))
-         << " matched with equation " << (mate_map[i]-n+1) << endl;
-#endif
+}
 
-  // Create the resulting map, by copying the n first elements of mate_map, and substracting n to them
-  endo2eq.resize(equation_number());
-  transform(mate_map.begin(), mate_map.begin() + n, endo2eq.begin(), bind2nd(minus<int>(), n));
 
-#ifdef DEBUG
-  multimap<int, int> natural_endo2eqs;
-  computeNormalizedEquations(natural_endo2eqs);
 
-  int n1 = 0, n2 = 0;
+void
+StaticModel::writeOutput(ostream &output, bool block) const
+{
+  if (!block)
+    return;
 
-  for(int i = 0; i < symbol_table.endo_nbr(); i++)
+  unsigned int nb_blocks = getNbBlocks();
+  output << "M_.blocksMFS = cell(" << nb_blocks << ", 1);" << endl;
+  for(int b = 0; b < (int) nb_blocks; b++)
     {
-      if (natural_endo2eqs.count(i) == 0)
-        continue;
+      output << "M_.blocksMFS{" << b+1 << "} = [ ";
+      unsigned int block_size = getBlockSize(b);
+      unsigned int block_mfs = getBlockMfs(b);
+      unsigned int block_recursive = block_size - block_mfs;
+      BlockSimulationType simulation_type = getBlockSimulationType(b);
 
-      n1++;
+      if (simulation_type != EVALUATE_BACKWARD && simulation_type != EVALUATE_FORWARD)
+        for(int i= block_recursive; i< (int) block_size; i++)
+          output << getBlockVariableID(b, i)+1 << "; ";
 
-      pair<multimap<int, int>::const_iterator, multimap<int, int>::const_iterator> x = natural_endo2eqs.equal_range(i);
-      if (find_if(x.first, x.second, compose1(bind2nd(equal_to<int>(), endo2eq[i]), select2nd<multimap<int, int>::value_type>())) == x.second)
-        cout << "Natural normalization of variable " << symbol_table.getName(symbol_table.getID(eEndogenous, i))
-             << " not used." << endl;
-      else
-        n2++;
+      output << "];" << endl;
     }
-
-  cout << "Used " << n2 << " natural normalizations out of " << n1 << ", for a total of " << n << " equations." << endl;
-#endif
 }
 
-void
-StaticModel::computeNormalizedEquations(multimap<int, int> &endo2eqs) const
-{
-  for(int i = 0; i < equation_number(); i++)
-    {
-      VariableNode *lhs = dynamic_cast<VariableNode *>(equations[i]->get_arg1());
-      if (lhs == NULL)
-        continue;
-
-      int symb_id = lhs->get_symb_id();
-      if (symbol_table.getType(symb_id) != eEndogenous)
-        continue;
-
-      set<pair<int, int> > endo;
-      equations[i]->get_arg2()->collectEndogenous(endo);
-      if (endo.find(make_pair(symbol_table.getTypeSpecificID(symb_id), 0)) != endo.end())
-        continue;
 
-      endo2eqs.insert(make_pair(symbol_table.getTypeSpecificID(symb_id), i));
-      cout << "Endogenous " << symbol_table.getName(symb_id) << " normalized in equation " << (i+1) << endl;
-    }
+SymbolType
+StaticModel::getTypeByDerivID(int deriv_id) const throw (UnknownDerivIDException)
+{
+  return symbol_table.getType(getSymbIDByDerivID(deriv_id));
 }
 
-void
-StaticModel::writeLatexFile(const string &basename) const
+int
+StaticModel::getLagByDerivID(int deriv_id) const throw (UnknownDerivIDException)
 {
-  writeLatexModelFile(basename + "_static.tex", oLatexStaticModel);
+  return 0;
 }
 
-void
-StaticModel::computeSortedBlockDecomposition()
+int
+StaticModel::getSymbIDByDerivID(int deriv_id) const throw (UnknownDerivIDException)
 {
-  const int n = equation_number();
-
-  assert((int) endo2eq.size() == n);
-
-  // Compute graph representation of static model
-  typedef adjacency_list<vecS, vecS, directedS> DirectedGraph;
-  DirectedGraph g(n);
-
-  set<pair<int, int> > endo;
-  for(int i = 0; i < n; i++)
-    {
-      endo.clear();
-      equations[endo2eq[i]]->collectEndogenous(endo);
-      for(set<pair<int, int> >::const_iterator it = endo.begin();
-          it != endo.end(); it++)
-        add_edge(it->first, i, g);
-    }
-
-  // Compute strongly connected components
-  vector<int> endo2block(n);
-  int m = strong_components(g, &endo2block[0]);
-
-  // Create directed acyclic graph associated to the strongly connected components
-  DirectedGraph dag(m);
-  graph_traits<DirectedGraph>::edge_iterator ei, ei_end;
-  for(tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
-    {
-      int s = endo2block[source(*ei, g)];
-      int t = endo2block[target(*ei, g)];
-      if (s != t)
-        add_edge(s, t, dag);
-    }
-
-  // Compute topological sort of DAG (ordered list of unordered SCC)
-  deque<int> ordered2unordered;
-  topological_sort(dag, front_inserter(ordered2unordered)); // We use a front inserter because topological_sort returns the inverse order
-  // Construct mapping from unordered SCC to ordered SCC
-  vector<int> unordered2ordered(m);
-  for(int i = 0; i < m; i++)
-    unordered2ordered[ordered2unordered[i]] = i;
-
-  // Fill in data structure representing blocks
-  blocks.clear();
-  blocks.resize(m);
-  for(int i = 0; i < n; i++)
-    blocks[unordered2ordered[endo2block[i]]].insert(i);
-
-#ifdef DEBUG
-  cout << "Found " << m << " blocks" << endl;
-  for(int i = 0; i < m; i++)
-    cout << " Block " << i << " of size " << blocks[i].size() << endl;
-#endif
+  return deriv_id;
 }
 
-void
-StaticModel::computeMFS()
+int
+StaticModel::getDerivID(int symb_id, int lag) const throw (UnknownDerivIDException)
 {
-  const int n = equation_number();
-  assert((int) endo2eq.size() == n);
+  if (symbol_table.getType(symb_id) == eEndogenous)
+    return symb_id;
+  else
+    return -1;
+}
 
-  const int nblocks = blocks.size();
-  blocksMFS.clear();
-  blocksMFS.resize(nblocks);
 
-  // Iterate over blocks
-  for(int b = 0; b < nblocks; b++)
+map<pair<pair<int, pair<int, int> >, pair<int, int> >, int>
+StaticModel::get_Derivatives(int block)
+{
+  map<pair<pair<int, pair<int, int> >, pair<int, int> >, int> Derivatives;
+  Derivatives.clear();
+  int block_size = getBlockSize(block);
+  int block_nb_recursive = block_size - getBlockMfs(block);
+  int lag = 0;
+  for(int eq = 0; eq < block_size; eq++)
     {
-      // Construct subgraph for MFS computation, where vertex number is position in the block
-      int p = blocks[b].size();
-      MFS::AdjacencyList_type g(p);
-
-      // Construct v_index and v_index1 properties, and a mapping between type specific IDs and vertex descriptors
-      property_map<MFS::AdjacencyList_type, vertex_index_t>::type v_index = get(vertex_index, g);
-      property_map<MFS::AdjacencyList_type, vertex_index1_t>::type v_index1 = get(vertex_index1, g);
-      map<int, graph_traits<MFS::AdjacencyList_type>::vertex_descriptor> tsid2vertex;
-      int j = 0;
-      for(set<int>::const_iterator it = blocks[b].begin(); it != blocks[b].end(); ++it)
+      int eqr = getBlockEquationID(block, eq);
+      for(int var = 0; var < block_size; var++)
         {
-          tsid2vertex[*it] = vertex(j, g);
-          put(v_index, vertex(j, g), *it);
-          put(v_index1, vertex(j, g), *it);
-          j++;
-        }
+          int varr = getBlockVariableID(block, var);
+          if(dynamic_jacobian.find(make_pair(lag, make_pair(eqr, varr))) != dynamic_jacobian.end())
+            {
+              bool OK = true;
+              map<pair<pair<int, pair<int, int> >, pair<int, int> >, int>::const_iterator its = Derivatives.find(make_pair(make_pair(lag, make_pair(eq, var)), make_pair(eqr, varr)));
+              if(its!=Derivatives.end())
+                {
+                	if(its->second == 2)
+                	  OK=false;
+                }
 
-      // Add edges, loop over endogenous in the block
-      set<pair<int, int> > endo;
-      for(set<int>::const_iterator it = blocks[b].begin(); it != blocks[b].end(); ++it)
-        {
-          endo.clear();
-
-          // Test if associated equation is in normalized form, and compute set of endogenous appearing in it
-          ExprNode *lhs = equations[endo2eq[*it]]->get_arg1();
-          VariableNode *lhs_var = dynamic_cast<VariableNode *>(lhs);
-          if (lhs_var == NULL || lhs_var->get_symb_id() != symbol_table.getID(eEndogenous, *it))
-            lhs->collectEndogenous(endo); // Only collect endogenous of LHS if not normalized form
-          ExprNode *rhs = equations[endo2eq[*it]]->get_arg2();
-          rhs->collectEndogenous(endo);
-
-          for(set<pair<int, int> >::const_iterator it2 = endo.begin();
-              it2 != endo.end(); ++it2)
-            if (blocks[b].find(it2->first) != blocks[b].end()) // Add edge only if vertex member of this block
-              add_edge(tsid2vertex[it2->first], tsid2vertex[*it], g);
+              if(OK)
+                {
+                  if (getBlockEquationType(block, eq) == E_EVALUATE_S and eq<block_nb_recursive)
+                    //It's a normalized equation, we have to recompute the derivative using chain rule derivative function
+                    Derivatives[make_pair(make_pair(lag, make_pair(eq, var)), make_pair(eqr, varr))] = 1;
+                  else
+                    //It's a feedback equation we can use the derivatives
+                    Derivatives[make_pair(make_pair(lag, make_pair(eq, var)), make_pair(eqr, varr))] = 0;
+                }
+              if(var<block_nb_recursive)
+                {
+                  int eqs = getBlockEquationID(block, var);
+                  for(int vars=block_nb_recursive; vars<block_size; vars++)
+                    {
+                      int varrs = getBlockVariableID(block, vars);
+                      //A new derivative needs to be computed using the chain rule derivative function (a feedback variable appears in a recursive equation)
+                      if(Derivatives.find(make_pair(make_pair(lag, make_pair(var, vars)), make_pair(eqs, varrs)))!=Derivatives.end())
+                        Derivatives[make_pair(make_pair(lag, make_pair(eq, vars)), make_pair(eqr, varrs))] = 2;
+                    }
+                }
+            }
         }
-
-      // Compute minimum feedback set
-      MFS::Minimal_set_of_feedback_vertex(blocksMFS[b], g);
-
-#ifdef DEBUG
-      cout << "Block " << b << ": " << blocksMFS[b].size() << "/" << blocks[b].size() << " in MFS" << endl;
-#endif
     }
+
+  return(Derivatives);
 }
 
+
 void
-StaticModel::computeSortedRecursive()
+StaticModel::computeChainRuleJacobian(t_blocks_derivatives &blocks_derivatives)
 {
-  const int nblocks = blocks.size();
-  blocksRecursive.clear();
-  blocksRecursive.resize(nblocks);
-
-  for(int b = 0; b < nblocks; b++)
+  map<int, NodeID> recursive_variables;
+  unsigned int nb_blocks = getNbBlocks();
+  blocks_derivatives = t_blocks_derivatives(nb_blocks);
+  for(unsigned int block = 0; block < nb_blocks; block++)
     {
-      // Construct the set of recursive vars
-      // The index in this vector will be the vertex descriptor in the graph
-      vector<int> recurs_vars;
-      set_difference(blocks[b].begin(), blocks[b].end(),
-                     blocksMFS[b].begin(), blocksMFS[b].end(),
-                     back_inserter(recurs_vars));
-
-      // Construct graph representation of recursive vars
-      typedef adjacency_list<vecS, vecS, directedS> DirectedGraph;
-      DirectedGraph dag(recurs_vars.size());
-      set<pair<int, int> > endo;
-      for(int i = 0; i < (int) recurs_vars.size(); i++)
+      t_block_derivatives_equation_variable_laglead_nodeid tmp_derivatives;
+      recursive_variables.clear();
+      BlockSimulationType simulation_type = getBlockSimulationType(block);
+      int block_size = getBlockSize(block);
+      int block_nb_mfs = getBlockMfs(block);
+      int block_nb_recursives = block_size - block_nb_mfs;
+      if (simulation_type==SOLVE_TWO_BOUNDARIES_COMPLETE or simulation_type==SOLVE_TWO_BOUNDARIES_SIMPLE)
         {
-          endo.clear();
-          equations[endo2eq[recurs_vars[i]]]->get_arg2()->collectEndogenous(endo);
-          for(set<pair<int, int> >::const_iterator it = endo.begin();
-              it != endo.end(); it++)
+          blocks_derivatives.push_back(t_block_derivatives_equation_variable_laglead_nodeid(0));
+          for(int i = 0; i < block_nb_recursives; i++)
+            {
+              if (getBlockEquationType(block, i) == E_EVALUATE_S)
+                recursive_variables[getDerivID(symbol_table.getID(eEndogenous, getBlockVariableID(block, i)), 0)] = getBlockEquationRenormalizedNodeID(block, i);
+              else
+                recursive_variables[getDerivID(symbol_table.getID(eEndogenous, getBlockVariableID(block, i)), 0)] = getBlockEquationNodeID(block, i);
+            }
+          map<pair<pair<int, pair<int, int> >, pair<int, int> >, int> Derivatives = get_Derivatives(block);
+          map<pair<pair<int, pair<int, int> >, pair<int, int> >, int>::const_iterator it = Derivatives.begin();
+          for(int i=0; i<(int)Derivatives.size(); i++)
             {
-              vector<int>::const_iterator it2 = find(recurs_vars.begin(), recurs_vars.end(), it->first);
-              if (it2 != recurs_vars.end())
+              int Deriv_type = it->second;
+              pair<pair<int, pair<int, int> >, pair<int, int> > it_l(it->first);
+              it++;
+              int lag = it_l.first.first;
+              int eq = it_l.first.second.first;
+              int var = it_l.first.second.second;
+              int eqr = it_l.second.first;
+              int varr = it_l.second.second;
+              if(Deriv_type == 0)
+                first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = first_derivatives[make_pair(eqr, getDerivID(symbol_table.getID(eEndogenous, varr), lag))];
+              else if (Deriv_type == 1)
+                first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = (equation_type_and_normalized_equation[eqr].second)->getChainRuleDerivative(getDerivID(symbol_table.getID(eEndogenous, varr), lag), recursive_variables);
+              else if (Deriv_type == 2)
                 {
-                  int source_vertex = it2 - recurs_vars.begin();
-                  add_edge(source_vertex, i, dag);
+                  if(getBlockEquationType(block, eq) == E_EVALUATE_S && eq<block_nb_recursives)
+                    first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = (equation_type_and_normalized_equation[eqr].second)->getChainRuleDerivative(getDerivID(symbol_table.getID(eEndogenous, varr), lag), recursive_variables);
+                  else
+                    first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))] = equations[eqr]->getChainRuleDerivative(getDerivID(symbol_table.getID(eEndogenous, varr), lag), recursive_variables);
                 }
+              tmp_derivatives.push_back(make_pair(make_pair(eq, var), make_pair(lag, first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, lag))]) ));
             }
         }
-      // Compute topological sort
-      deque<int> ordered_recurs_vertices;
-      topological_sort(dag, front_inserter(ordered_recurs_vertices)); // We use a front inserter because topological_sort returns the inverse order
-
-      // Construct the final order
-      for(deque<int>::const_iterator it = ordered_recurs_vertices.begin();
-          it != ordered_recurs_vertices.end(); it++)
-        blocksRecursive[b].push_back(recurs_vars[*it]);
-    }
-}
-
-void
-StaticModel::computeBlockMFSJacobian()
-{
-  blocksMFSJacobian.clear();
-  for(int b = 0; b < (int) blocks.size(); b++)
-    {
-      // Create the map of recursive vars to their normalized equation
-      map<int, NodeID> recursive2eq;
-      for(vector<int>::const_iterator it = blocksRecursive[b].begin();
-          it != blocksRecursive[b].end(); it++)
-        recursive2eq[symbol_table.getID(eEndogenous, *it)] = equations[endo2eq[*it]];
-
-      for(set<int>::const_iterator it = blocksMFS[b].begin();
-          it != blocksMFS[b].end(); it++)
+      else if(   simulation_type==SOLVE_BACKWARD_SIMPLE or simulation_type==SOLVE_FORWARD_SIMPLE
+              or simulation_type==SOLVE_BACKWARD_COMPLETE or simulation_type==SOLVE_FORWARD_COMPLETE)
         {
-          int eq_no = endo2eq[*it];
-          for(set<int>::const_iterator it2 = blocksMFS[b].begin();
-              it2 != blocksMFS[b].end(); it2++)
+          blocks_derivatives.push_back(t_block_derivatives_equation_variable_laglead_nodeid(0));
+          for(int i = 0; i < block_nb_recursives; i++)
             {
-              int deriv_id = symbol_table.getID(eEndogenous, *it2);
-              NodeID d = equations[eq_no]->getChainRuleDerivative(deriv_id, recursive2eq);
-              if (d != Zero)
-                blocksMFSJacobian[make_pair(eq_no, *it2)] = d;
+              if (getBlockEquationType(block, i) == E_EVALUATE_S)
+                recursive_variables[getDerivID(symbol_table.getID(eEndogenous, getBlockVariableID(block,i)), 0)] = getBlockEquationRenormalizedNodeID(block, i);
+              else
+                recursive_variables[getDerivID(symbol_table.getID(eEndogenous, getBlockVariableID(block,i)), 0)] = getBlockEquationNodeID(block, i);
+            }
+          for(int eq = block_nb_recursives; eq < block_size; eq++)
+            {
+              int eqr = getBlockEquationID(block, eq);
+              for(int var = block_nb_recursives; var < block_size; var++)
+                {
+                  int varr = getBlockVariableID(block, var);
+                  NodeID d1 = equations[eqr]->getChainRuleDerivative(getDerivID(symbol_table.getID(eEndogenous, varr), 0), recursive_variables);
+                  if (d1 == Zero)
+                    continue;
+                  first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, 0))] = d1;
+                  tmp_derivatives.push_back(
+                 make_pair(make_pair(eq, var),make_pair(0, first_chain_rule_derivatives[make_pair(eqr, make_pair(varr, 0))])));
+                }
             }
         }
+      blocks_derivatives[block] = tmp_derivatives;
     }
 }
 
+
 void
-StaticModel::writeOutput(ostream &output, bool block) const
+StaticModel::collect_block_first_order_derivatives()
 {
-  if (!block)
-    return;
-
-  output << "M_.blocksMFS = cell(" << blocksMFS.size() << ", 1);" << endl;
-  for(int b = 0; b < (int) blocks.size(); b++)
+  //! vector for an equation or a variable indicates the block number
+  vector<int> equation_2_block, variable_2_block;
+  unsigned int nb_blocks = getNbBlocks();
+  equation_2_block = vector<int>(equation_reordered.size());
+  variable_2_block = vector<int>(variable_reordered.size());
+  for(unsigned int block = 0; block < nb_blocks; block++)
     {
-      output << "M_.blocksMFS{" << b+1 << "} = [ ";
-      transform(blocksMFS[b].begin(), blocksMFS[b].end(), ostream_iterator<int>(output, "; "), bind2nd(plus<int>(), 1));
-      output << "];" << endl;
+      unsigned int block_size = getBlockSize(block);
+      for(unsigned int i = 0; i < block_size; i++)
+        {
+          equation_2_block[getBlockEquationID(block, i)] = block;
+          variable_2_block[getBlockVariableID(block, i)] = block;
+        }
     }
-}
-
-void
-StaticModel::writeLocalVars(ostream &output, NodeID expr, set<int> &local_var_written) const
-{
-  set<int> expr_local_var;
-  expr->collectModelLocalVariables(expr_local_var);
-  vector<int> new_local_var;
-  set_difference(expr_local_var.begin(), expr_local_var.end(),
-                 local_var_written.begin(), local_var_written.end(),
-                 back_inserter(new_local_var));
-
-  for(vector<int>::const_iterator it = new_local_var.begin();
-      it != new_local_var.end(); it++)
+  derivative_endo = vector<t_derivative>(nb_blocks);
+  endo_max_leadlag_block = vector<pair<int, int> >(nb_blocks, make_pair( 0, 0));
+  max_leadlag_block = vector<pair<int, int> >(nb_blocks, make_pair( 0, 0));
+  for (first_derivatives_type::iterator it2 = first_derivatives.begin();
+       it2 != first_derivatives.end(); it2++)
     {
-      output << symbol_table.getName(*it) << " = ";
-      map<int, NodeID>::const_iterator it2 = local_variables_table.find(*it);
-      it2->second->writeOutput(output, oMatlabStaticModel, temporary_terms_type());
-      output << ";" << endl;
-      local_var_written.insert(*it);
+      int eq = it2->first.first;
+      int var = symbol_table.getTypeSpecificID(getSymbIDByDerivID(it2->first.second));
+      int lag = 0;
+      int block_eq = equation_2_block[eq];
+      int block_var = variable_2_block[var];
+      max_leadlag_block[block_eq] = make_pair(0, 0);
+      max_leadlag_block[block_eq] = make_pair(0, 0);
+      endo_max_leadlag_block[block_eq] = make_pair(0, 0);
+      endo_max_leadlag_block[block_eq] = make_pair(0, 0);
+      t_derivative tmp_derivative ;
+      t_lag_var lag_var;
+      if (getTypeByDerivID(it2->first.second) == eEndogenous && block_eq == block_var)
+        {
+          tmp_derivative = derivative_endo[block_eq];
+          tmp_derivative[make_pair(lag, make_pair(eq, var))] = first_derivatives[make_pair(eq, getDerivID(symbol_table.getID(eEndogenous, var), lag))];
+          derivative_endo[block_eq] = tmp_derivative;
+        }
     }
 }
 
 void
-StaticModel::writeStaticBlockMFSFile(ostream &output, const string &func_name) const
+StaticModel::writeChainRuleDerivative(ostream &output, int eqr, int varr, int lag,
+                           ExprNodeOutputType output_type,
+                           const temporary_terms_type &temporary_terms) const
 {
-  output << "function [residual, g1, y] = " << func_name << "(nblock, y, x, params)" << endl
-         << "  switch nblock" << endl;
-
-  for(int b = 0; b < (int) blocks.size(); b++)
-    {
-      set<int> local_var;
-
-      output << "    case " << b+1 << endl
-             << "      % Variables not in minimum feedback set" << endl;
-      for(vector<int>::const_iterator it = blocksRecursive[b].begin();
-          it != blocksRecursive[b].end(); it++)
-        {
-          NodeID eq = equations[endo2eq[*it]];
-
-          writeLocalVars(output, eq, local_var);
-
-          eq->writeOutput(output, oMatlabStaticModel, temporary_terms_type());
-          output << ";" << endl;
-        }
-
-      output << "      % Model residuals" << endl
-             << "residual = zeros(" << blocksMFS[b].size() << ",1);" << endl;
-
-      int i = 1;
-      for (set<int>::const_iterator it = blocksMFS[b].begin();
-           it != blocksMFS[b].end(); it++)
-        {
-          BinaryOpNode *eq = equations[endo2eq[*it]];
-
-          writeLocalVars(output, eq, local_var);
-
-          output << "residual(" << i << ")=(";
-
-          NodeID lhs = eq->get_arg1();
-          lhs->writeOutput(output, oMatlabStaticModel, temporary_terms_type());
-          output << ")-(";
+  map<pair<int, pair<int, int> >, NodeID>::const_iterator it = first_chain_rule_derivatives.find(make_pair(eqr, make_pair(varr, lag)));
+  if (it != first_chain_rule_derivatives.end())
+    (it->second)->writeOutput(output, output_type, temporary_terms);
+  else
+    output << 0;
+}
 
-          NodeID rhs = eq->get_arg2();
-          rhs->writeOutput(output, oMatlabStaticModel, temporary_terms_type());
-          output << ");" << endl;
 
-          i++;
-        }
+void
+StaticModel::writeLatexFile(const string &basename) const
+  {
+    writeLatexModelFile(basename + "_static.tex", oLatexStaticModel);
+  }
 
-      output << "      % Jacobian matrix" << endl
-             << "g1 = zeros(" << blocksMFS[b].size() << ", " << blocksMFS[b].size() << ");" << endl;
-      i = 1;
-      for (set<int>::const_iterator it = blocksMFS[b].begin();
-           it != blocksMFS[b].end(); it++)
-        {
-          int eq_no = endo2eq[*it];
-          int j = 1;
-          for (set<int>::const_iterator it2 = blocksMFS[b].begin();
-               it2 != blocksMFS[b].end(); it2++)
-            {
-              map<pair<int, int>, NodeID>::const_iterator itd = blocksMFSJacobian.find(make_pair(eq_no, *it2));
-              if (itd != blocksMFSJacobian.end())
-                {
-                  output << "g1(" << i << "," << j << ")=";
-                  itd->second->writeOutput(output, oMatlabStaticModel, temporary_terms_type());
-                  output << ";" << endl;
-                }
-              j++;
-            }
-          i++;
-        }
-    }
+void
+StaticModel::jacobianHelper(ostream &output, int eq_nb, int col_nb, ExprNodeOutputType output_type) const
+{
+  output << LEFT_ARRAY_SUBSCRIPT(output_type);
+  if (IS_MATLAB(output_type))
+    output << eq_nb + 1 << ", " << col_nb + 1;
+  else
+    output << eq_nb + col_nb * equations.size();
+  output << RIGHT_ARRAY_SUBSCRIPT(output_type);
+}
 
-  output << "  end" << endl
-         << "end" << endl;
+void
+StaticModel::hessianHelper(ostream &output, int row_nb, int col_nb, ExprNodeOutputType output_type) const
+{
+  output << LEFT_ARRAY_SUBSCRIPT(output_type);
+  if (IS_MATLAB(output_type))
+    output << row_nb + 1 << ", " << col_nb + 1;
+  else
+    output << row_nb + col_nb * NNZDerivatives[1];
+  output << RIGHT_ARRAY_SUBSCRIPT(output_type);
 }
 
 void
diff --git a/StaticModel.hh b/StaticModel.hh
index a55e8cadddf36c83ab854185a219dab5dba49e06..ae2da07418d69dbe44f0d0526fd70a0ba1702af6 100644
--- a/StaticModel.hh
+++ b/StaticModel.hh
@@ -17,86 +17,166 @@
  * along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef _STATICMODEL_HH
-#define _STATICMODEL_HH
+#ifndef _STATIC_MODEL_HH
+#define _STATIC_MODEL_HH
+
+using namespace std;
+
+#include <fstream>
 
 #include "ModelTree.hh"
 
 //! Stores a static model
-/*! Derivation IDs are allocated only for endogenous, and are equal to symbol ID in that case */
 class StaticModel : public ModelTree
 {
 private:
-  //! Normalization of equations
-  /*! Maps endogenous type specific IDs to equation numbers */
-  vector<int> endo2eq;
+  typedef map<pair<int, int>, int> deriv_id_table_t;
+  //! Maps a pair (symbol_id, lag) to a deriv ID
+  deriv_id_table_t deriv_id_table;
+  //! Maps a deriv ID to a pair (symbol_id, lag)
+  vector<pair<int, int> > inv_deriv_id_table;
 
-  //! Block decomposition of the model
-  /*! List of blocks in topological order. Lists the set of endogenous type specific IDs for each block. */
-  vector<set<int> > blocks;
+  //! Temporary terms for the file containing parameters dervicatives
+  temporary_terms_type params_derivs_temporary_terms;
 
-  //! Minimum feedback set for each block
-  /*! Elements of blocksMFS are subset of elements of blocks */
-  vector<set<int> > blocksMFS;
+  //! Temporary terms for block decomposed models
+  vector<vector<temporary_terms_type> > v_temporary_terms;
 
-  //! Variables not in minimum feedback set for each block, sorted in topological order
-  /*! This is the set difference blocks - blocksMFS. The variables are sorted in topological order. */
-  vector<vector<int> > blocksRecursive;
+  vector<temporary_terms_inuse_type> v_temporary_terms_inuse;
 
-  //! Jacobian for matrix restricted to MFS
-  /*! Maps a pair (equation ID, endogenous type specific ID) to the derivative expression. Stores only non-null derivatives. */
-  map<pair<int, int>, NodeID> blocksMFSJacobian;
+
+  typedef map< pair< int, pair< int, int> >, NodeID> first_chain_rule_derivatives_type;
+  first_chain_rule_derivatives_type first_chain_rule_derivatives;
 
   //! Writes static model file (standard Matlab version)
-  void writeStaticMFile(ostream &output, const string &func_name) const;
+  void writeStaticMFile(const string &static_basename) const;
+
+  //! Writes the static function calling the block to solve (Matlab version)
+  void writeStaticBlockMFSFile(const string &basename) const;
 
-  //! Writes static model file (block+MFS version)
-  void writeStaticBlockMFSFile(ostream &output, const string &func_name) const;
 
-  //! Computes normalization of the static model
-  void computeNormalization();
+  //! Writes static model file (C version)
+  /*! \todo add third derivatives handling */
+  void writeStaticCFile(const string &static_basename) const;
 
-  //! Computes blocks of the static model, sorted in topological order
-  /*! Must be called after computeNormalization() */
-  void computeSortedBlockDecomposition();
+  //! Writes the Block reordred structure of the model in M output
+  void writeModelEquationsOrdered_M(const string &dynamic_basename) const;
 
-  //! For each block of the static model, computes minimum feedback set (MFS)
-  /*! Must be called after computeSortedBlockDecomposition() */
-  void computeMFS();
+  //! Writes the code of the Block reordred structure of the model in virtual machine bytecode
+  void writeModelEquationsCodeOrdered(const string file_name, const string bin_basename, map_idx_type map_idx) const;
 
-  //! For each block of the static model, computes resursive variables (those not in minimum feedback set), and sort them in topological order
-  /*! Must be called after computeMFS() */
-  void computeSortedRecursive();
+  //! Computes jacobian and prepares for equation normalization
+  /*! Using values from initval/endval blocks and parameter initializations:
+    - computes the jacobian for the model w.r. to contemporaneous variables
+    - removes edges of the incidence matrix when derivative w.r. to the corresponding variable is too close to zero (below the cutoff)
+  */
+  void evaluateJacobian(const eval_context_type &eval_context, jacob_map *j_m, bool dynamic);
 
-  //! Computes derivatives of each MFS
-  /*! Must be called after computeSortedRecursive() */
-  void computeBlockMFSJacobian();
+  map_idx_type map_idx;
 
-  //! Computes the list of equations which are already in normalized form
-  /*! Returns a multimap mapping endogenous which are normalized (represented by their type specific ID) to the equation(s) which define it */
-  void computeNormalizedEquations(multimap<int, int> &endo2eqs) const;
+  void computeTemporaryTermsOrdered();
+  //! Write derivative code of an equation w.r. to a variable
+  void compileDerivative(ofstream &code_file, int eq, int symb_id, int lag, map_idx_type &map_idx) const;
+  //! Write chain rule derivative code of an equation w.r. to a variable
+  void compileChainRuleDerivative(ofstream &code_file, int eq, int var, int lag, map_idx_type &map_idx) const;
 
-  //! Helper for writing model local variables in block+MFS mode
-  /*!
-    Write the definition of model local variables which are used in expr, except those in local_var_written.
-    Add these variables to local_var_written at the end.
-  */
-  void writeLocalVars(ostream &output, NodeID expr, set<int> &local_var_written) const;
+  //! Get the type corresponding to a derivation ID
+  virtual SymbolType getTypeByDerivID(int deriv_id) const throw (UnknownDerivIDException);
+  //! Get the lag corresponding to a derivation ID
+  virtual int getLagByDerivID(int deriv_id) const throw (UnknownDerivIDException);
+  //! Get the symbol ID corresponding to a derivation ID
+  virtual int getSymbIDByDerivID(int deriv_id) const throw (UnknownDerivIDException);
+  //! Compute the column indices of the static Jacobian
+  void computeStatJacobianCols();
+  //! return a map on the block jacobian
+  map<pair<pair<int, pair<int, int> >, pair<int, int> >, int> get_Derivatives(int block);
+  //! Computes chain rule derivatives of the Jacobian w.r. to endogenous variables
+  void computeChainRuleJacobian(t_blocks_derivatives &blocks_derivatives);
+  //! Collect only the first derivatives
+  map<pair<int, pair<int, int> >, NodeID> collect_first_order_derivatives_endogenous();
+
+  //! Helper for writing the Jacobian elements in MATLAB and C
+  /*! Writes either (i+1,j+1) or [i+j*no_eq] */
+  void jacobianHelper(ostream &output, int eq_nb, int col_nb, ExprNodeOutputType output_type) const;
+
+  //! Helper for writing the sparse Hessian elements in MATLAB and C
+  /*! Writes either (i+1,j+1) or [i+j*NNZDerivatives[1]] */
+  void hessianHelper(ostream &output, int row_nb, int col_nb, ExprNodeOutputType output_type) const;
+
+  //! Write chain rule derivative of a recursive equation w.r. to a variable
+  void writeChainRuleDerivative(ostream &output, int eq, int var, int lag, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const;
+
+  //! Collecte the derivatives w.r. to endogenous of the block, to endogenous of previouys blocks and to exogenous
+  void collect_block_first_order_derivatives();
+
+protected:
+  //! Indicate if the temporary terms are computed for the overall model (true) or not (false). Default value true
+  bool global_temporary_terms;
+
+  //! vector of block reordered variables and equations
+  vector<int> equation_reordered, variable_reordered, inv_equation_reordered, inv_variable_reordered;
+
+  //! Vector describing equations: BlockSimulationType, if BlockSimulationType == EVALUATE_s then a NodeID on the new normalized equation
+  t_equation_type_and_normalized_equation equation_type_and_normalized_equation;
+
+  //! for each block contains pair< Simulation_Type, pair < Block_Size, Recursive_part_Size > >
+  t_block_type_firstequation_size_mfs block_type_firstequation_size_mfs;
+
+  //! for all blocks derivatives description
+  t_blocks_derivatives blocks_derivatives;
+
+  //! The jacobian without the elements below the cutoff
+  dynamic_jacob_map dynamic_jacobian;
+
+  //! Vector indicating if the block is linear in endogenous variable (true) or not (false)
+  vector<bool> blocks_linear;
+
+  //! Map the derivatives for a block pair<lag, make_pair(make_pair(eq, var)), NodeID>
+  typedef map<pair< int, pair<int, int> >, NodeID> t_derivative;
+  //! Vector of derivative for each blocks
+  vector<t_derivative> derivative_endo, derivative_other_endo, derivative_exo, derivative_exo_det;
+
+  //!List for each block and for each lag-leag all the other endogenous variables and exogenous variables
+  typedef set<int> t_var;
+  typedef map<int, t_var> t_lag_var;
+  vector<t_lag_var> other_endo_block, exo_block, exo_det_block;
+
+  //!Maximum lead and lag for each block on endogenous of the block, endogenous of the previous blocks, exogenous and deterministic exogenous
+  vector<pair<int, int> > endo_max_leadlag_block, other_endo_max_leadlag_block, exo_max_leadlag_block, exo_det_max_leadlag_block, max_leadlag_block;
 
 public:
   StaticModel(SymbolTable &symbol_table_arg, NumericalConstants &num_constants);
-  //! Execute computations (derivation)
-  /*!
-    \param block whether block decomposition and minimum feedback set should be computed
-    \param hessian whether Hessian (w.r. to endogenous only) should be computed
-    \param no_tmp_terms if true, no temporary terms will be computed in the static and dynamic files */
-  void computingPass(bool block, bool hessian, bool no_tmp_terms);
 
   //! Writes information on block decomposition when relevant
   void writeOutput(ostream &output, bool block) const;
 
+  //! Absolute value under which a number is considered to be zero
+  double cutoff;
+  //! Compute the minimum feedback set in the static model:
+  /*!   0 : all endogenous variables are considered as feedback variables
+				1 : the variables belonging to a non linear equation are considered as feedback variables
+        2 : the variables belonging to a non normalizable non linear equation are considered as feedback variables
+        default value = 0 */
+  int mfs;
+  //! the file containing the model and the derivatives code
+  ofstream code_file;
+  //! Execute computations (variable sorting + derivation)
+  /*!
+    \param jacobianExo whether derivatives w.r. to exo and exo_det should be in the Jacobian (derivatives w.r. to endo are always computed)
+    \param hessian whether 2nd derivatives w.r. to exo, exo_det and endo should be computed (implies jacobianExo = true)
+    \param thirdDerivatives whether 3rd derivatives w.r. to endo/exo/exo_det should be computed (implies jacobianExo = true)
+    \param paramsDerivatives whether 2nd derivatives w.r. to a pair (endo/exo/exo_det, parameter) should be computed (implies jacobianExo = true)
+    \param eval_context evaluation context for normalization
+    \param no_tmp_terms if true, no temporary terms will be computed in the static files
+  */
+  void computingPass(const eval_context_type &eval_context, bool no_tmp_terms, bool hessian, bool block);
+
+  //! Adds informations for simulation in a binary file
+  void Write_Inf_To_Bin_File(const string &static_basename, const string &bin_basename, const int &num,
+                             int &u_count_int, bool &file_open) const;
+
   //! Writes static model file
-  void writeStaticFile(const string &basename, bool block) const;
+  void writeStaticFile(const string &basename, bool block, bool bytecode) const;
 
   //! Writes LaTeX file with the equations of the static model
   void writeLatexFile(const string &basename) const;
@@ -105,6 +185,39 @@ public:
   void writeAuxVarInitval(ostream &output) const;
 
   virtual int getDerivID(int symb_id, int lag) const throw (UnknownDerivIDException);
+
+  //! Return the number of blocks
+  virtual unsigned int getNbBlocks() const {return(block_type_firstequation_size_mfs.size());};
+  //! Determine the simulation type of each block
+  virtual BlockSimulationType getBlockSimulationType(int block_number) const {return(block_type_firstequation_size_mfs[block_number].first.first);};
+  //! Return the first equation number of a block
+  virtual unsigned int getBlockFirstEquation(int block_number) const {return(block_type_firstequation_size_mfs[block_number].first.second);};
+  //! Return the size of the block block_number
+  virtual unsigned int getBlockSize(int block_number) const {return(block_type_firstequation_size_mfs[block_number].second.first);};
+  //! Return the number of feedback variable of the block block_number
+  virtual unsigned int getBlockMfs(int block_number) const {return(block_type_firstequation_size_mfs[block_number].second.second);};
+  //! Return the maximum lag in a block
+  virtual unsigned int getBlockMaxLag(int block_number) const {return(block_lag_lead[block_number].first);};
+  //! Return the maximum lead in a block
+  virtual unsigned int getBlockMaxLead(int block_number) const {return(block_lag_lead[block_number].second);};
+  //! Return the type of equation (equation_number) belonging to the block block_number
+  virtual EquationType getBlockEquationType(int block_number, int equation_number) const {return( equation_type_and_normalized_equation[equation_reordered[block_type_firstequation_size_mfs[block_number].first.second+equation_number]].first);};
+  //! Return true if the equation has been normalized
+  virtual bool isBlockEquationRenormalized(int block_number, int equation_number) const {return( equation_type_and_normalized_equation[equation_reordered[block_type_firstequation_size_mfs[block_number].first.second+equation_number]].first == E_EVALUATE_S);};
+  //! Return the NodeID of the equation equation_number belonging to the block block_number
+  virtual NodeID getBlockEquationNodeID(int block_number, int equation_number) const {return( equations[equation_reordered[block_type_firstequation_size_mfs[block_number].first.second+equation_number]]);};
+  //! Return the NodeID of the renormalized equation equation_number belonging to the block block_number
+  virtual NodeID getBlockEquationRenormalizedNodeID(int block_number, int equation_number) const {return( equation_type_and_normalized_equation[equation_reordered[block_type_firstequation_size_mfs[block_number].first.second+equation_number]].second);};
+  //! Return the original number of equation equation_number belonging to the block block_number
+  virtual int getBlockEquationID(int block_number, int equation_number) const {return( equation_reordered[block_type_firstequation_size_mfs[block_number].first.second+equation_number]);};
+  //! Return the original number of variable variable_number belonging to the block block_number
+  virtual int getBlockVariableID(int block_number, int variable_number) const {return( variable_reordered[block_type_firstequation_size_mfs[block_number].first.second+variable_number]);};
+  //! Return the position of equation_number in the block number belonging to the block block_number
+  virtual int getBlockInitialEquationID(int block_number, int equation_number) const {return((int)inv_equation_reordered[equation_number] - (int)block_type_firstequation_size_mfs[block_number].first.second);};
+  //! Return the position of variable_number in the block number belonging to the block block_number
+  virtual int getBlockInitialVariableID(int block_number, int variable_number) const {return((int)inv_variable_reordered[variable_number] - (int)block_type_firstequation_size_mfs[block_number].first.second);};
+
+
 };
 
 #endif