diff --git a/src/DynamicModel.cc b/src/DynamicModel.cc
index 9369fc6bf9cc7f55410c99edb2e6941e0565083c..6e1ed53cb69be10da0877efecdd6d0878e6b14a8 100644
--- a/src/DynamicModel.cc
+++ b/src/DynamicModel.cc
@@ -455,7 +455,7 @@ DynamicModel::writeModelEquationsOrdered_M(const string &basename) const
           if (simulation_type == BlockSimulationType::solveTwoBoundariesComplete
               || simulation_type == BlockSimulationType::solveTwoBoundariesSimple)
             output << "    g1 = spalloc(" << block_mfs << "*Periods, "
-                   << block_mfs << "*(Periods+" << max_leadlag_block[block].first+max_leadlag_block[block].second+1 << ")"
+                   << block_mfs << "*(Periods+" << blocks[block].max_lag+blocks[block].max_lead+1 << ")"
                    << ", " << nze << "*Periods);" << endl;
           else
             output << "    g1 = spalloc(" << block_mfs
@@ -1155,8 +1155,8 @@ DynamicModel::writeModelEquationsCode_Block(const string &basename, const map_id
       int block_size = blocks[block].size;
       int block_mfs = blocks[block].mfs_size;
       int block_recursive = blocks[block].getRecursiveSize();
-      int block_max_lag = max_leadlag_block[block].first;
-      int block_max_lead = max_leadlag_block[block].second;
+      int block_max_lag = blocks[block].max_lag;
+      int block_max_lead = blocks[block].max_lead;
 
       if (simulation_type == BlockSimulationType::solveTwoBoundariesSimple
           || simulation_type == BlockSimulationType::solveTwoBoundariesComplete
@@ -2125,8 +2125,8 @@ DynamicModel::writeSparseDynamicMFile(const string &basename) const
                             << "  end;" << endl
                             << "  [y oo_] = solve_two_boundaries('" << basename << ".block.dynamic_" <<  block + 1 << "'"
                             <<", y, x, params, steady_state, y_index, " << nze
-                            <<", options_.periods, " << max_leadlag_block[block].first
-                            <<", " << max_leadlag_block[block].second
+                            <<", options_.periods, " << blocks[block].max_lag
+                            <<", " << blocks[block].max_lead
                             <<", " << blocks[block].linear
                             <<", blck_num, y_kmin, options_.simul.maxit, options_.solve_tolf, options_.slowc, " << cutoff << ", options_.stack_solve_algo, options_, M_, oo_);" << endl
                             << "  tmp = y(:,M_.block_structure.block(" << block + 1 << ").variable);" << endl
@@ -3122,14 +3122,14 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block_de
           count_lead_lag_incidence = 0;
           BlockSimulationType simulation_type = blocks[block].simulation_type;
           int block_size = blocks[block].size;
-          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 = exo_max_leadlag_block[block].first;
-          max_lead_exo = exo_max_leadlag_block[block].second;
-          max_lag_exo_det = exo_det_max_leadlag_block[block].first;
-          max_lead_exo_det = exo_det_max_leadlag_block[block].second;
+          max_lag = blocks[block].max_lag;
+          max_lead = blocks[block].max_lead;
+          max_lag_endo = blocks[block].max_endo_lag;
+          max_lead_endo = blocks[block].max_endo_lead;
+          max_lag_exo = blocks[block].max_exo_lag;
+          max_lead_exo = blocks[block].max_exo_lead;
+          max_lag_exo_det = blocks[block].max_exo_det_lag;
+          max_lead_exo_det = blocks[block].max_exo_det_lead;
           ostringstream tmp_s, tmp_s_eq;
           tmp_s.str("");
           tmp_s_eq.str("");
@@ -3224,8 +3224,6 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block_de
           output << "block_structure.block(" << block+1 << ").lead_lag_incidence = [];" << endl;
           int last_var = -1;
           vector<int> local_state_var;
-          vector<int> local_stat_var;
-          int n_static = 0, n_backward = 0, n_forward = 0, n_mixed = 0;
           for (int lag = -1; lag < 1+1; lag++)
             {
               last_var = -1;
@@ -3234,32 +3232,7 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block_de
                   if (lag == get<0>(it.first) && last_var != get<1>(it.first))
                     {
                       if (lag == -1)
-                        {
-                          local_state_var.push_back(getBlockVariableID(block, get<1>(it.first))+1);
-                          n_backward++;
-                        }
-                      else if (lag == 0)
-                        {
-                          if (find(local_state_var.begin(), local_state_var.end(), getBlockVariableID(block, get<1>(it.first))+1) == local_state_var.end())
-                            {
-                              local_stat_var.push_back(getBlockVariableID(block, get<1>(it.first))+1);
-                              n_static++;
-                            }
-                        }
-                      else
-                        {
-                          if (find(local_state_var.begin(), local_state_var.end(), getBlockVariableID(block, get<1>(it.first))+1) != local_state_var.end())
-                            {
-                              n_backward--;
-                              n_mixed++;
-                            }
-                          else
-                            {
-                              if (find(local_stat_var.begin(), local_stat_var.end(), getBlockVariableID(block, get<1>(it.first))+1) != local_stat_var.end())
-                                n_static--;
-                              n_forward++;
-                            }
-                        }
+                        local_state_var.push_back(getBlockVariableID(block, get<1>(it.first))+1);
                       count_lead_lag_incidence++;
                       for (int i = last_var; i < get<1>(it.first)-1; i++)
                         tmp_s << " 0";
@@ -3308,10 +3281,10 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block_de
                 }
               output << "block_structure.block(" << block+1 << ").lead_lag_incidence_other = [ block_structure.block(" << block+1 << ").lead_lag_incidence_other; " << tmp_s.str() << "]; %lag = " << lag << endl;
             }
-          output << "block_structure.block(" << block+1 << ").n_static = " << n_static << ";" << endl
-                 << "block_structure.block(" << block+1 << ").n_forward = " << n_forward << ";" << endl
-                 << "block_structure.block(" << block+1 << ").n_backward = " << n_backward << ";" << endl
-                 << "block_structure.block(" << block+1 << ").n_mixed = " << n_mixed << ";" << endl;
+          output << "block_structure.block(" << block+1 << ").n_static = " << blocks[block].n_static << ";" << endl
+                 << "block_structure.block(" << block+1 << ").n_forward = " << blocks[block].n_forward << ";" << endl
+                 << "block_structure.block(" << block+1 << ").n_backward = " << blocks[block].n_backward << ";" << endl
+                 << "block_structure.block(" << block+1 << ").n_mixed = " << blocks[block].n_mixed << ";" << endl;
         }
       output << modstruct << "block_structure.block = block_structure.block;" << endl;
       string cst_s;
@@ -4782,7 +4755,7 @@ DynamicModel::computingPass(bool jacobianExo, int derivsOrder, int paramsDerivsO
 
       equationTypeDetermination(first_order_endo_derivatives, 0);
 
-      reduceBlocksAndTypeDetermination(linear_decomposition);
+      reduceBlocksAndTypeDetermination();
 
       computeChainRuleJacobian();
 
@@ -4812,7 +4785,7 @@ DynamicModel::computingPass(bool jacobianExo, int derivsOrder, int paramsDerivsO
 
       computeBlockDecompositionAndFeedbackVariablesForEachBlock();
 
-      reduceBlocksAndTypeDetermination(linear_decomposition);
+      reduceBlocksAndTypeDetermination();
 
       printBlockDecomposition();
 
@@ -5030,37 +5003,19 @@ DynamicModel::collect_block_first_order_derivatives()
   derivative_other_endo = vector<derivative_t>(nb_blocks);
   derivative_exo = vector<derivative_t>(nb_blocks);
   derivative_exo_det = vector<derivative_t>(nb_blocks);
-  endo_max_leadlag_block = vector<pair<int, int>>(nb_blocks, { 0, 0 });
-  other_endo_max_leadlag_block = vector<pair<int, int>>(nb_blocks, { 0, 0 });
-  exo_max_leadlag_block = vector<pair<int, int>>(nb_blocks, { 0, 0 });
-  exo_det_max_leadlag_block = vector<pair<int, int>>(nb_blocks, { 0, 0 });
-  max_leadlag_block = vector<pair<int, int>>(nb_blocks, { 0, 0 });
   for (auto & [indices, d1] : derivatives[1])
     {
       int eq = indices[0];
       int var = symbol_table.getTypeSpecificID(getSymbIDByDerivID(indices[1]));
       int lag = getLagByDerivID(indices[1]);
       int block_eq = eq2block[eq];
-      int block_var = 0;
       derivative_t tmp_derivative;
       lag_var_t lag_var;
       switch (getTypeByDerivID(indices[1]))
         {
         case SymbolType::endogenous:
-          block_var = endo2block[var];
-          if (block_eq == block_var)
-            {
-              if (lag < 0 && lag < -endo_max_leadlag_block[block_eq].first)
-                endo_max_leadlag_block[block_eq] = { -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] = { endo_max_leadlag_block[block_eq].first, lag };
-            }
-          else
+          if (block_eq != endo2block[var])
             {
-              if (lag < 0 && lag < -other_endo_max_leadlag_block[block_eq].first)
-                other_endo_max_leadlag_block[block_eq] = { -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] = { other_endo_max_leadlag_block[block_eq].first, lag };
               tmp_derivative = derivative_other_endo[block_eq];
 
               if (auto it = block_other_endo_index.find(block_eq);
@@ -5084,10 +5039,6 @@ DynamicModel::collect_block_first_order_derivatives()
             }
           break;
         case SymbolType::exogenous:
-          if (lag < 0 && lag < -exo_max_leadlag_block[block_eq].first)
-            exo_max_leadlag_block[block_eq] = { -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] = { exo_max_leadlag_block[block_eq].first, lag };
           tmp_derivative = derivative_exo[block_eq];
 
           if (auto it = block_exo_index.find(block_eq);
@@ -5110,10 +5061,6 @@ DynamicModel::collect_block_first_order_derivatives()
           exo_block[block_eq] = lag_var;
           break;
         case SymbolType::exogenousDet:
-          if (lag < 0 && lag < -exo_det_max_leadlag_block[block_eq].first)
-            exo_det_max_leadlag_block[block_eq] = { -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] = { exo_det_max_leadlag_block[block_eq].first, lag };
           tmp_derivative = derivative_exo_det[block_eq];
 
           if (auto it = block_det_exo_index.find(block_eq);
@@ -5138,10 +5085,6 @@ DynamicModel::collect_block_first_order_derivatives()
         default:
           break;
         }
-      if (lag < 0 && lag < -max_leadlag_block[block_eq].first)
-        max_leadlag_block[block_eq] = { -lag, max_leadlag_block[block_eq].second };
-      if (lag > 0 && lag > max_leadlag_block[block_eq].second)
-        max_leadlag_block[block_eq] = { max_leadlag_block[block_eq].first, lag };
     }
 }
 
diff --git a/src/ModelTree.cc b/src/ModelTree.cc
index 01f4ddaf6d98427120d4f9e43ece64fbea0f6fa8..3a00a8ed3abd4a73b73d1a0b9586c7b61eae27d7 100644
--- a/src/ModelTree.cc
+++ b/src/ModelTree.cc
@@ -156,11 +156,6 @@ ModelTree::ModelTree(const ModelTree &m) :
   eq_idx_orig2block{m.eq_idx_orig2block},
   endo_idx_orig2block{m.endo_idx_orig2block},
   map_idx{m.map_idx},
-  endo_max_leadlag_block{m.endo_max_leadlag_block},
-  other_endo_max_leadlag_block{m.other_endo_max_leadlag_block},
-  exo_max_leadlag_block{m.exo_max_leadlag_block},
-  exo_det_max_leadlag_block{m.exo_det_max_leadlag_block},
-  max_leadlag_block{m.max_leadlag_block},
   blocks{m.blocks},
   endo2block{m.endo2block},
   eq2block{m.eq2block},
@@ -210,11 +205,6 @@ ModelTree::operator=(const ModelTree &m)
   derivative_other_endo.clear();
   derivative_exo.clear();
   derivative_exo_det.clear();
-  endo_max_leadlag_block = m.endo_max_leadlag_block;
-  other_endo_max_leadlag_block = m.other_endo_max_leadlag_block;
-  exo_max_leadlag_block = m.exo_max_leadlag_block;
-  exo_det_max_leadlag_block = m.exo_det_max_leadlag_block;
-  max_leadlag_block = m.max_leadlag_block;
   blocks = m.blocks;
   endo2block = m.endo2block;
   eq2block = m.eq2block;
@@ -437,21 +427,8 @@ ModelTree::select_non_linear_equations_and_variables()
   blocks.resize(1);
   blocks[0].size = i;
   blocks[0].mfs_size = i;
-
-  auto [equation_lag_lead, variable_lag_lead] = getVariableLeadLagByBlock();
-
-  for (int i = 0; i < blocks[0].size; i++)
-    {
-      auto [max_lag, max_lead] = variable_lag_lead[endo_idx_block2orig[i]];
-      if (max_lag != 0 && max_lead != 0)
-        blocks[0].n_mixed++;
-      else if (max_lag == 0 && max_lead != 0)
-        blocks[0].n_forward++;
-      else if (max_lag != 0 && max_lead == 0)
-        blocks[0].n_backward++;
-      else
-        blocks[0].n_static++;
-    }
+  blocks[0].first_equation = 0;
+  computeDynamicStructureOfBlock(0);
 }
 
 bool
@@ -625,6 +602,75 @@ ModelTree::equationTypeDetermination(const map<tuple<int, int, int>, expr_t> &fi
     }
 }
 
+void
+ModelTree::computeDynamicStructureOfBlock(int blk)
+{
+  vector<pair<int, int>> max_endo_lag_lead(blocks[blk].size, { 0, 0 });
+  blocks[blk].max_endo_lag = blocks[blk].max_endo_lead = 0;
+  blocks[blk].max_other_endo_lag = blocks[blk].max_other_endo_lead = 0;
+  blocks[blk].max_exo_lag = blocks[blk].max_exo_lead = 0;
+  blocks[blk].max_exo_det_lag = blocks[blk].max_exo_det_lead = 0;
+  for (int eq = 0; eq < blocks[blk].size; eq++)
+    {
+      set<pair<int, int>> endos_and_lags;
+      expr_t e = getBlockEquationExpr(blk, eq);
+
+      /* Compute max lags/leads for endogenous. Also fill per-variable structure
+         for endos belonging to this block */
+      e->collectEndogenous(endos_and_lags);
+      for (auto [endo, lag] : endos_and_lags)
+        if (endo2block[endo] == blk)
+          {
+            blocks[blk].max_endo_lag = max(blocks[blk].max_endo_lag, -lag);
+            blocks[blk].max_endo_lead = max(blocks[blk].max_endo_lead, lag);
+            auto &[max_endo_lag, max_endo_lead] = max_endo_lag_lead[getBlockInitialVariableID(blk, endo)];
+            max_endo_lag = max(max_endo_lag, -lag);
+            max_endo_lead = max(max_endo_lead, lag);
+          }
+        else
+          {
+            blocks[blk].max_other_endo_lag = max(blocks[blk].max_other_endo_lag, -lag);
+            blocks[blk].max_other_endo_lead = max(blocks[blk].max_other_endo_lead, lag);
+          }
+
+      // Compute max lags/leads for exogenous
+      blocks[blk].max_exo_lag = max(e->maxExoLag(), blocks[blk].max_exo_lag);
+      blocks[blk].max_exo_lead = max(e->maxExoLead(), blocks[blk].max_exo_lead);
+
+      // Compute max lags/leads for deterministic exogenous
+      set<pair<int, int>> dynvars;
+      e->collectDynamicVariables(SymbolType::exogenousDet, dynvars);
+      for (auto [symb_id, lag] : dynvars)
+        {
+          blocks[blk].max_exo_det_lag = max(-lag, blocks[blk].max_exo_det_lag);
+          blocks[blk].max_exo_det_lead = max(lag, blocks[blk].max_exo_det_lead);
+        }
+    }
+
+  // Compute max lags/leads over all variables
+  blocks[blk].max_lag = max(blocks[blk].max_endo_lag, max(blocks[blk].max_other_endo_lag,
+                                                          max(blocks[blk].max_exo_lag,
+                                                              blocks[blk].max_exo_det_lag)));
+  blocks[blk].max_lead = max(blocks[blk].max_endo_lead, max(blocks[blk].max_other_endo_lead,
+                                                            max(blocks[blk].max_exo_lead,
+                                                                blocks[blk].max_exo_det_lead)));
+
+  // Categorize endos that belong to the block
+  blocks[blk].n_mixed = blocks[blk].n_forward = blocks[blk].n_backward = blocks[blk].n_static = 0;
+  for (int var = 0; var < blocks[blk].size; var++)
+    {
+      auto [max_lag, max_lead] = max_endo_lag_lead[var];
+      if (max_lag != 0 && max_lead != 0)
+        blocks[blk].n_mixed++;
+      else if (max_lag == 0 && max_lead != 0)
+        blocks[blk].n_forward++;
+      else if (max_lag != 0 && max_lead == 0)
+        blocks[blk].n_backward++;
+      else
+        blocks[blk].n_static++;
+    }
+}
+
 pair<lag_lead_vector_t, lag_lead_vector_t>
 ModelTree::getVariableLeadLagByBlock() const
 {
@@ -708,21 +754,6 @@ ModelTree::computeBlockDecompositionAndFeedbackVariablesForEachBlock()
   // Determine the dynamic structure of each block
   auto [equation_lag_lead, variable_lag_lead] = getVariableLeadLagByBlock();
 
-  for (int var = 0; var < nb_var; var++)
-    {
-      auto [max_lag, max_lead] = variable_lag_lead[endo_idx_block2orig[var]];
-      int blk = endo2block[endo_idx_block2orig[var]];
-
-      if (max_lag != 0 && max_lead != 0)
-        blocks[blk].n_mixed++;
-      else if (max_lag == 0 && max_lead != 0)
-        blocks[blk].n_forward++;
-      else if (max_lag != 0 && max_lead == 0)
-        blocks[blk].n_backward++;
-      else
-        blocks[blk].n_static++;
-    }
-
   /* For each simultaneous block, the minimum set of feedback variable is computed.
      Then, the variables within the blocks are reordered so that recursive
      (non-feedback) appear first, to get a sub-recursive block without feedback variables.
@@ -779,6 +810,9 @@ ModelTree::computeBlockDecompositionAndFeedbackVariablesForEachBlock()
     }
 
   updateReverseVariableEquationOrderings();
+
+  for (int blk = 0; blk < static_cast<int>(blocks.size()); blk++)
+    computeDynamicStructureOfBlock(blk);
 }
 
 void
@@ -809,28 +843,13 @@ ModelTree::printBlockDecomposition() const
 }
 
 void
-ModelTree::reduceBlocksAndTypeDetermination(bool linear_decomposition)
+ModelTree::reduceBlocksAndTypeDetermination()
 {
   for (int blk = 0; blk < static_cast<int>(blocks.size()); blk++)
     {
-      /* Compute the maximum lead and lag across all endogenous that appear in
-         this block and that belong to it */
-      int max_lag = 0, max_lead = 0;
-      for (int eq = 0; eq < blocks[blk].size; eq++)
-        {
-          set<pair<int, int>> endos_and_lags;
-          getBlockEquationExpr(blk, eq)->collectEndogenous(endos_and_lags);
-          for (const auto &[endo, lag] : endos_and_lags)
-            if (linear_decomposition || endo2block[endo] == blk)
-              {
-                max_lead = max(lag, max_lead);
-                max_lag = max(-lag, max_lag);
-              }
-        }
-
       // Determine the block type
       BlockSimulationType Simulation_Type;
-      if (max_lag > 0 && max_lead > 0)
+      if (blocks[blk].max_endo_lag > 0 && blocks[blk].max_endo_lead > 0)
         {
           if (blocks[blk].size == 1)
             Simulation_Type = BlockSimulationType::solveTwoBoundariesSimple;
@@ -839,14 +858,14 @@ ModelTree::reduceBlocksAndTypeDetermination(bool linear_decomposition)
         }
       else if (blocks[blk].size > 1)
         {
-          if (max_lead > 0)
+          if (blocks[blk].max_endo_lead > 0)
             Simulation_Type = BlockSimulationType::solveBackwardComplete;
           else
             Simulation_Type = BlockSimulationType::solveForwardComplete;
         }
       else
         {
-          if (max_lead > 0)
+          if (blocks[blk].max_endo_lead > 0)
             Simulation_Type = BlockSimulationType::solveBackwardSimple;
           else
             Simulation_Type = BlockSimulationType::solveForwardSimple;
@@ -894,12 +913,7 @@ ModelTree::reduceBlocksAndTypeDetermination(bool linear_decomposition)
                      We need to consider the case where a variable of the
                      previous block appears with a lag/lead in the current one
                      (the reverse case is excluded, by construction). */
-                  blocks[blk-1].max_lag = is_lag ? 1 : max(blocks[blk-1].max_lag, max_lag);
-                  blocks[blk-1].max_lead = is_lead ? 1 : max(blocks[blk-1].max_lead, max_lead);
-                  blocks[blk-1].n_static += blocks[blk].n_static;
-                  blocks[blk-1].n_forward += blocks[blk].n_forward;
-                  blocks[blk-1].n_backward += blocks[blk].n_backward;
-                  blocks[blk-1].n_mixed += blocks[blk].n_mixed;
+                  computeDynamicStructureOfBlock(blk-1);
                   blocks.erase(blocks.begin()+blk);
                   for (auto &b : endo2block)
                     if (b >= blk)
@@ -914,8 +928,6 @@ ModelTree::reduceBlocksAndTypeDetermination(bool linear_decomposition)
         }
 
       blocks[blk].simulation_type = Simulation_Type;
-      blocks[blk].max_lag = max_lag;
-      blocks[blk].max_lead = max_lead;
     }
 }
 
diff --git a/src/ModelTree.hh b/src/ModelTree.hh
index e33b3aa72cc46ade57c46913dd3199b9f759e9f3..c29dbd22e2349b70484de3c5f9e9fb943e58a68f 100644
--- a/src/ModelTree.hh
+++ b/src/ModelTree.hh
@@ -180,9 +180,6 @@ protected:
   //! Vector of derivative for each blocks
   vector<derivative_t> derivative_other_endo, derivative_exo, derivative_exo_det;
 
-  //!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;
-
   class BlockInfo
   {
   public:
@@ -192,7 +189,11 @@ protected:
     int mfs_size{0}; // Size of the minimal feedback set
     bool linear{true}; // Whether the block is linear in endogenous variable
     int n_static{0}, n_forward{0}, n_backward{0}, n_mixed{0};
-    int max_lag{0}, max_lead{0};
+    int max_endo_lag{0}, max_endo_lead{0}; // Maximum lag/lead on endos that appear in and *that belong to* the block
+    int max_other_endo_lag{0}, max_other_endo_lead{0}; // Maximum lag/lead on endos that appear in but do not belong to the block
+    int max_exo_lag{0}, max_exo_lead{0};
+    int max_exo_det_lag{0}, max_exo_det_lead{0};
+    int max_lag{0}, max_lead{0}; // The max over all endo/exo variables
 
     inline int getRecursiveSize() const { return size - mfs_size; };
   };
@@ -299,18 +300,21 @@ protected:
   void computePrologueAndEpilogue();
   //! Determine the type of each equation of model and try to normalize the unnormalized equation
   void equationTypeDetermination(const map<tuple<int, int, int>, expr_t> &first_order_endo_derivatives, int mfs);
+  /* Fills the max lags/leads and n_{static,mixed,forward,backward} fields of a
+     given block.
+     Needs the fields size and first_equation. */
+  void computeDynamicStructureOfBlock(int blk);
   /* Compute the block decomposition and for a non-recusive block find the minimum feedback set
 
      Initializes the “blocks” structure, and fills the following fields: size, first_equation,
-     mfs_size, n_static, n_forward, n_backward, n_mixed.
+     mfs_size, n_static, n_forward, n_backward, n_mixed, maximum lags/leads.
      Also initializes the endo2block and eq2block structures. */
   void computeBlockDecompositionAndFeedbackVariablesForEachBlock();
   /* Reduce the number of block by merging the same type of equations in the
      prologue and the epilogue, and determine the type of each block.
 
-     Fills the following fields of the “blocks” structure: simulation_type,
-     max_lead, max_lag. */
-  void reduceBlocksAndTypeDetermination(bool linear_decomposition);
+     Fills the “simulation_type” field of the “blocks” structure.  */
+  void reduceBlocksAndTypeDetermination();
   /* The 1st output gives, for each equation (in original order) the (max_lag,
      max_lead) across all endogenous that appear in the equation and that
      belong to the same block (i.e. those endogenous are solved in the same
diff --git a/src/StaticModel.cc b/src/StaticModel.cc
index 6df1a0c51628bac84db03930fe4a16cd11b42cd9..82ecd946079968a06a2d4be5e6ace8469ba1c42a 100644
--- a/src/StaticModel.cc
+++ b/src/StaticModel.cc
@@ -1135,7 +1135,7 @@ StaticModel::computingPass(int derivsOrder, int paramsDerivsOrder, const eval_co
 
       computeBlockDecompositionAndFeedbackVariablesForEachBlock();
 
-      reduceBlocksAndTypeDetermination(false);
+      reduceBlocksAndTypeDetermination();
 
       printBlockDecomposition();
 
@@ -1143,8 +1143,6 @@ StaticModel::computingPass(int derivsOrder, int paramsDerivsOrder, const eval_co
 
       determineLinearBlocks();
 
-      collect_block_first_order_derivatives();
-
       global_temporary_terms = true;
       if (!no_tmp_terms)
         computeTemporaryTermsOrdered();
@@ -2138,15 +2136,6 @@ StaticModel::computeChainRuleJacobian()
     }
 }
 
-void
-StaticModel::collect_block_first_order_derivatives()
-{
-  endo_max_leadlag_block.clear();
-  endo_max_leadlag_block.resize(blocks.size(), { 0, 0 });
-  max_leadlag_block.clear();
-  max_leadlag_block.resize(blocks.size(), { 0, 0 });
-}
-
 void
 StaticModel::writeLatexFile(const string &basename, bool write_equation_tags) const
 {
diff --git a/src/StaticModel.hh b/src/StaticModel.hh
index 6a49dcd1c8ea85db5cce17f7edad5a9871dd5aed..4dd3a204e99af86694f72e87094aed746c253309 100644
--- a/src/StaticModel.hh
+++ b/src/StaticModel.hh
@@ -90,9 +90,6 @@ private:
   //! Computes chain rule derivatives of the Jacobian w.r. to endogenous variables
   void computeChainRuleJacobian();
 
-  //! Collecte the derivatives w.r. to endogenous of the block, to endogenous of previouys blocks and to exogenous
-  void collect_block_first_order_derivatives();
-
   //! Indicate if the temporary terms are computed for the overall model (true) or not (false). Default value true
   bool global_temporary_terms{true};