diff --git a/BlockTriangular.cc b/BlockTriangular.cc
index f99683992d5cd6e72616ce2f13b1af22ba9bf2b8..370eed674be918e8d2e374654eac81ea00e2e884 100644
--- a/BlockTriangular.cc
+++ b/BlockTriangular.cc
@@ -125,7 +125,7 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block
   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(symbol_table.endo_nbr * sizeof(int));
+  tmp_other_endo = (int*)malloc(symbol_table.endo_nbr() * sizeof(int));
   tmp_size = (int*)malloc((incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1) * sizeof(int));
   //cout << "tmp_size = (int*)malloc((incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1= " << incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1 << ") * sizeof(int))\n";
   tmp_size_other_endo = (int*)malloc((incidencematrix.Model_Max_Lead + incidencematrix.Model_Max_Lag + 1) * sizeof(int));
@@ -134,13 +134,13 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block
   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, symbol_table.endo_nbr*sizeof(int));
+  memset(tmp_other_endo, 0, symbol_table.endo_nbr()*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));
+  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 ();
@@ -158,7 +158,7 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block
                 {
                   for (j = 0;j < size;j++)
                     {
-                      if (Cur_IM[i_1 + Index_Equ_IM[first_count_equ + j].index*symbol_table.endo_nbr])
+                      if (Cur_IM[i_1 + Index_Equ_IM[first_count_equ + j].index*symbol_table.endo_nbr()])
                         {
                           tmp_variable_evaluated[i_1] = true;
                           tmp_size[incidencematrix.Model_Max_Lag_Endo + k]++;
@@ -177,7 +177,7 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block
                 {
                   for (j = 0;j < size;j++)
                     {
-                      if (Cur_IM[i_1 + Index_Equ_IM[first_count_equ + j].index*symbol_table.endo_nbr])
+                      if (Cur_IM[i_1 + Index_Equ_IM[first_count_equ + j].index*symbol_table.endo_nbr()])
                         {
                           tmp_variable_evaluated[i_1] = true;
                           tmp_size[incidencematrix.Model_Max_Lag_Endo + k]++;
@@ -208,8 +208,8 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block
           Cur_IM = incidencematrix.Get_IM(k, eEndogenous);
           if (Cur_IM)
             {
-              i_1 = Index_Equ_IM[first_count_equ+i].index * symbol_table.endo_nbr;
-              for (j = 0;j < symbol_table.endo_nbr;j++)
+              i_1 = Index_Equ_IM[first_count_equ+i].index * symbol_table.endo_nbr();
+              for (j = 0;j < symbol_table.endo_nbr();j++)
                 if (Cur_IM[i_1 + j])
                   {
                     if (!tmp_variable_evaluated[j])
@@ -234,8 +234,8 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block
   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_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++)
     {
@@ -244,8 +244,8 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block
           Cur_IM = incidencematrix.Get_IM(k, eExogenous);
           if (Cur_IM)
             {
-              i_1 = Index_Equ_IM[first_count_equ+i].index * symbol_table.exo_nbr;
-              for (j=0;j<symbol_table.exo_nbr;j++)
+              i_1 = Index_Equ_IM[first_count_equ+i].index * symbol_table.exo_nbr();
+              for (j=0;j<symbol_table.exo_nbr();j++)
                 if (Cur_IM[i_1 + j])
                   {
                     if (!tmp_exo[j])
@@ -271,7 +271,7 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block
   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++)
+  for (j=0;j<symbol_table.exo_nbr();j++)
     if (tmp_exo[j])
       {
         ModelBlock->Block_List[count_Block].Exogenous[k] = j;
@@ -325,7 +325,7 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block
       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));
+      memset(tmp_variable_evaluated, 0, symbol_table.endo_nbr()*sizeof(bool));
       IM = incidencematrix.Get_IM(i - Lag, eEndogenous);
       if (IM)
         {
@@ -334,7 +334,7 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block
               i_1 = Index_Var_IM[j].index;
               m = 0;
               for (k = first_count_equ;k < size + first_count_equ;k++)
-                if (IM[i_1 + Index_Equ_IM[k].index*symbol_table.endo_nbr])
+                if (IM[i_1 + Index_Equ_IM[k].index*symbol_table.endo_nbr()])
                   m++;
               if (m > 0)
                 {
@@ -345,7 +345,7 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block
           m = 0;
           for (j = first_count_equ;j < size + first_count_equ;j++)
             {
-              i_1 = Index_Equ_IM[j].index * symbol_table.endo_nbr;
+              i_1 = Index_Equ_IM[j].index * symbol_table.endo_nbr();
               for (k = first_count_equ;k < size + first_count_equ;k++)
                 if (IM[Index_Var_IM[k].index + i_1])
                   {
@@ -369,8 +369,8 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block
           m = 0;
           for (j = first_count_equ;j < size + first_count_equ;j++)
             {
-              i_1 = Index_Equ_IM[j].index * symbol_table.endo_nbr;
-              for (k = 0;k < symbol_table.endo_nbr;k++)
+              i_1 = Index_Equ_IM[j].index * symbol_table.endo_nbr();
+              for (k = 0;k < symbol_table.endo_nbr();k++)
                 if ((!tmp_variable_evaluated[Index_Var_IM[k].index]) && IM[Index_Var_IM[k].index + i_1])
                   {
                     ModelBlock->Block_List[count_Block].IM_lead_lag[i].u_other_endo[m] = l;
@@ -390,7 +390,7 @@ BlockTriangular::Allocate_Block(int size, int *count_Equ, int count_Block, Block
           m = 0;
           for (j = first_count_equ;j < size + first_count_equ;j++)
             {
-              i_1 = Index_Equ_IM[j].index * symbol_table.exo_nbr;
+              i_1 = Index_Equ_IM[j].index * symbol_table.exo_nbr();
               for (k = 0; k<tmp_nb_exo; k++)
                 {
                   if (IM[ModelBlock->Block_List[count_Block].Exogenous[k]+i_1])
@@ -505,7 +505,7 @@ BlockTriangular::Reduce_Blocks_and_type_determination(int prologue, int epilogue
                 {
                   for (int j = 0;j < Blck_Size;j++)
                     {
-                      if (Cur_IM[i_1 + Index_Equ_IM[first_count_equ + j].index*symbol_table.endo_nbr])
+                      if (Cur_IM[i_1 + Index_Equ_IM[first_count_equ + j].index*symbol_table.endo_nbr()])
                         {
                           if (k > Lead)
                             Lead = k;
@@ -709,7 +709,7 @@ BlockTriangular::Normalize_and_BlockDecompose(bool* IM, Model_Block* ModelBlock,
   free(Equation_gr);
 
 
-  blocks.block_result_to_IM(res, IM, *prologue, symbol_table.endo_nbr, Index_Equ_IM, Index_Var_IM);
+  blocks.block_result_to_IM(res, IM, *prologue, symbol_table.endo_nbr(), Index_Equ_IM, Index_Var_IM);
 
 
   t_type  Type = Reduce_Blocks_and_type_determination(*prologue, *epilogue, res, equations);
@@ -773,15 +773,15 @@ BlockTriangular::Normalize_and_BlockDecompose_Static_0_Model(const jacob_map &j_
   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);
+  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 (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++)
+          for (i = 0;i < symbol_table.endo_nbr()*symbol_table.endo_nbr();i++)
             {
               SIM[i] = (SIM[i]) || (Cur_IM[i]);
             }
@@ -792,13 +792,13 @@ BlockTriangular::Normalize_and_BlockDecompose_Static_0_Model(const jacob_map &j_
       cout << "incidence matrix for the static model (unsorted) \n";
       incidencematrix.Print_SIM(SIM, eEndogenous);
     }
-  Index_Equ_IM = (simple*)malloc(symbol_table.endo_nbr * sizeof(*Index_Equ_IM));
-  for (i = 0;i < symbol_table.endo_nbr;i++)
+  Index_Equ_IM = (simple*)malloc(symbol_table.endo_nbr() * sizeof(*Index_Equ_IM));
+  for (i = 0;i < symbol_table.endo_nbr();i++)
     {
       Index_Equ_IM[i].index = i;
     }
-  Index_Var_IM = (simple*)malloc(symbol_table.endo_nbr * sizeof(*Index_Var_IM));
-  for (i = 0;i < symbol_table.endo_nbr;i++)
+  Index_Var_IM = (simple*)malloc(symbol_table.endo_nbr() * sizeof(*Index_Var_IM));
+  for (i = 0;i < symbol_table.endo_nbr();i++)
     {
       Index_Var_IM[i].index = i;
     }
@@ -806,10 +806,10 @@ BlockTriangular::Normalize_and_BlockDecompose_Static_0_Model(const jacob_map &j_
     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 = (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, 1, 1, SIM_0, j_m, equations);
+  Normalize_and_BlockDecompose(SIM, ModelBlock, symbol_table.endo_nbr(), &prologue, &epilogue, Index_Var_IM, Index_Equ_IM, 1, 1, SIM_0, j_m, equations);
   free(SIM_0);
   free(SIM);
 }
diff --git a/ComputingTasks.cc b/ComputingTasks.cc
index 661ec6c5a283b2248898d4e26162d0a179931b5a..188d17860cf5301c7edb32003a10a05cf0623990 100644
--- a/ComputingTasks.cc
+++ b/ComputingTasks.cc
@@ -423,7 +423,7 @@ EstimatedParamsStatement::writeOutput(ostream &output, const string &basename) c
 
   for(it = estim_params_list.begin(); it != estim_params_list.end(); it++)
     {
-      int symb_id = symbol_table.getID(it->name) + 1;
+      int symb_id = symbol_table.getTypeSpecificID(it->name) + 1;
       SymbolType symb_type = symbol_table.getType(it->name);
 
       switch(it->type)
@@ -444,7 +444,7 @@ EstimatedParamsStatement::writeOutput(ostream &output, const string &basename) c
             output << "estim_params_.corrx = [estim_params_.corrx; ";
           else if (symb_type == eEndogenous)
             output << "estim_params_.corrn = [estim_params_.corrn; ";
-          output << symb_id << " " << symbol_table.getID(it->name2)+1;
+          output << symb_id << " " << symbol_table.getTypeSpecificID(it->name2)+1;
           break;
         }
       output << ", ";
@@ -482,7 +482,7 @@ EstimatedParamsInitStatement::writeOutput(ostream &output, const string &basenam
 
   for(it = estim_params_list.begin(); it != estim_params_list.end(); it++)
     {
-      int symb_id = symbol_table.getID(it->name) + 1;
+      int symb_id = symbol_table.getTypeSpecificID(it->name) + 1;
       SymbolType symb_type = symbol_table.getType(it->name);
 
       if (it->type < 3)
@@ -513,14 +513,14 @@ EstimatedParamsInitStatement::writeOutput(ostream &output, const string &basenam
         {
           if (symb_type == eExogenous)
             {
-              output << "tmp1 = find((estim_params_.corrx(:,1)==" << symb_id << ")) & (estim_params_.corrx(:,2)==" << symbol_table.getID(it->name2)+1 << ");" << endl;
+              output << "tmp1 = find((estim_params_.corrx(:,1)==" << symb_id << ")) & (estim_params_.corrx(:,2)==" << symbol_table.getTypeSpecificID(it->name2)+1 << ");" << endl;
               output << "estim_params_.corrx(tmp1,3) = ";
               it->init_val->writeOutput(output);
               output << ";" << endl;
             }
           else if (symb_type == eEndogenous)
             {
-              output << "tmp1 = find((estim_params_.corrn(:,1)==" << symb_id << ")) & (estim_params_.corrn(:,2)==" << symbol_table.getID(it->name2)+1 << ";" << endl;
+              output << "tmp1 = find((estim_params_.corrn(:,1)==" << symb_id << ")) & (estim_params_.corrn(:,2)==" << symbol_table.getTypeSpecificID(it->name2)+1 << ";" << endl;
               output << "estim_params_.corrn(tmp1,3) = ";
               it->init_val->writeOutput(output);
               output << ";" << endl;
@@ -543,7 +543,7 @@ EstimatedParamsBoundsStatement::writeOutput(ostream &output, const string &basen
 
   for(it = estim_params_list.begin(); it != estim_params_list.end(); it++)
     {
-      int symb_id = symbol_table.getID(it->name) + 1;
+      int symb_id = symbol_table.getTypeSpecificID(it->name) + 1;
       SymbolType symb_type = symbol_table.getType(it->name);
 
       if (it->type < 3)
@@ -589,7 +589,7 @@ EstimatedParamsBoundsStatement::writeOutput(ostream &output, const string &basen
         {
           if (symb_type == eExogenous)
             {
-              output << "tmp1 = find((estim_params_.corrx(:,1)==" << symb_id << ")) & (estim_params_.corrx(:,2)==" << symbol_table.getID(it->name2)+1 << ");" << endl;
+              output << "tmp1 = find((estim_params_.corrx(:,1)==" << symb_id << ")) & (estim_params_.corrx(:,2)==" << symbol_table.getTypeSpecificID(it->name2)+1 << ");" << endl;
 
               output << "estim_params_.corrx(tmp1,4) = ";
               it->low_bound->writeOutput(output);
@@ -601,7 +601,7 @@ EstimatedParamsBoundsStatement::writeOutput(ostream &output, const string &basen
             }
           else if (symb_type == eEndogenous)
             {
-              output << "tmp1 = find((estim_params_.corrn(:,1)==" << symb_id << ")) & (estim_params_.corrn(:,2)==" << symbol_table.getID(it->name2)+1 << ";" << endl;
+              output << "tmp1 = find((estim_params_.corrn(:,1)==" << symb_id << ")) & (estim_params_.corrn(:,2)==" << symbol_table.getTypeSpecificID(it->name2)+1 << ";" << endl;
 
               output << "estim_params_.corrn(tmp1,4) = ";
               it->low_bound->writeOutput(output);
@@ -678,7 +678,7 @@ CalibVarStatement::writeOutput(ostream &output, const string &basename) const
       const string &weight = it->second.first;
       const NodeID expression = it->second.second;
 
-      int id = symbol_table.getID(name) + 1;
+      int id = symbol_table.getTypeSpecificID(name) + 1;
       if (symbol_table.getType(name) == eEndogenous)
         {
           output << "calib_var_index{1} = [calib_var_index{1};" <<  id << "," << id << "];\n";
@@ -706,8 +706,8 @@ CalibVarStatement::writeOutput(ostream &output, const string &basename) const
       const string &weight = it->second.first;
       const NodeID expression = it->second.second;
 
-      int id1 = symbol_table.getID(name1) + 1;
-      int id2 = symbol_table.getID(name2) + 1;
+      int id1 = symbol_table.getTypeSpecificID(name1) + 1;
+      int id2 = symbol_table.getTypeSpecificID(name2) + 1;
       if (symbol_table.getType(name1) == eEndogenous)
         {
           output << "calib_var_index{1} = [calib_var_index{1};" <<  id1 << "," << id2 << "];\n";
@@ -737,7 +737,7 @@ CalibVarStatement::writeOutput(ostream &output, const string &basename) const
       const string &weight = it->second.first;
       const NodeID expression = it->second.second;
 
-      int id = symbol_table.getID(name) + 1;
+      int id = symbol_table.getTypeSpecificID(name) + 1;
 
       if (iar > max_iar)
         {
@@ -837,7 +837,7 @@ OptimWeightsStatement::writeOutput(ostream &output, const string &basename) cons
     {
       const string &name = it->first;
       const NodeID value = it->second;
-      int id = symbol_table.getID(name) + 1;
+      int id = symbol_table.getTypeSpecificID(name) + 1;
       output <<  "optim_weights_(" << id << "," << id << ") = ";
       value->writeOutput(output);
       output << ";" << endl;
@@ -850,8 +850,8 @@ OptimWeightsStatement::writeOutput(ostream &output, const string &basename) cons
       const string &name1 = it->first.first;
       const string &name2 = it->first.second;
       const NodeID value = it->second;
-      int id1 = symbol_table.getID(name1) + 1;
-      int id2 = symbol_table.getID(name2) + 1;
+      int id1 = symbol_table.getTypeSpecificID(name1) + 1;
+      int id2 = symbol_table.getTypeSpecificID(name2) + 1;
       output <<  "optim_weights_(" << id1 << "," << id2 << ") = ";
       value->writeOutput(output);
       output << ";" << endl;
@@ -889,37 +889,6 @@ DynaTypeStatement::writeOutput(ostream &output, const string &basename) const
          << "',var_list_);" << endl;
 }
 
-SaveParamsAndSteadyStateStatement::SaveParamsAndSteadyStateStatement(const string &filename_arg) :
-  filename(filename_arg)
-{
-}
-
-void
-SaveParamsAndSteadyStateStatement::writeOutput(ostream &output, const string &basename) const
-{
-  output << "save_params_and_steady_state('" << filename << "');" << endl;
-}
-
-LoadParamsAndSteadyStateStatement::LoadParamsAndSteadyStateStatement(const string &filename_arg) :
-  filename(filename_arg)
-{
-}
-
-void
-LoadParamsAndSteadyStateStatement::checkPass(ModFileStructure &mod_file_struct)
-{
-  mod_file_struct.load_params_and_steady_state_present = true;
-  mod_file_struct.load_params_and_steady_state_filename = filename;
-}
-
-
-void
-LoadParamsAndSteadyStateStatement::writeOutput(ostream &output, const string &basename) const
-{
-  output << "load_params_and_steady_state('" << filename << "');" << endl;
-}
-
-
 ModelComparisonStatement::ModelComparisonStatement(const filename_list_type &filename_list_arg,
                                                    const OptionsList &options_list_arg) :
   filename_list(filename_list_arg),
diff --git a/DataTree.cc b/DataTree.cc
index 6c6405a8a458384ccd1c91326c1f34e5fdb1b0c5..b970df20d2a7c82b434586139fd3057c5b734f01 100644
--- a/DataTree.cc
+++ b/DataTree.cc
@@ -60,13 +60,12 @@ NodeID
 DataTree::AddVariable(const string &name, int lag)
 {
   int symb_id = symbol_table.getID(name);
-  SymbolType type = symbol_table.getType(name);
 
-  variable_node_map_type::iterator it = variable_node_map.find(make_pair(make_pair(symb_id, type), lag));
+  variable_node_map_type::iterator it = variable_node_map.find(make_pair(symb_id, lag));
   if (it != variable_node_map.end())
     return it->second;
   else
-    return new VariableNode(*this, symb_id, type, lag);
+    return new VariableNode(*this, symb_id, lag);
 }
 
 NodeID
@@ -423,3 +422,22 @@ DataTree::AddUnknownFunction(const string &function_name, const vector<NodeID> &
 
   return new UnknownFunctionNode(*this, id, arguments);
 }
+
+void
+DataTree::fillEvalContext(eval_context_type &eval_context) const
+{
+  for(map<int, NodeID>::const_iterator it = local_variables_table.begin();
+      it != local_variables_table.end(); it++)
+    {
+      try
+        {
+          const NodeID expression = it->second;
+          double val = expression->eval(eval_context);
+          eval_context[it->first] = val;
+        }
+      catch(ExprNode::EvalException &e)
+        {
+          // Do nothing
+        }
+    }
+}
diff --git a/ExprNode.cc b/ExprNode.cc
index a2a6f9083681cd757f3eb5e5dcc65f8b08990fc2..d3da5f91749d3e162e2fcc0f77c2880d8d09ea7d 100644
--- a/ExprNode.cc
+++ b/ExprNode.cc
@@ -170,20 +170,20 @@ NumConstNode::collectExogenous(set<pair<int, int> > &result) const
 }
 
 
-VariableNode::VariableNode(DataTree &datatree_arg, int symb_id_arg, SymbolType type_arg, int lag_arg) :
+VariableNode::VariableNode(DataTree &datatree_arg, int symb_id_arg, int lag_arg) :
   ExprNode(datatree_arg),
   symb_id(symb_id_arg),
-  type(type_arg),
+  type(datatree.symbol_table.getType(symb_id_arg)),
   lag(lag_arg)
 {
   // Add myself to the variable map
-  datatree.variable_node_map[make_pair(make_pair(symb_id, type), lag)] = this;
+  datatree.variable_node_map[make_pair(symb_id, lag)] = this;
 
   // Add myself to the variable table if necessary and initialize var_id
   if (type == eEndogenous
       || type == eExogenousDet
       || type == eExogenous)
-    var_id = datatree.variable_table.addVariable(type, symb_id, lag);
+    var_id = datatree.variable_table.addVariable(symb_id, lag);
   else
     var_id = -1;
 
@@ -277,13 +277,14 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
     }
 
   int i;
+  int tsid = datatree.symbol_table.getTypeSpecificID(symb_id);
   switch(type)
     {
     case eParameter:
       if (output_type == oMatlabOutsideModel)
-        output << "M_.params" << "(" << symb_id + 1 << ")";
+        output << "M_.params" << "(" << tsid + 1 << ")";
       else
-        output << "params" << LPAR(output_type) << symb_id + OFFSET(output_type) << RPAR(output_type);
+        output << "params" << LPAR(output_type) << tsid + OFFSET(output_type) << RPAR(output_type);
       break;
 
     case eModelLocalVariable:
@@ -295,7 +296,7 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
           output << ")";
         }
       else
-        output << datatree.symbol_table.getNameByID(type, symb_id);
+        output << datatree.symbol_table.getName(symb_id);
       break;
 
     case eEndogenous:
@@ -309,19 +310,19 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
         case oMatlabStaticModel:
         case oMatlabStaticModelSparse:
         case oCStaticModel:
-          i = symb_id + OFFSET(output_type);
+          i = tsid + OFFSET(output_type);
           output <<  "y" << LPAR(output_type) << i << RPAR(output_type);
           break;
         case oCDynamicModelSparseDLL:
           if (lag > 0)
-            output << "y" << LPAR(output_type) << "(it_+" << lag << ")*y_size+" << symb_id << RPAR(output_type);
+            output << "y" << LPAR(output_type) << "(it_+" << lag << ")*y_size+" << tsid << RPAR(output_type);
           else if (lag < 0)
-            output << "y" << LPAR(output_type) << "(it_" << lag << ")*y_size+" << symb_id << RPAR(output_type);
+            output << "y" << LPAR(output_type) << "(it_" << lag << ")*y_size+" << tsid << RPAR(output_type);
           else
-            output << "y" << LPAR(output_type) << "Per_y_+" << symb_id << RPAR(output_type);
+            output << "y" << LPAR(output_type) << "Per_y_+" << tsid << RPAR(output_type);
           break;
         case oMatlabDynamicModelSparse:
-          i = symb_id + OFFSET(output_type);
+          i = tsid + OFFSET(output_type);
           if (lag > 0)
             output << "y" << LPAR(output_type) << "it_+" << lag << ", " << i << RPAR(output_type);
           else if (lag < 0)
@@ -330,13 +331,13 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
             output << "y" << LPAR(output_type) << "it_, " << i << RPAR(output_type);
           break;
         case oMatlabOutsideModel:
-          output << "oo_.steady_state" << "(" << symb_id + 1 << ")";
+          output << "oo_.steady_state" << "(" << tsid + 1 << ")";
           break;
         }
       break;
 
     case eExogenous:
-      i = symb_id + OFFSET(output_type);
+      i = tsid + OFFSET(output_type);
       switch(output_type)
         {
         case oMatlabDynamicModel:
@@ -374,7 +375,7 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
       break;
 
     case eExogenousDet:
-      i = symb_id + datatree.symbol_table.exo_nbr + OFFSET(output_type);
+      i = tsid + datatree.symbol_table.exo_nbr() + OFFSET(output_type);
       switch(output_type)
         {
         case oMatlabDynamicModel:
@@ -406,7 +407,7 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
               cerr << "VariableNode::writeOutput: lag != 0 for exogenous determistic variable outside model scope!" << endl;
               exit(EXIT_FAILURE);
             }
-          output <<  "oo_.exo_det_steady_state" << "(" << symb_id + 1 << ")";
+          output <<  "oo_.exo_det_steady_state" << "(" << tsid + 1 << ")";
           break;
         }
       break;
@@ -420,11 +421,9 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
 double
 VariableNode::eval(const eval_context_type &eval_context) const throw (EvalException)
 {
-  eval_context_type::const_iterator it = eval_context.find(make_pair(symb_id, type));
+  eval_context_type::const_iterator it = eval_context.find(symb_id);
   if (it == eval_context.end())
-    {
-      throw EvalException();
-    }
+    throw EvalException();
 
   return it->second;
 }
@@ -464,7 +463,7 @@ VariableNode::compile(ofstream &CompileCode, bool lhs_rhs, ExprNodeOutputType ou
       CompileCode.write(reinterpret_cast<char *>(&lagl), sizeof(lagl));
       break;
     case eExogenousDet:
-      i = symb_id + datatree.symbol_table.exo_nbr + OFFSET(output_type);
+      i = symb_id + datatree.symbol_table.exo_nbr() + OFFSET(output_type);
       CompileCode.write(reinterpret_cast<char *>(&i), sizeof(i));
       lagl=lag;
       CompileCode.write(reinterpret_cast<char *>(&lagl), sizeof(lagl));
@@ -1726,7 +1725,7 @@ UnknownFunctionNode::computeTemporaryTerms(map<NodeID, int> &reference_count,
 void UnknownFunctionNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
                                       const temporary_terms_type &temporary_terms) const
 {
-  output << datatree.symbol_table.getNameByID(eUnknownFunction, symb_id) << "(";
+  output << datatree.symbol_table.getName(symb_id) << "(";
   for(vector<NodeID>::const_iterator it = arguments.begin();
       it != arguments.end(); it++)
     {
diff --git a/IncidenceMatrix.cc b/IncidenceMatrix.cc
index bf660ddc3772b1983050d1958d2c0d9a8e6adfd6..9d3205a018edd2842ccc18f4945a6b168fdb991b 100644
--- a/IncidenceMatrix.cc
+++ b/IncidenceMatrix.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007-2008 Dynare Team
+ * Copyright (C) 2007-2009 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -38,9 +38,9 @@ IncidenceMatrix::Build_IM(int lead_lag, SymbolType type)
   bool *IM;
   if(type==eEndogenous)
     {
-      size = symbol_table.endo_nbr * symbol_table.endo_nbr * sizeof(IM[0]);
+      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;
+      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)
@@ -62,9 +62,9 @@ IncidenceMatrix::Build_IM(int lead_lag, SymbolType type)
     }
   else
     {  //eExogenous
-      size = symbol_table.endo_nbr * symbol_table.exo_nbr * sizeof(IM[0]);
+      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;
+      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)
@@ -130,17 +130,17 @@ IncidenceMatrix::fill_IM(int equation, int variable, int lead_lag, SymbolType ty
 {
   bool* Cur_IM;
   Cur_IM = Get_IM(lead_lag, type);
-  if(equation >= symbol_table.endo_nbr)
+  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";
+      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;
+    Cur_IM[equation*symbol_table.endo_nbr() + variable] = 1;
   else
-    Cur_IM[equation*symbol_table.exo_nbr + variable] = 1;
+    Cur_IM[equation*symbol_table.exo_nbr() + variable] = 1;
 }
 
 //------------------------------------------------------------------------------
@@ -153,9 +153,9 @@ IncidenceMatrix::unfill_IM(int equation, int variable, int lead_lag, SymbolType
   if (!Cur_IM)
     Cur_IM = Build_IM(lead_lag, type);
   if(type==eEndogenous)
-    Cur_IM[equation*symbol_table.endo_nbr + variable] = 0;
+    Cur_IM[equation*symbol_table.endo_nbr() + variable] = 0;
   else
-    Cur_IM[equation*symbol_table.exo_nbr + variable] = 0;
+    Cur_IM[equation*symbol_table.exo_nbr() + variable] = 0;
 }
 
 
@@ -166,10 +166,10 @@ IncidenceMatrix::Print_SIM(bool* IM, SymbolType type) const
 {
   int i, j, n;
   if(type == eEndogenous)
-    n = symbol_table.endo_nbr;
+    n = symbol_table.endo_nbr();
   else
-    n = symbol_table.exo_nbr;
-  for(i = 0;i < symbol_table.endo_nbr;i++)
+    n = symbol_table.exo_nbr();
+  for(i = 0;i < symbol_table.endo_nbr();i++)
     {
       cout << " ";
       for(j = 0;j < n;j++)
diff --git a/ModFile.cc b/ModFile.cc
index 1a72b23a80fc8acdab7fb643fc8330d808bcebf0..864cc3e4c0fc4396a7fa6fc830187d8d6715f155 100644
--- a/ModFile.cc
+++ b/ModFile.cc
@@ -36,233 +36,44 @@ ModFile::~ModFile()
     delete (*it);
 }
 
-
-
 void
 ModFile::evalAllExpressions()
 {
-  //Evaluate Parameters
-
-  InitParamStatement *it;
-  vector< vector<double> >::iterator it2;
-  ostringstream constant;
-  NodeID tmp_id;
-  CollectStruct collect_struct;
-  int j=0, k;
-  if(mod_file_struct.load_params_and_steady_state_present)
-    {
-      cout << "Reading " << mod_file_struct.load_params_and_steady_state_filename << " ...";
-      matlab_file.MatFileRead(mod_file_struct.load_params_and_steady_state_filename);
-      string sname="stored_values";
-      bool tmp_b=matlab_file.Collect(sname, collect_struct);
-      matlab_file.Delete();
-      if(!tmp_b)
-        {
-          cout << "The structure " << sname << " is not found in " << mod_file_struct.load_params_and_steady_state_filename << "\n";
-        }
-      cout << "done\n";
-    }
-  cout << "Evaluating expressions ...";
-  for(vector<Statement *>::const_iterator it1=statements.begin();it1!=statements.end(); it1++)
-    {
-      it=dynamic_cast<InitParamStatement *>(*it1);
-      if(it)
-        {
-          try
-            {
-              const NodeID expression = it->get_expression();
-              double val = expression->eval(global_eval_context);
-              int symb_id = symbol_table.getID(it->get_name());
-              global_eval_context[make_pair(symb_id, eParameter)] = val;
-              j++;
-            }
-          catch(ExprNode::EvalException &e)
-            {
-              cout << "error in evaluation of param\n";
-            }
-        }
-    }
-  if(mod_file_struct.load_params_and_steady_state_present && j!=symbol_table.parameter_nbr)
-    {
-      //Reading a Mat-File
-      for(k=0;k <symbol_table.parameter_nbr; k++)
-        {
-          if(global_eval_context.find(make_pair(k, eParameter))==global_eval_context.end())
-            {
-              map<string,vector<double> >::iterator it2=collect_struct.variable_double_name.find(symbol_table.getNameByID(eParameter, k));
-              if(it2!=collect_struct.variable_double_name.end())
-                {
-                  j++;
-                  vector<double>::iterator it=it2->second.begin();
-                  global_eval_context[make_pair(k, eParameter)]=*it;
-                }
-            }
-        }
-    }
-  if (j!=symbol_table.parameter_nbr)
-    {
-      cout << "Warning: Uninitialized parameters: \n";
-      for(j=0;j <symbol_table.parameter_nbr; j++)
-        {
-          if(global_eval_context.find(make_pair(j, eParameter))==global_eval_context.end())
-            cout << " " << symbol_table.getNameByID(eParameter, j) << "\n";
-        }
-    }
-  //Evaluate variables
-  for(InitOrEndValStatement::init_values_type::const_iterator it=init_values.begin(); it!=init_values.end(); it++)
-    {
-      try
-        {
-          const string &name = it->first;
-          const NodeID expression = it->second;
-          SymbolType type = symbol_table.getType(name);
-          double val = expression->eval(global_eval_context);
-          int symb_id = symbol_table.getID(name);
-          global_eval_context[make_pair(symb_id, type)] = val;
-        }
-      catch(ExprNode::EvalException &e)
-        {
-          cout << "error in evaluation of variable\n";
-        }
-    }
-  if(mod_file_struct.load_params_and_steady_state_present && int(init_values.size())<symbol_table.endo_nbr+symbol_table.exo_nbr+symbol_table.exo_det_nbr)
-    {
-      for(j=0;j <symbol_table.endo_nbr; j++)
-        {
-          if(global_eval_context.find(make_pair(j, eEndogenous))==global_eval_context.end())
-            {
-              map<string,vector<double> >::iterator it2=collect_struct.variable_double_name.find(symbol_table.getNameByID(eEndogenous, j));
-              if(it2!=collect_struct.variable_double_name.end())
-                {
-                  vector<double>::iterator it=it2->second.begin();
-                  global_eval_context[make_pair(j, eEndogenous)]=*it;
-                  constant.str("");
-                  if(*it>=0)
-                    {
-                      constant << *it;
-                      tmp_id=expressions_tree.AddNumConstant(constant.str());
-                    }
-                  else
-                    {
-                      constant << -*it;
-                      tmp_id=expressions_tree.AddUMinus(expressions_tree.AddNumConstant(constant.str()));
-                    }
-                  init_values.push_back(make_pair(it2->first, tmp_id));
-                }
-            }
-        }
-      for(j=0;j <symbol_table.exo_nbr; j++)
-        {
-          if(global_eval_context.find(make_pair(j, eExogenous))==global_eval_context.end())
-            {
-              map<string,vector<double> >::iterator it2=collect_struct.variable_double_name.find(symbol_table.getNameByID(eExogenous, j));
-              if(it2!=collect_struct.variable_double_name.end())
-                {
-                  vector<double>::iterator it=it2->second.begin();
-                  global_eval_context[make_pair(j, eExogenous)]=*it;
-                  constant.str("");
-                  if(*it>=0)
-                    {
-                      constant << *it;
-                      tmp_id=expressions_tree.AddNumConstant(constant.str());
-                    }
-                  else
-                    {
-                      constant << -*it;
-                      tmp_id=expressions_tree.AddUMinus(expressions_tree.AddNumConstant(constant.str()));
-                    }
-                  init_values.push_back(make_pair(it2->first, tmp_id));
-                }
-            }
-        }
-      for(j=0;j <symbol_table.exo_det_nbr; j++)
-        {
-          if(global_eval_context.find(make_pair(j, eExogenous))==global_eval_context.end())
-            {
-              map<string,vector<double> >::iterator it2=collect_struct.variable_double_name.find(symbol_table.getNameByID(eExogenous, j));
-              if(it2!=collect_struct.variable_double_name.end())
-                {
-                  vector<double>::iterator it=it2->second.begin();
-                  global_eval_context[make_pair(j, eExogenous)]=*it;
-                  constant.str("");
-                  if(*it>=0)
-                    {
-                      constant << *it;
-                      tmp_id=expressions_tree.AddNumConstant(constant.str());
-                    }
-                  else
-                    {
-                      constant << -*it;
-                      tmp_id=expressions_tree.AddUMinus(expressions_tree.AddNumConstant(constant.str()));
-                    }
-                  init_values.push_back(make_pair(it2->first, tmp_id));
-                }
-            }
-        }
-    }
-  if(int(init_values.size())<symbol_table.endo_nbr+symbol_table.exo_nbr+symbol_table.exo_det_nbr)
-    {
-      cout << "\nWarning: Uninitialized variable: \n";
-      cout << "Endogenous\n";
-      for(j=0;j <symbol_table.endo_nbr; j++)
-        {
-          if(global_eval_context.find(make_pair(j, eEndogenous))==global_eval_context.end())
-            {
-              cout << " " << symbol_table.getNameByID(eEndogenous, j) << "\n";
-              global_eval_context[make_pair(j, eEndogenous)] = 0;
-            }
-        }
-      cout << "Exogenous\n";
-      for(j=0;j <symbol_table.exo_nbr; j++)
-        {
-          if(global_eval_context.find(make_pair(j, eExogenous))==global_eval_context.end())
-            {
-              cout << " " << symbol_table.getNameByID(eExogenous, j) << "\n";
-              global_eval_context[make_pair(j, eExogenous)]=0;
-            }
-        }
-      cout << "Deterministic exogenous\n";
-      for(j=0;j <symbol_table.exo_det_nbr; j++)
-        {
-          if(global_eval_context.find(make_pair(j, eExogenousDet))==global_eval_context.end())
-            {
-              cout << " " << symbol_table.getNameByID(eExogenousDet, j) << "\n";
-              global_eval_context[make_pair(j, eExogenousDet)]=0;
-            }
-        }
-    }
-  //Evaluate Local variables
-  for(map<int, NodeID>::const_iterator it = model_tree.local_variables_table.begin(); it !=model_tree.local_variables_table.end(); it++)
+  cout << "Evaluating expressions...";
+
+  // Loop over all statements, and fill global eval context if relevant
+  for(vector<Statement *>::const_iterator it = statements.begin(); it != statements.end(); it++)
     {
-      try
-        {
-          const NodeID expression = it->second;
-          double val = expression->eval(global_eval_context);
-          //cout << it->first << "  " << symbol_table.getNameByID(eModelLocalVariable, it->first) << " = " << val << "\n";
-          global_eval_context[make_pair(it->first, eModelLocalVariable)] = val;
-        }
-      catch(ExprNode::EvalException &e)
-        {
-          cout << "error in evaluation of pound\n";
-        }
+      InitParamStatement *ips = dynamic_cast<InitParamStatement *>(*it);
+      if (ips)
+        ips->fillEvalContext(global_eval_context);
+
+      InitOrEndValStatement *ies = dynamic_cast<InitOrEndValStatement *>(*it);
+      if (ies)
+        ies->fillEvalContext(global_eval_context);
+
+      LoadParamsAndSteadyStateStatement *lpass = dynamic_cast<LoadParamsAndSteadyStateStatement *>(*it);
+      if (lpass)
+        lpass->fillEvalContext(global_eval_context);
     }
-  if(int(model_tree.local_variables_table.size())!=symbol_table.model_local_variable_nbr+symbol_table.modfile_local_variable_nbr)
+
+  // Evaluate model local variables
+  model_tree.fillEvalContext(global_eval_context);
+
+  cout << "done" << endl;
+
+  // Check if some symbols are not initialized, and give them a zero value then
+  for(int id = 0; id <= symbol_table.maxID(); id++)
     {
-      cout << "Warning: Unitilialized pound: \n";
-      cout << "Local variable in a model\n";
-      for(j=0;j <symbol_table.model_local_variable_nbr; j++)
+      SymbolType type = symbol_table.getType(id);
+      if ((type == eEndogenous || type == eExogenous || type == eExogenousDet
+          || type == eParameter || type == eModelLocalVariable)
+          && global_eval_context.find(id) == global_eval_context.end())
         {
-          if(global_eval_context.find(make_pair(j, eModelLocalVariable))==global_eval_context.end())
-            cout << " " << symbol_table.getNameByID(eModelLocalVariable, j) << "\n";
-        }
-      cout << "Local variable in a model file\n";
-      for(j=0;j <symbol_table.modfile_local_variable_nbr; j++)
-        {
-          if(global_eval_context.find(make_pair(j, eModFileLocalVariable))==global_eval_context.end())
-            cout << " " << symbol_table.getNameByID(eModFileLocalVariable, j) << "\n";
+          cerr << "WARNING: can't find a numeric initial value for " << symbol_table.getName(id) << ", using zero" << endl;
+          global_eval_context[id] = 0;
         }
     }
-  cout << "done\n";
 }
 
 void
@@ -304,6 +115,9 @@ ModFile::checkPass()
       exit(EXIT_FAILURE);
     }
 
+  // Freeze the symbol table
+  symbol_table.freeze();
+
   /*
     Enforce the same number of equations and endogenous, except in two cases:
     - ramsey_policy is used
@@ -312,9 +126,9 @@ ModFile::checkPass()
   if (!mod_file_struct.ramsey_policy_present
       && !((mod_file_struct.bvar_density_present || mod_file_struct.bvar_forecast_present)
            && model_tree.equation_number() == 0)
-      && (model_tree.equation_number() != symbol_table.endo_nbr))
+      && (model_tree.equation_number() != symbol_table.endo_nbr()))
     {
-      cerr << "ERROR: There are " << model_tree.equation_number() << " equations but " << symbol_table.endo_nbr << " endogenous variables!" << endl;
+      cerr << "ERROR: There are " << model_tree.equation_number() << " equations but " << symbol_table.endo_nbr() << " endogenous variables!" << endl;
       exit(EXIT_FAILURE);
     }
 }
@@ -341,13 +155,11 @@ ModFile::computingPass(bool no_tmp_terms)
           if (mod_file_struct.order_option == 3)
             model_tree.computeThirdDerivatives = true;
         }
-      //evalAllExpressions();
       model_tree.computingPass(global_eval_context, no_tmp_terms);
     }
   for(vector<Statement *>::iterator it = statements.begin();
       it != statements.end(); it++)
     (*it)->computingPass();
-  //evalAllExpressions();
 }
 
 void
diff --git a/ModelNormalization.cc b/ModelNormalization.cc
index 4a3dda7dc1ed89dc1c27057f3c370ce9ff69946e..0c0cea0c8d29abdc071881cc91a6b7d098028347 100644
--- a/ModelNormalization.cc
+++ b/ModelNormalization.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007-2008 Dynare Team
+ * Copyright (C) 2007-2009 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -531,7 +531,7 @@ Normalization::Normalize(int n, int prologue, int epilogue, bool* IM, simple* In
       cout << "\n and the following variables:\n - ";
       for(i = 0; i < Variable->size; i++)
         if(Variable->Number[i].matched == -1)
-          cout << symbol_table.getNameByID(eEndogenous, Index_Equ_IM[i].index) << " ";
+          cout << symbol_table.getName(Index_Equ_IM[i].index) << " ";
       cout << "\n could not be normalized\n";
       //ErrorHandling(n, IM, Index_Equ_IM);
       //system("PAUSE");
diff --git a/ModelTree.cc b/ModelTree.cc
index 9b91c98b880d473b8f56f6fbb4c9b85fd494e8b1..022c05235f158227c411debee6cd7bb5c77f1a73 100644
--- a/ModelTree.cc
+++ b/ModelTree.cc
@@ -62,10 +62,9 @@ ModelTree::equation_number() const
 void
 ModelTree::writeDerivative(ostream &output, int eq, int symb_id, int lag,
                            ExprNodeOutputType output_type,
-                           const temporary_terms_type &temporary_terms,
-                           SymbolType type) const
+                           const temporary_terms_type &temporary_terms) const
 {
-  first_derivatives_type::const_iterator it = first_derivatives.find(make_pair(eq, variable_table.getID(type, symb_id, lag)));
+  first_derivatives_type::const_iterator it = first_derivatives.find(make_pair(eq, variable_table.getID(symb_id, lag)));
   if (it != first_derivatives.end())
     (it->second)->writeOutput(output, output_type, temporary_terms);
   else
@@ -75,7 +74,7 @@ ModelTree::writeDerivative(ostream &output, int eq, int symb_id, int lag,
 void
 ModelTree::compileDerivative(ofstream &code_file, int eq, int symb_id, int lag, ExprNodeOutputType output_type, map_idx_type &map_idx) const
 {
-  first_derivatives_type::const_iterator it = first_derivatives.find(make_pair(eq, variable_table.getID(eEndogenous, symb_id, lag)));
+  first_derivatives_type::const_iterator it = first_derivatives.find(make_pair(eq, variable_table.getID(symb_id, lag)));
   if (it != first_derivatives.end())
     (it->second)->compile(code_file,false, output_type, temporary_terms, map_idx);
   else
@@ -217,7 +216,7 @@ ModelTree::writeModelLocalVariables(ostream &output, ExprNodeOutputType output_t
       if (!OFFSET(output_type))
         output << "double ";
 
-      output << symbol_table.getNameByID(eModelLocalVariable, id) << " = ";
+      output << symbol_table.getName(id) << " = ";
       // Use an empty set for the temporary terms
       value->writeOutput(output, output_type, temporary_terms_type());
       output << ";" << endl;
@@ -303,7 +302,7 @@ ModelTree::computeTemporaryTermsOrdered(int order, Model_Block *ModelBlock)
             {
               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,variable_table.getID(eEndogenous, var,lag)));
+              it=first_derivatives.find(make_pair(eq,variable_table.getID(var, lag)));
               it->second->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, j, ModelBlock, ModelBlock->Block_List[j].Size-1, map_idx);
             }
         }
@@ -314,7 +313,7 @@ ModelTree::computeTemporaryTermsOrdered(int order, Model_Block *ModelBlock)
             {
               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,variable_table.getID(eExogenous, var,lag)));
+              it=first_derivatives.find(make_pair(eq,variable_table.getID(var, lag)));
               it->second->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, j, ModelBlock, ModelBlock->Block_List[j].Size-1, map_idx);
             }
         }
@@ -328,7 +327,7 @@ ModelTree::computeTemporaryTermsOrdered(int order, Model_Block *ModelBlock)
                 {
                   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,variable_table.getID(eEndogenous, var,lag)));
+                  it=first_derivatives.find(make_pair(eq,variable_table.getID(var, lag)));
                   it->second->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, j, ModelBlock, ModelBlock->Block_List[j].Size-1, map_idx);
                 }
             }
@@ -349,7 +348,7 @@ ModelTree::computeTemporaryTermsOrdered(int order, Model_Block *ModelBlock)
             {
               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,variable_table.getID(eEndogenous, var,lag)));
+              it=first_derivatives.find(make_pair(eq,variable_table.getID(var, lag)));
               it->second->collectTemporary_terms(temporary_terms, ModelBlock, j);
             }
         }
@@ -360,7 +359,7 @@ ModelTree::computeTemporaryTermsOrdered(int order, Model_Block *ModelBlock)
             {
               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,variable_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);
             }
         }
@@ -374,7 +373,7 @@ ModelTree::computeTemporaryTermsOrdered(int order, Model_Block *ModelBlock)
                 {
                   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,variable_table.getID(eEndogenous, var,lag)));
+                  it=first_derivatives.find(make_pair(eq,variable_table.getID(var, lag)));
                   it->second->collectTemporary_terms(temporary_terms, ModelBlock, j);
                 }
             }
@@ -395,7 +394,7 @@ ModelTree::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const string &
   ostringstream tmp_output, tmp1_output, global_output;
   NodeID lhs=NULL, rhs=NULL;
   BinaryOpNode *eq_node;
-  ostringstream Uf[symbol_table.endo_nbr];
+  ostringstream Uf[symbol_table.endo_nbr()];
   map<NodeID, int> reference_count;
   int prev_Simulation_Type=-1, count_derivates=0;
   int jacobian_max_endo_col;
@@ -520,7 +519,7 @@ ModelTree::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const string &
               tt2.insert(*it);
               output << ";" << endl;
             }
-          string sModel = symbol_table.getNameByID(eEndogenous, ModelBlock->Block_List[j].Variable[i]) ;
+          string sModel = symbol_table.getName(ModelBlock->Block_List[j].Variable[i]) ;
           eq_node = equations[ModelBlock->Block_List[j].Equation[i]];
           lhs = eq_node->arg1;
           rhs = eq_node->arg2;
@@ -603,8 +602,8 @@ ModelTree::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const string &
                   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, var, k, oMatlabDynamicModelSparse, temporary_terms, eEndogenous);
-                  output << "; % variable=" << symbol_table.getNameByID(eEndogenous, var)
+                  writeDerivative(output, eq, var, k, oMatlabDynamicModelSparse, temporary_terms);
+                  output << "; % variable=" << symbol_table.getName(var)
                          << "(" << k//variable_table.getLag(variable_table.getSymbolID(ModelBlock->Block_List[j].Variable[0]))
                          << ") " << var+1
                          << ", equation=" << eq+1 << endl;
@@ -621,9 +620,9 @@ ModelTree::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const string &
                   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+variable_table.max_exo_lag-ModelBlock->Block_List[j].Max_Lag)*symbol_table.exo_nbr << ") = ";
-                  writeDerivative(output, eq, var, k, oMatlabDynamicModelSparse, temporary_terms, eExogenous);
-                  output << "; % variable=" << symbol_table.getNameByID(eExogenous, var)
+                         << varr+1+(m+variable_table.max_exo_lag-ModelBlock->Block_List[j].Max_Lag)*symbol_table.exo_nbr() << ") = ";
+                  writeDerivative(output, eq, var, k, oMatlabDynamicModelSparse, temporary_terms);
+                  output << "; % variable=" << symbol_table.getName(var)
                          << "(" << k << ") " << var+1
                          << ", equation=" << eq+1 << endl;
                 }
@@ -640,9 +639,9 @@ ModelTree::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const string &
                       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+variable_table.max_endo_lag-ModelBlock->Block_List[j].Max_Lag)*symbol_table.endo_nbr << ") = ";
-                      writeDerivative(output, eq, var, k, oMatlabDynamicModelSparse, temporary_terms, eEndogenous);
-                      output << "; % variable=" << symbol_table.getNameByID(eEndogenous, var)
+                             << varr+1+(m+variable_table.max_endo_lag-ModelBlock->Block_List[j].Max_Lag)*symbol_table.endo_nbr() << ") = ";
+                      writeDerivative(output, eq, var, k, oMatlabDynamicModelSparse, temporary_terms);
+                      output << "; % variable=" << symbol_table.getName(var)
                              << "(" << k << ") " << var+1
                              << ", equation=" << eq+1 << endl;
                     }
@@ -669,8 +668,8 @@ ModelTree::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const string &
                   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, var, k, oMatlabDynamicModelSparse, temporary_terms, eEndogenous);
-                  output << "; % variable=" << symbol_table.getNameByID(eEndogenous, var)
+                  writeDerivative(output, eq, var, k, oMatlabDynamicModelSparse, temporary_terms);
+                  output << "; % variable=" << symbol_table.getName(var)
                          << "(" << k
                          << ") " << var+1
                          << ", equation=" << eq+1 << endl;
@@ -686,8 +685,8 @@ ModelTree::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const string &
                   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+variable_table.max_exo_lag-ModelBlock->Block_List[j].Max_Lag)*ModelBlock->Block_List[j].nb_exo << ") = ";
-                  writeDerivative(output, eq, var, k, oMatlabDynamicModelSparse, temporary_terms, eExogenous);
-                  output << "; % variable=" << symbol_table.getNameByID(eExogenous, var)
+                  writeDerivative(output, eq, var, k, oMatlabDynamicModelSparse, temporary_terms);
+                  output << "; % variable=" << symbol_table.getName(var)
                          << "(" << k << ") " << var+1
                          << ", equation=" << eq+1 << endl;
                 }
@@ -704,9 +703,9 @@ ModelTree::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const string &
                       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+variable_table.max_endo_lag-ModelBlock->Block_List[j].Max_Lag)*symbol_table.endo_nbr << ") = ";
-                      writeDerivative(output, eq, var, k, oMatlabDynamicModelSparse, temporary_terms, eEndogenous);
-                      output << "; % variable=" << symbol_table.getNameByID(eEndogenous, var)
+                             << varr+1+(m+variable_table.max_endo_lag-ModelBlock->Block_List[j].Max_Lag)*symbol_table.endo_nbr() << ") = ";
+                      writeDerivative(output, eq, var, k, oMatlabDynamicModelSparse, temporary_terms);
+                      output << "; % variable=" << symbol_table.getName(var)
                              << "(" << k << ") " << var+1
                              << ", equation=" << eq+1 << endl;
                     }
@@ -724,8 +723,8 @@ ModelTree::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const string &
               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 << ") = ";
-              writeDerivative(output, eq, var, 0, oMatlabDynamicModelSparse, temporary_terms, eEndogenous);
-              output << "; % variable=" << symbol_table.getNameByID(eEndogenous, var)
+              writeDerivative(output, eq, var, 0, oMatlabDynamicModelSparse, temporary_terms);
+              output << "; % variable=" << symbol_table.getName(var)
                      << "(" << variable_table.getLag(variable_table.getSymbolID(var)) << ") " << var+1
                      << ", equation=" << eq+1 << endl;
             }
@@ -759,8 +758,8 @@ ModelTree::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const string &
                     output << "      g1(" << eqr+1 << "+Per_J_, " << varr+1 << "+y_size*(it_+" << k-1 << ")) = ";
                   else if (k<0)
                     output << "      g1(" << eqr+1 << "+Per_J_, " << varr+1 << "+y_size*(it_" << k-1 << ")) = ";
-                  writeDerivative(output, eq, var, k, oMatlabDynamicModelSparse, temporary_terms, eEndogenous);
-                  output << "; % variable=" << symbol_table.getNameByID(eEndogenous, var)
+                  writeDerivative(output, eq, var, k, oMatlabDynamicModelSparse, temporary_terms);
+                  output << "; % variable=" << symbol_table.getName(var)
                          << "(" << k << ") " << var+1
                          << ", equation=" << eq+1 << endl;
 #ifdef CONDITION
@@ -805,8 +804,8 @@ ModelTree::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const string &
                   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, var, k, oMatlabDynamicModelSparse, temporary_terms, eEndogenous);
-                  output << "; % variable=" << symbol_table.getNameByID(eEndogenous, var)
+                  writeDerivative(output, eq, var, k, oMatlabDynamicModelSparse, temporary_terms);
+                  output << "; % variable=" << symbol_table.getName(var)
                          << "(" << k << ") " << var+1
                          << ", equation=" << eq+1 << endl;
                 }
@@ -823,8 +822,8 @@ ModelTree::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const string &
                   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, var, k, oMatlabDynamicModelSparse, temporary_terms, eExogenous);
-                  output << "; % variable (exogenous)=" << symbol_table.getNameByID(eExogenous, var)
+                  writeDerivative(output, eq, var, k, oMatlabDynamicModelSparse, temporary_terms);
+                  output << "; % variable (exogenous)=" << symbol_table.getName(var)
                          << "(" << k << ") " << var+1 << " " << varr+1
                          << ", equation=" << eq+1 << endl;
                 }
@@ -841,9 +840,9 @@ ModelTree::writeModelEquationsOrdered_M( Model_Block *ModelBlock, const string &
                       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+variable_table.max_endo_lag-ModelBlock->Block_List[j].Max_Lag)*symbol_table.endo_nbr << ") = ";
-                      writeDerivative(output, eq, var, k, oMatlabDynamicModelSparse, temporary_terms, eEndogenous);
-                      output << "; % variable=" << symbol_table.getNameByID(eEndogenous, var)
+                             << varr+1+(m+variable_table.max_endo_lag-ModelBlock->Block_List[j].Max_Lag)*symbol_table.endo_nbr() << ") = ";
+                      writeDerivative(output, eq, var, k, oMatlabDynamicModelSparse, temporary_terms);
+                      output << "; % variable=" << symbol_table.getName(var)
                              << "(" << k << ") " << var+1
                              << ", equation=" << eq+1 << endl;
                     }
@@ -914,7 +913,7 @@ ModelTree::writeModelStaticEquationsOrdered_M(Model_Block *ModelBlock, const str
         }
 
       int n=ModelBlock->Block_List[j].Size;
-      int n1=symbol_table.endo_nbr;
+      int n1=symbol_table.endo_nbr();
       IM=(bool*)malloc(n*n*sizeof(bool));
       memset(IM, 0, n*n*sizeof(bool));
       for (m=-ModelBlock->Block_List[j].Max_Lag;m<=ModelBlock->Block_List[j].Max_Lead;m++)
@@ -963,7 +962,7 @@ ModelTree::writeModelStaticEquationsOrdered_M(Model_Block *ModelBlock, const str
               tt2.insert(*it);
               output << ";" << endl;
             }
-          string sModel = symbol_table.getNameByID(eEndogenous, ModelBlock->Block_List[j].Variable[i]) ;
+          string sModel = symbol_table.getName(ModelBlock->Block_List[j].Variable[i]) ;
           output << sps << "  % equation " << ModelBlock->Block_List[j].Equation[i]+1 << " variable : "
                  << sModel << " (" << ModelBlock->Block_List[j].Variable[i]+1 << ")" << endl;
           eq_node = equations[ModelBlock->Block_List[j].Equation[i]];
@@ -1018,8 +1017,8 @@ ModelTree::writeModelStaticEquationsOrdered_M(Model_Block *ModelBlock, const str
         case EVALUATE_FORWARD_R:
           output << "  if(jacobian_eval)\n";
           output << "    g1( " << g1_index << ", " << g1_index << ")=";
-          writeDerivative(output, ModelBlock->Block_List[j].Equation[0], ModelBlock->Block_List[j].Variable[0], 0, oMatlabStaticModelSparse, temporary_terms, eEndogenous);
-          output << "; % variable=" << symbol_table.getNameByID(eEndogenous, ModelBlock->Block_List[j].Variable[0])
+          writeDerivative(output, ModelBlock->Block_List[j].Equation[0], ModelBlock->Block_List[j].Variable[0], 0, oMatlabStaticModelSparse, temporary_terms);
+          output << "; % variable=" << symbol_table.getName(ModelBlock->Block_List[j].Variable[0])
                  << "(" << variable_table.getLag(variable_table.getSymbolID(ModelBlock->Block_List[j].Variable[0]))
                  << ") " << ModelBlock->Block_List[j].Variable[0]+1
                  << ", equation=" << ModelBlock->Block_List[j].Equation[0]+1 << endl;
@@ -1042,8 +1041,8 @@ ModelTree::writeModelStaticEquationsOrdered_M(Model_Block *ModelBlock, const str
                   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 << ") = g1(" << eqr+1 << ", " << varr+1 << ") + ";
-                  writeDerivative(output, eq, var, k, oMatlabStaticModelSparse, temporary_terms, eEndogenous);
-                  output << "; % variable=" << symbol_table.getNameByID(eEndogenous, var)
+                  writeDerivative(output, eq, var, k, oMatlabStaticModelSparse, temporary_terms);
+                  output << "; % variable=" << symbol_table.getName(var)
                          << "(" << k << ") " << var+1
                          << ", equation=" << eq+1 << endl;
 #ifdef CONDITION
@@ -1103,7 +1102,7 @@ ModelTree::writeModelEquationsCodeOrdered(const string file_name, const Model_Bl
   NodeID lhs=NULL, rhs=NULL;
   BinaryOpNode *eq_node;
   bool lhs_rhs_done;
-  Uff Uf[symbol_table.endo_nbr];
+  Uff Uf[symbol_table.endo_nbr()];
   map<NodeID, int> reference_count;
   map<int,int> ModelBlock_Aggregated_Size, ModelBlock_Aggregated_Number;
   int prev_Simulation_Type=-1;
@@ -1175,7 +1174,7 @@ ModelTree::writeModelEquationsCodeOrdered(const string file_name, const Model_Bl
           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;
           code_file.write(reinterpret_cast<char *>(&v),sizeof(v));
-          v=symbol_table.endo_nbr;
+          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));
@@ -1570,7 +1569,7 @@ ModelTree::writeStaticCFile(const string &static_basename) const
                    << "  if (nlhs >= 2)" << endl
                    << "  {" << endl
                    << "      /* Set the output pointer to the output matrix g1. */" << endl
-                   << "      plhs[1] = mxCreateDoubleMatrix(" << equations.size() << ", " << symbol_table.endo_nbr << ", mxREAL);" << endl
+                   << "      plhs[1] = mxCreateDoubleMatrix(" << equations.size() << ", " << symbol_table.endo_nbr() << ", mxREAL);" << endl
                    << "      /* Create a C pointer to a copy of the output matrix g1. */" << endl
                    << "      g1 = mxGetPr(plhs[1]);" << endl
                    << "  }" << endl
@@ -1692,7 +1691,7 @@ ModelTree::writeStaticModel(ostream &StaticOutput) const
         {
           ostringstream g1;
           g1 << "  g1";
-          matrixHelper(g1, eq, variable_table.getSymbolID(var), output_type);
+          matrixHelper(g1, eq, symbol_table.getTypeSpecificID(variable_table.getSymbolID(var)), output_type);
 
           jacobian_output << g1.str() << "=" << g1.str() << "+";
           d1->writeOutput(jacobian_output, output_type, temporary_terms);
@@ -1714,11 +1713,11 @@ ModelTree::writeStaticModel(ostream &StaticOutput) const
         if (variable_table.getType(var1) == eEndogenous
             && variable_table.getType(var2) == eEndogenous)
           {
-            int id1 = variable_table.getSymbolID(var1);
-            int id2 = variable_table.getSymbolID(var2);
+            int id1 = symbol_table.getTypeSpecificID(variable_table.getSymbolID(var1));
+            int id2 = symbol_table.getTypeSpecificID(variable_table.getSymbolID(var2));
 
-            int col_nb = id1*symbol_table.endo_nbr+id2;
-            int col_nb_sym = id2*symbol_table.endo_nbr+id1;
+            int col_nb = id1*symbol_table.endo_nbr()+id2;
+            int col_nb_sym = id2*symbol_table.endo_nbr()+id1;
 
             hessian_output << "  g2";
             matrixHelper(hessian_output, eq, col_nb, output_type);
@@ -1751,7 +1750,7 @@ ModelTree::writeStaticModel(ostream &StaticOutput) const
                    << "  residual = real(residual)+imag(residual).^2;" << endl
                    << "end" << endl
                    << "if nargout >= 2," << endl
-                   << "  g1 = zeros(" << equations.size() << ", " << symbol_table.endo_nbr << ");" << endl
+                   << "  g1 = zeros(" << equations.size() << ", " << symbol_table.endo_nbr() << ");" << endl
                    << endl
                    << "%" << endl
                    << "% Jacobian matrix" << endl
@@ -1766,7 +1765,7 @@ ModelTree::writeStaticModel(ostream &StaticOutput) const
         {
           StaticOutput << "if nargout >= 3,\n";
           // Writing initialization instruction for matrix g2
-          int ncols = symbol_table.endo_nbr * symbol_table.endo_nbr;
+          int ncols = symbol_table.endo_nbr() * symbol_table.endo_nbr();
           StaticOutput << "  g2 = sparse([],[],[], " << equations.size() << ", " << ncols << ", " << 5*ncols << ");" << endl
                        << endl
                        << "%" << endl
@@ -1943,7 +1942,7 @@ ModelTree::writeSparseStaticMFile(const string &static_basename, const string &b
   mStaticModelFile << "    g1=[];\n";
   mStaticModelFile << "    x=varargin{2}(:);\n";
   mStaticModelFile << "    params=varargin{3}(:);\n";
-  mStaticModelFile << "    residual=zeros(1, " << symbol_table.endo_nbr << ");\n";
+  mStaticModelFile << "    residual=zeros(1, " << symbol_table.endo_nbr() << ");\n";
   prev_Simulation_Type=-1;
   tmp.str("");
   tmp_eq.str("");
@@ -2248,12 +2247,12 @@ ModelTree::writeSparseDynamicMFile(const string &dynamic_basename, const string
               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;
+                    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 << " " << block_triangular.ModelBlock->Block_List[i].Exogenous[ik]+1+j*symbol_table.exo_nbr()+symbol_table.endo_nbr()*tmp_i;
               mDynamicModelFile << " ];\n";
               tmp.str("");
               tmp_eq.str("");
@@ -2673,7 +2672,7 @@ ModelTree::writeOutput(ostream &output) const
   output << "M_.lead_lag_incidence = [";
   // Loop on endogenous variables
   int lag = 0;
-  for (int endoID = 0; endoID < symbol_table.endo_nbr; endoID++)
+  for (int endoID = 0; endoID < symbol_table.endo_nbr(); endoID++)
     {
       output << "\n\t";
       // Loop on periods
@@ -2682,7 +2681,7 @@ ModelTree::writeOutput(ostream &output) const
           // Print variableID if exists with current period, otherwise print 0
           try
             {
-              int varID = variable_table.getID(eEndogenous, endoID, lag);
+              int varID = variable_table.getID(symbol_table.getID(eEndogenous, endoID), lag);
               output << " " << variable_table.getDynJacobianCol(varID) + 1;
             }
           catch (VariableTable::UnknownVariableKeyException &e)
@@ -2773,7 +2772,7 @@ ModelTree::writeOutput(ostream &output) const
                       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]])
+                            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())
@@ -2809,7 +2808,7 @@ ModelTree::writeOutput(ostream &output) const
                           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 (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++;
@@ -2845,7 +2844,7 @@ ModelTree::writeOutput(ostream &output) const
               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++)
+              for (int i=0;i<symbol_table.endo_nbr()*symbol_table.endo_nbr();i++)
                 {
                   if (IM[i])
                     {
@@ -2853,7 +2852,7 @@ ModelTree::writeOutput(ostream &output) const
                         output << " ; ";
                       else
                         output << " ";
-                      output << i/symbol_table.endo_nbr+1 << " " << i % symbol_table.endo_nbr+1;
+                      output << i/symbol_table.endo_nbr()+1 << " " << i % symbol_table.endo_nbr()+1;
                       new_entry=false;
                     }
                 }
@@ -2862,29 +2861,29 @@ ModelTree::writeOutput(ostream &output) const
         }
     }
   // Writing initialization for some other variables
-  output << "M_.exo_names_orig_ord = [1:" << symbol_table.exo_nbr << "];\n";
+  output << "M_.exo_names_orig_ord = [1:" << symbol_table.exo_nbr() << "];\n";
   output << "M_.maximum_lag = " << variable_table.max_lag << ";\n";
   output << "M_.maximum_lead = " << variable_table.max_lead << ";\n";
-  if (symbol_table.endo_nbr)
+  if (symbol_table.endo_nbr())
     {
       output << "M_.maximum_endo_lag = " << variable_table.max_endo_lag << ";\n";
       output << "M_.maximum_endo_lead = " << variable_table.max_endo_lead << ";\n";
-      output << "oo_.steady_state = zeros(" << symbol_table.endo_nbr << ", 1);\n";
+      output << "oo_.steady_state = zeros(" << symbol_table.endo_nbr() << ", 1);\n";
     }
-  if (symbol_table.exo_nbr)
+  if (symbol_table.exo_nbr())
     {
       output << "M_.maximum_exo_lag = " << variable_table.max_exo_lag << ";\n";
       output << "M_.maximum_exo_lead = " << variable_table.max_exo_lead << ";\n";
-      output << "oo_.exo_steady_state = zeros(" << symbol_table.exo_nbr << ", 1);\n";
+      output << "oo_.exo_steady_state = zeros(" << symbol_table.exo_nbr() << ", 1);\n";
     }
-  if (symbol_table.exo_det_nbr)
+  if (symbol_table.exo_det_nbr())
     {
       output << "M_.maximum_exo_det_lag = " << variable_table.max_exo_det_lag << ";\n";
       output << "M_.maximum_exo_det_lead = " << variable_table.max_exo_det_lead << ";\n";
-      output << "oo_.exo_det_steady_state = zeros(" << symbol_table.exo_det_nbr << ", 1);\n";
+      output << "oo_.exo_det_steady_state = zeros(" << symbol_table.exo_det_nbr() << ", 1);\n";
     }
-  if (symbol_table.parameter_nbr)
-    output << "M_.params = repmat(NaN," << symbol_table.parameter_nbr << ", 1);\n";
+  if (symbol_table.param_nbr())
+    output << "M_.params = repmat(NaN," << symbol_table.param_nbr() << ", 1);\n";
 }
 
 void
@@ -2921,10 +2920,10 @@ ModelTree::evaluateJacobian(const eval_context_type &eval_context, jacob_map *j_
             }
           catch (ExprNode::EvalException &e)
             {
-              cout << "evaluation of Jacobian failed for equation " << it->first.first+1 << " and variable " << symbol_table.getNameByID(eEndogenous, variable_table.getSymbolID(it->first.second)) << "(" << variable_table.getLag(it->first.second) << ") [" << variable_table.getSymbolID(it->first.second) << "] !" << endl;
+              cout << "evaluation of Jacobian failed for equation " << it->first.first+1 << " and variable " << symbol_table.getName(variable_table.getSymbolID(it->first.second)) << "(" << variable_table.getLag(it->first.second) << ") [" << variable_table.getSymbolID(it->first.second) << "] !" << endl;
               Id->writeOutput(cout, oMatlabDynamicModelSparse, temporary_terms);
               cout << "\n";
-              cerr << "ModelTree::evaluateJacobian: evaluation of Jacobian failed for equation " << it->first.first+1 << " and variable " << symbol_table.getNameByID(eEndogenous, variable_table.getSymbolID(it->first.second)) << "(" << variable_table.getLag(it->first.second) << ")!" << endl;
+              cerr << "ModelTree::evaluateJacobian: evaluation of Jacobian failed for equation " << it->first.first+1 << " and variable " << symbol_table.getName(variable_table.getSymbolID(it->first.second)) << "(" << variable_table.getLag(it->first.second) << ")!" << endl;
             }
           int eq=it->first.first;
           int var=variable_table.getSymbolID(it->first.second);
@@ -2939,10 +2938,10 @@ ModelTree::evaluateJacobian(const eval_context_type &eval_context, jacob_map *j_
               j++;
               (*j_m)[make_pair(eq,var)]=val;
             }
-          if (IM[eq*symbol_table.endo_nbr+var] && (fabs(val) < cutoff))
+          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";
+                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++;
             }
@@ -2969,7 +2968,7 @@ ModelTree::BlockLinear(Model_Block *ModelBlock)
             {
               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(eEndogenous,var,0)));
+              first_derivatives_type::const_iterator it=first_derivatives.find(make_pair(eq,variable_table.getID(var,0)));
               if (it!= first_derivatives.end())
                 {
                   NodeID Id = it->second;
@@ -2998,7 +2997,7 @@ ModelTree::BlockLinear(Model_Block *ModelBlock)
                 {
                   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(eEndogenous,var,k1)));
+                  first_derivatives_type::const_iterator it=first_derivatives.find(make_pair(eq,variable_table.getID(var,k1)));
                   NodeID Id = it->second;
                   if (it!= first_derivatives.end())
                     {
diff --git a/NumericalInitialization.cc b/NumericalInitialization.cc
index 456d7defd2a63afc40b6576bf68f8324a157b09e..65ba044208171676a3e17f04664a232f9fcfbdd2 100644
--- a/NumericalInitialization.cc
+++ b/NumericalInitialization.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003-2008 Dynare Team
+ * Copyright (C) 2003-2009 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -19,10 +19,12 @@
 
 #include "NumericalInitialization.hh"
 
-InitParamStatement::InitParamStatement(const string &param_name_arg,
+#include "MatlabFile.hh"
+
+InitParamStatement::InitParamStatement(int symb_id_arg,
                                        const NodeID param_value_arg,
                                        const SymbolTable &symbol_table_arg) :
-  param_name(param_name_arg),
+  symb_id(symb_id_arg),
   param_value(param_value_arg),
   symbol_table(symbol_table_arg)
 {
@@ -31,26 +33,26 @@ InitParamStatement::InitParamStatement(const string &param_name_arg,
 void
 InitParamStatement::writeOutput(ostream &output, const string &basename) const
 {
-  int id = symbol_table.getID(param_name) + 1;
+  int id = symbol_table.getTypeSpecificID(symb_id) + 1;
   output << "M_.params( " << id << " ) = ";
   param_value->writeOutput(output);
   output << ";" << endl;
-  output << param_name << " = M_.params( " << id << " );\n";
-}
-
-NodeID
-InitParamStatement::get_expression() const
-{
-  return(param_value);
+  output << symbol_table.getName(symb_id) << " = M_.params( " << id << " );\n";
 }
 
-string
-InitParamStatement::get_name() const
+void
+InitParamStatement::fillEvalContext(eval_context_type &eval_context) const
 {
-  return(param_name);
+  try
+    {
+      eval_context[symb_id] = param_value->eval(eval_context);
+    }
+  catch(ExprNode::EvalException &e)
+    {
+      // Do nothing
+    }
 }
 
-
 InitOrEndValStatement::InitOrEndValStatement(const init_values_type &init_values_arg,
                                              const SymbolTable &symbol_table_arg) :
   init_values(init_values_arg),
@@ -58,17 +60,34 @@ InitOrEndValStatement::InitOrEndValStatement(const init_values_type &init_values
 {
 }
 
+void
+InitOrEndValStatement::fillEvalContext(eval_context_type &eval_context) const
+{
+  for(init_values_type::const_iterator it = init_values.begin();
+      it != init_values.end(); it++)
+    {
+      try
+        {
+          eval_context[it->first] = (it->second)->eval(eval_context);
+        }
+      catch(ExprNode::EvalException &e)
+        {
+          // Do nothing
+        }
+    }
+}
+
 void
 InitOrEndValStatement::writeInitValues(ostream &output) const
 {
   for(init_values_type::const_iterator it = init_values.begin();
       it != init_values.end(); it++)
     {
-      const string &name = it->first;
+      const int symb_id = it->first;
       const NodeID expression = it->second;
 
-      SymbolType type = symbol_table.getType(name);
-      int id = symbol_table.getID(name) + 1;
+      SymbolType type = symbol_table.getType(symb_id);
+      int tsid = symbol_table.getTypeSpecificID(symb_id) + 1;
 
       if (type == eEndogenous)
         output << "oo_.steady_state";
@@ -77,7 +96,7 @@ InitOrEndValStatement::writeInitValues(ostream &output) const
       else if (type == eExogenousDet)
         output << "oo_.exo_det_steady_state";
 
-      output << "( " << id << " ) = ";
+      output << "( " << tsid << " ) = ";
       expression->writeOutput(output);
       output << ";" << endl;
     }
@@ -147,19 +166,19 @@ HistValStatement::writeOutput(ostream &output, const string &basename) const
   for(hist_values_type::const_iterator it = hist_values.begin();
       it != hist_values.end(); it++)
     {
-      const string &name = it->first.first;
+      const int &symb_id = it->first.first;
       const int &lag = it->first.second;
       const NodeID expression = it->second;
 
-      SymbolType type = symbol_table.getType(name);
-      int id = symbol_table.getID(name) + 1;
+      SymbolType type = symbol_table.getType(symb_id);
+      int tsid = symbol_table.getTypeSpecificID(symb_id) + 1;
 
       if (type == eEndogenous)
-        output << "oo_.endo_simul( " << id << ", M_.maximum_lag + " << lag << ") = ";
+        output << "oo_.endo_simul( " << tsid << ", M_.maximum_lag + " << lag << ") = ";
       else if (type == eExogenous)
-        output << "oo_.exo_simul( M_.maximum_lag + " << lag << ", " << id << " ) = ";
+        output << "oo_.exo_simul( M_.maximum_lag + " << lag << ", " << tsid << " ) = ";
       else if (type != eExogenousDet)
-        output << "oo_.exo_det_simul( M_.maximum_lag + " << lag  << ", " << id << " ) = ";
+        output << "oo_.exo_det_simul( M_.maximum_lag + " << lag  << ", " << tsid << " ) = ";
 
       expression->writeOutput(output);
       output << ";" << endl;
@@ -199,14 +218,14 @@ HomotopyStatement::writeOutput(ostream &output, const string &basename) const
   for(homotopy_values_type::const_iterator it = homotopy_values.begin();
       it != homotopy_values.end(); it++)
     {
-      const string &name = it->first;
+      const int &symb_id = it->first;
       const NodeID expression1 = it->second.first;
       const NodeID expression2 = it->second.second;
 
-      const SymbolType type = symbol_table.getType(name);
-      const int id = symbol_table.getID(name) + 1;
+      const SymbolType type = symbol_table.getType(symb_id);
+      const int tsid = symbol_table.getTypeSpecificID(symb_id) + 1;
 
-      output << "options_.homotopy_values = vertcat(options_.homotopy_values, [ " << type << ", " << id << ", ";
+      output << "options_.homotopy_values = vertcat(options_.homotopy_values, [ " << type << ", " << tsid << ", ";
       if (expression1 != NULL)
         expression1->writeOutput(output);
       else
@@ -216,3 +235,61 @@ HomotopyStatement::writeOutput(ostream &output, const string &basename) const
       output << "]);" << endl;
     }
 }
+
+SaveParamsAndSteadyStateStatement::SaveParamsAndSteadyStateStatement(const string &filename_arg) :
+  filename(filename_arg)
+{
+}
+
+void
+SaveParamsAndSteadyStateStatement::writeOutput(ostream &output, const string &basename) const
+{
+  output << "save_params_and_steady_state('" << filename << "');" << endl;
+}
+
+LoadParamsAndSteadyStateStatement::LoadParamsAndSteadyStateStatement(const string &filename_arg,
+                                                                     const SymbolTable &symbol_table_arg) :
+  filename(filename_arg), symbol_table(symbol_table_arg)
+{
+}
+
+void
+LoadParamsAndSteadyStateStatement::writeOutput(ostream &output, const string &basename) const
+{
+  output << "load_params_and_steady_state('" << filename << "');" << endl;
+}
+
+void
+LoadParamsAndSteadyStateStatement::fillEvalContext(eval_context_type &eval_context) const
+{
+  cout << "Reading " << filename << " ...";
+
+  MatlabFile matlab_file;
+  matlab_file.MatFileRead(filename);
+
+  string sname = "stored_values";
+
+  CollectStruct collect_struct;
+  bool tmp_b = matlab_file.Collect(sname, collect_struct);
+  matlab_file.Delete();
+  if (!tmp_b)
+    cout << "The structure " << sname << " was not found in " << filename << endl;
+  cout << "done\n";
+
+  for(map<string, vector<double> >::iterator it = collect_struct.variable_double_name.begin();
+      it != collect_struct.variable_double_name.end(); it++)
+    {
+      const string &symbol_name = it->first;
+      double val = it->second[0];
+
+      try
+        {
+          int symb_id = symbol_table.getID(symbol_name);
+          eval_context[symb_id] = val;
+        }
+      catch(SymbolTable::UnknownSymbolNameException &e)
+        {
+          cerr << "Warning: unknown symbol " << symbol_name << " in " << filename << endl;
+        }
+    }
+}
diff --git a/ParsingDriver.cc b/ParsingDriver.cc
index aa38e10b8bb481469a13325ebd7c91ae2c2e6edd..81d095f52bc66ec5ad92c847e30fcd3ffb2644f9 100644
--- a/ParsingDriver.cc
+++ b/ParsingDriver.cc
@@ -257,22 +257,12 @@ void
 ParsingDriver::init_param(string *name, NodeID rhs)
 {
   check_symbol_existence(*name);
-  if (mod_file->symbol_table.getType(*name) != eParameter)
+  int symb_id = mod_file->symbol_table.getID(*name);
+  if (mod_file->symbol_table.getType(symb_id) != eParameter)
     error(*name + " is not a parameter");
 
-  mod_file->addStatement(new InitParamStatement(*name, rhs, mod_file->symbol_table));
+  mod_file->addStatement(new InitParamStatement(symb_id, rhs, mod_file->symbol_table));
 
-  // Update global eval context
-  /*try
-    {
-    double val = rhs->eval(mod_file->global_eval_context);
-    int symb_id = mod_file->symbol_table.getID(*name);
-    mod_file->global_eval_context[make_pair(symb_id, eParameter)] = val;
-    }
-    catch(ExprNode::EvalException &e)
-    {
-    }
-  */
   delete name;
 }
 
@@ -280,26 +270,16 @@ void
 ParsingDriver::init_val(string *name, NodeID rhs)
 {
   check_symbol_existence(*name);
-  SymbolType type = mod_file->symbol_table.getType(*name);
+  int symb_id = mod_file->symbol_table.getID(*name);
+  SymbolType type = mod_file->symbol_table.getType(symb_id);
 
   if (type != eEndogenous
       && type != eExogenous
       && type != eExogenousDet)
     error("initval/endval: " + *name + " should be an endogenous or exogenous variable");
-  //cout << "mod_file->init_values = " << mod_file->init_values << "\n";
-  mod_file->init_values.push_back(make_pair(*name, rhs));
-  //cout << "init_val " << *name << " mod_file->init_values.size()=" << mod_file->init_values.size() << "\n";
-  // Update global evaluation context
-  /*try
-    {
-    double val = rhs->eval(mod_file->global_eval_context);
-    int symb_id = mod_file->symbol_table.getID(*name);
-    mod_file->global_eval_context[make_pair(symb_id, type)] = val;
-    }
-    catch(ExprNode::EvalException &e)
-    {
-    }
-  */
+
+  init_values.push_back(make_pair(symb_id, rhs));
+
   delete name;
 }
 
@@ -314,7 +294,8 @@ void
 ParsingDriver::hist_val(string *name, string *lag, NodeID rhs)
 {
   check_symbol_existence(*name);
-  SymbolType type = mod_file->symbol_table.getType(*name);
+  int symb_id = mod_file->symbol_table.getID(*name);
+  SymbolType type = mod_file->symbol_table.getType(symb_id);
 
   if (type != eEndogenous
       && type != eExogenous
@@ -322,7 +303,7 @@ ParsingDriver::hist_val(string *name, string *lag, NodeID rhs)
     error("hist_val: " + *name + " should be an endogenous or exogenous variable");
 
   int ilag = atoi(lag->c_str());
-  pair<string, int> key(*name, ilag);
+  pair<int, int> key(symb_id, ilag);
 
   if (hist_values.find(key) != hist_values.end())
     error("hist_val: (" + *name + ", " + *lag + ") declared twice");
@@ -337,14 +318,15 @@ void
 ParsingDriver::homotopy_val(string *name, NodeID val1, NodeID val2)
 {
   check_symbol_existence(*name);
-  SymbolType type = mod_file->symbol_table.getType(*name);
+  int symb_id = mod_file->symbol_table.getID(*name);
+  SymbolType type = mod_file->symbol_table.getType(symb_id);
 
   if (type != eParameter
       && type != eExogenous
       && type != eExogenousDet)
     error("homotopy_val: " + *name + " should be a parameter or exogenous variable");
 
-  homotopy_values.push_back(make_pair(*name, make_pair(val1, val2)));
+  homotopy_values.push_back(make_pair(symb_id, make_pair(val1, val2)));
 
   delete name;
 }
@@ -382,17 +364,15 @@ ParsingDriver::sparse()
 void
 ParsingDriver::end_initval()
 {
-  mod_file->addStatement(new InitValStatement(mod_file->init_values, mod_file->symbol_table));
-  //mod_file->init_values.clear();
-  //cout << "mod_file->init_values.clear() in end_initval()\n";
+  mod_file->addStatement(new InitValStatement(init_values, mod_file->symbol_table));
+  init_values.clear();
 }
 
 void
 ParsingDriver::end_endval()
 {
-  mod_file->addStatement(new EndValStatement(mod_file->init_values, mod_file->symbol_table));
-  //mod_file->init_values.clear();
-  //cout << "mod_file->init_values.clear() in end_endval()\n";
+  mod_file->addStatement(new EndValStatement(init_values, mod_file->symbol_table));
+  init_values.clear();
 }
 
 void
@@ -1016,12 +996,10 @@ ParsingDriver::run_dynasave(string *filename)
   delete filename;
 }
 
-
 void
 ParsingDriver::run_load_params_and_steady_state(string *filename)
 {
-  mod_file->addStatement(new LoadParamsAndSteadyStateStatement(*filename));
-
+  mod_file->addStatement(new LoadParamsAndSteadyStateStatement(*filename, mod_file->symbol_table));
   delete filename;
 }
 
@@ -1032,8 +1010,6 @@ ParsingDriver::run_save_params_and_steady_state(string *filename)
   delete filename;
 }
 
-
-
 void
 ParsingDriver::add_mc_filename(string *filename, string *prior)
 {
diff --git a/Shocks.cc b/Shocks.cc
index e7618adc6c2c3ee7902b33fcc6d0106236123cc5..8c3987cc93f11907539d35d5b758bddbc847da1c 100644
--- a/Shocks.cc
+++ b/Shocks.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003-2008 Dynare Team
+ * Copyright (C) 2003-2009 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -48,7 +48,7 @@ AbstractShocksStatement::writeDetShocks(ostream &output) const
   for(det_shocks_type::const_iterator it = det_shocks.begin();
       it != det_shocks.end(); it++)
     {
-      int id = symbol_table.getID(it->first) + 1;
+      int id = symbol_table.getTypeSpecificID(it->first) + 1;
       bool exo_det = (symbol_table.getType(it->first) == eExogenousDet);
       int set_shocks_index = ((int) mshocks) + 2 * ((int) exo_det);
 
@@ -87,7 +87,7 @@ AbstractShocksStatement::writeVarAndStdShocks(ostream &output) const
 
   for(it = var_shocks.begin(); it != var_shocks.end(); it++)
     {
-      int id = symbol_table.getID(it->first) + 1;
+      int id = symbol_table.getTypeSpecificID(it->first) + 1;
       const NodeID value = it->second;
       output << "M_.Sigma_e(" << id << ", " << id << ") = ";
       value->writeOutput(output);
@@ -96,7 +96,7 @@ AbstractShocksStatement::writeVarAndStdShocks(ostream &output) const
 
   for(it = std_shocks.begin(); it != std_shocks.end(); it++)
     {
-      int id = symbol_table.getID(it->first) + 1;
+      int id = symbol_table.getTypeSpecificID(it->first) + 1;
       const NodeID value = it->second;
       output << "M_.Sigma_e(" << id << ", " << id << ") = (";
       value->writeOutput(output);
@@ -111,8 +111,8 @@ AbstractShocksStatement::writeCovarAndCorrShocks(ostream &output) const
 
   for(it = covar_shocks.begin(); it != covar_shocks.end(); it++)
     {
-      int id1 = symbol_table.getID(it->first.first) + 1;
-      int id2 = symbol_table.getID(it->first.second) + 1;
+      int id1 = symbol_table.getTypeSpecificID(it->first.first) + 1;
+      int id2 = symbol_table.getTypeSpecificID(it->first.second) + 1;
       const NodeID value = it->second;
       output << "M_.Sigma_e(" << id1 << ", " << id2 << ") = ";
       value->writeOutput(output);
@@ -122,8 +122,8 @@ AbstractShocksStatement::writeCovarAndCorrShocks(ostream &output) const
 
   for(it = corr_shocks.begin(); it != corr_shocks.end(); it++)
     {
-      int id1 = symbol_table.getID(it->first.first) + 1;
-      int id2 = symbol_table.getID(it->first.second) + 1;
+      int id1 = symbol_table.getTypeSpecificID(it->first.first) + 1;
+      int id2 = symbol_table.getTypeSpecificID(it->first.second) + 1;
       const NodeID value = it->second;
       output << "M_.Sigma_e(" << id1 << ", " << id2 << ") = ";
       value->writeOutput(output);
diff --git a/Statement.cc b/Statement.cc
index 1032af8a91e8e9b51a544e22d48ca8b4048a5ebf..0594bcc2f3775947a3fb8e0b6bc3b272ab7ba849 100644
--- a/Statement.cc
+++ b/Statement.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006-2008 Dynare Team
+ * Copyright (C) 2006-2009 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -29,8 +29,7 @@ ModFileStructure::ModFileStructure() :
   ramsey_policy_present(false),
   order_option(0),
   bvar_density_present(false),
-  bvar_forecast_present(false),
-  load_params_and_steady_state_present(false)
+  bvar_forecast_present(false)
 {
 }
 
diff --git a/SymbolTable.cc b/SymbolTable.cc
index b01aaca56d28b5d11a0e73eadf84d703dc25fafe..35fbb17bb5b61287ce5e177c2d5463479da38372 100644
--- a/SymbolTable.cc
+++ b/SymbolTable.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003-2008 Dynare Team
+ * Copyright (C) 2003-2009 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -22,104 +22,165 @@
 
 #include "SymbolTable.hh"
 
-SymbolTable::SymbolTable() : endo_nbr(0), exo_nbr(0), exo_det_nbr(0),
-                             parameter_nbr(0), model_local_variable_nbr(0),
-                             modfile_local_variable_nbr(0), unknown_function_nbr(0)
+SymbolTable::SymbolTable() : frozen(false), size(0)
 {
 }
 
 void
-SymbolTable::addSymbol(const string &name, SymbolType type, const string &tex_name) throw (AlreadyDeclaredException)
+SymbolTable::addSymbol(const string &name, SymbolType type, const string &tex_name) throw (AlreadyDeclaredException, FrozenException)
 {
+  if (frozen)
+    throw FrozenException();
+
   if (exists(name))
     {
-      if (symbol_table[name].first == type)
+      if (type_table[getID(name)] == type)
         throw AlreadyDeclaredException(name, true);
       else
         throw AlreadyDeclaredException(name, false);
     }
 
-  int id;
+  int id = size++;
+
+  symbol_table[name] = id;
+  type_table.push_back(type);
+  name_table.push_back(name);
+  tex_name_table.push_back(tex_name);
+}
+
+void
+SymbolTable::freeze() throw (FrozenException)
+{
+  if (frozen)
+    throw FrozenException();
 
-  switch (type)
+  frozen = true;
+
+  for(int i = 0; i < size; i++)
     {
+      int tsi;
+      switch(getType(i))
+        {
+        case eEndogenous:
+          tsi = endo_ids.size();
+          endo_ids.push_back(i);
+          break;
+        case eExogenous:
+          tsi = exo_ids.size();
+          exo_ids.push_back(i);
+          break;
+        case eExogenousDet:
+          tsi = exo_det_ids.size();
+          exo_det_ids.push_back(i);
+          break;
+        case eParameter:
+          tsi = param_ids.size();
+          param_ids.push_back(i);
+          break;
+        default:
+          tsi = -1;
+          break;
+        }
+      type_specific_ids.push_back(tsi);
+    }
+}
+
+void
+SymbolTable::changeType(int id, SymbolType newtype) throw (UnknownSymbolIDException, FrozenException)
+{
+  if (frozen)
+    throw FrozenException();
+
+  if (id < 0 || id >= size)
+    throw UnknownSymbolIDException(id);
+
+  type_table[id] = newtype;
+}
+
+int
+SymbolTable::getID(SymbolType type, int tsid) const throw (UnknownTypeSpecificIDException, NotYetFrozenException)
+{
+  if (!frozen)
+    throw NotYetFrozenException();
+
+  switch(type)
+    {
+    case eEndogenous:
+      if (tsid < 0 || tsid >= (int) endo_ids.size())
+        throw UnknownTypeSpecificIDException(tsid, type);
+      else
+        return endo_ids[tsid];
     case eExogenous:
-      id = exo_nbr++;
-      break;
+      if (tsid < 0 || tsid >= (int) exo_ids.size())
+        throw UnknownTypeSpecificIDException(tsid, type);
+      else
+        return exo_ids[tsid];
     case eExogenousDet:
-      id = exo_det_nbr++;
-      break;
-    case eEndogenous:
-      id = endo_nbr++;
-      break;
+      if (tsid < 0 || tsid >= (int) exo_det_ids.size())
+        throw UnknownTypeSpecificIDException(tsid, type);
+      else
+        return exo_det_ids[tsid];
     case eParameter:
-      id = parameter_nbr++;
-      break;
-    case eModelLocalVariable:
-      id = model_local_variable_nbr++;
-      break;
-    case eModFileLocalVariable:
-      id = modfile_local_variable_nbr++;
-      break;
-    case eUnknownFunction:
-      id = unknown_function_nbr++;
-      break;
+      if (tsid < 0 || tsid >= (int) param_ids.size())
+        throw UnknownTypeSpecificIDException(tsid, type);
+      else
+        return param_ids[tsid];
+    default:
+      throw UnknownTypeSpecificIDException(tsid, type);
     }
-
-  named_symbol_type symbol(type, id); 
-  symbol_table[name] = symbol;
-  name_table[symbol] = name;
-  tex_name_table[symbol] = tex_name;
 }
 
 void
-SymbolTable::writeOutput(ostream &output) const
+SymbolTable::writeOutput(ostream &output) const throw (NotYetFrozenException)
 {
-  if (exo_nbr > 0)
+  if (!frozen)
+    throw NotYetFrozenException();
+
+  if (exo_nbr() > 0)
     {
-      output << "M_.exo_names = '" << getNameByID(eExogenous, 0) << "';" << endl;
-      output << "M_.exo_names_tex = '" << getTeXNameByID(eExogenous, 0) << "';" << endl;
-      for (int id = 1; id < exo_nbr; id++)
+      output << "M_.exo_names = '" << getName(exo_ids[0]) << "';" << endl;
+      output << "M_.exo_names_tex = '" << getTeXName(exo_ids[0]) << "';" << endl;
+      for (int id = 1; id < exo_nbr(); id++)
         {
-          output << "M_.exo_names = strvcat(M_.exo_names, '" << getNameByID(eExogenous, id) << "');" << endl
-                 << "M_.exo_names_tex = strvcat(M_.exo_names_tex, '" << getTeXNameByID(eExogenous, id) << "');" << endl;
+          output << "M_.exo_names = strvcat(M_.exo_names, '" << getName(exo_ids[id]) << "');" << endl
+                 << "M_.exo_names_tex = strvcat(M_.exo_names_tex, '" << getTeXName(exo_ids[id]) << "');" << endl;
         }
     }
-  if (exo_det_nbr > 0)
+  if (exo_det_nbr() > 0)
     {
-      output << "M_.exo_det_names = '" << getNameByID(eExogenousDet, 0) << "';" << endl;
-      output << "M_.exo_det_names_tex = '" << getTeXNameByID(eExogenousDet, 0) << "';" << endl;
-      for (int id = 1; id < exo_det_nbr; id++)
+      output << "M_.exo_det_names = '" << getName(exo_det_ids[0]) << "';" << endl;
+      output << "M_.exo_det_names_tex = '" << getTeXName(exo_det_ids[0]) << "';" << endl;
+      for (int id = 1; id < exo_det_nbr(); id++)
         {
-          output << "M_.exo_det_names = strvcat(M_.exo_det_names, '" << getNameByID(eExogenousDet, id) << "');" << endl
-                 << "M_.exo_det_names_tex = strvcat(M_.exo_det_names_tex, '" << getTeXNameByID(eExogenousDet, id) << "');" << endl;
+          output << "M_.exo_det_names = strvcat(M_.exo_det_names, '" << getName(exo_det_ids[id]) << "');" << endl
+                 << "M_.exo_det_names_tex = strvcat(M_.exo_det_names_tex, '" << getTeXName(exo_det_ids[id]) << "');" << endl;
         }
     }
-  if (endo_nbr > 0)
+  if (endo_nbr() > 0)
     {
-      output << "M_.endo_names = '" << getNameByID(eEndogenous, 0) << "';" << endl;
-      output << "M_.endo_names_tex = '" << getTeXNameByID(eEndogenous, 0) << "';" << endl;
-      for (int id = 1; id < endo_nbr; id++)
+      output << "M_.endo_names = '" << getName(endo_ids[0]) << "';" << endl;
+      output << "M_.endo_names_tex = '" << getTeXName(endo_ids[0]) << "';" << endl;
+      for (int id = 1; id < endo_nbr(); id++)
         {
-          output << "M_.endo_names = strvcat(M_.endo_names, '" << getNameByID(eEndogenous, id) << "');" << endl
-                 << "M_.endo_names_tex = strvcat(M_.endo_names_tex, '" << getTeXNameByID(eEndogenous, id) << "');" << endl;
+          output << "M_.endo_names = strvcat(M_.endo_names, '" << getName(endo_ids[id]) << "');" << endl
+                 << "M_.endo_names_tex = strvcat(M_.endo_names_tex, '" << getTeXName(endo_ids[id]) << "');" << endl;
         }
     }
-  if (parameter_nbr > 0)
+  if (param_nbr() > 0)
     {
-      output << "M_.param_names = '" << getNameByID(eParameter, 0) << "';" << endl;
-      output << "M_.param_names_tex = '" << getTeXNameByID(eParameter, 0) << "';" << endl;
-      for (int id = 1; id < parameter_nbr; id++)
+      output << "M_.param_names = '" << getName(param_ids[0]) << "';" << endl;
+      output << "M_.param_names_tex = '" << getTeXName(param_ids[0]) << "';" << endl;
+      for (int id = 1; id < param_nbr(); id++)
         {
-          output << "M_.param_names = strvcat(M_.param_names, '" << getNameByID(eParameter, id) << "');" << endl
-                 << "M_.param_names_tex = strvcat(M_.param_names_tex, '" << getTeXNameByID(eParameter, id) << "');" << endl;
+          output << "M_.param_names = strvcat(M_.param_names, '" << getName(param_ids[id]) << "');" << endl
+                 << "M_.param_names_tex = strvcat(M_.param_names_tex, '" << getTeXName(param_ids[id]) << "');" << endl;
         }
     }
 
-  output << "M_.exo_det_nbr = " << exo_det_nbr << ";" << endl
-         << "M_.exo_nbr = " << exo_nbr << ";" << endl
-         << "M_.endo_nbr = " << endo_nbr << ";" << endl
-         << "M_.param_nbr = " << parameter_nbr << ";" << endl;
+  output << "M_.exo_det_nbr = " << exo_det_nbr() << ";" << endl
+         << "M_.exo_nbr = " << exo_nbr() << ";" << endl
+         << "M_.endo_nbr = " << endo_nbr() << ";" << endl
+         << "M_.param_nbr = " << param_nbr() << ";" << endl;
 
-  output << "M_.Sigma_e = zeros(" << exo_nbr << ", " << exo_nbr << ");" << endl;
+  output << "M_.Sigma_e = zeros(" << exo_nbr() << ", " << exo_nbr() << ");" << endl;
 }
diff --git a/VariableTable.cc b/VariableTable.cc
index d57fcfd655a4a5bbc9fe1c7492fa098bb6d200f4..29d0f583ccc5341a849b68f02ca2acf25ebb8e0d 100644
--- a/VariableTable.cc
+++ b/VariableTable.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003-2008 Dynare Team
+ * Copyright (C) 2003-2009 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -17,6 +17,7 @@
  * along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <iostream>
 #include <cstdlib>
 
 #include "VariableTable.hh"
@@ -32,12 +33,12 @@ VariableTable::VariableTable(const SymbolTable &symbol_table_arg) :
 }
 
 int
-VariableTable::addVariable(SymbolType type, int symb_id, int lag) throw (DynJacobianColsAlreadyComputedException)
+VariableTable::addVariable(int symb_id, int lag) throw (DynJacobianColsAlreadyComputedException)
 {
   if (dyn_jacobian_cols_table.size() != 0)
     throw DynJacobianColsAlreadyComputedException();
 
-  var_key_type key = make_pair(make_pair(type, lag), symb_id);
+  var_key_type key = make_pair(lag, symb_id);
 
   // Testing if variable already exists
   variable_table_type::const_iterator it = variable_table.find(key);
@@ -47,7 +48,7 @@ VariableTable::addVariable(SymbolType type, int symb_id, int lag) throw (DynJaco
   int var_id = size();
 
   variable_table[key] = var_id;
-  inv_variable_table[var_id] = key;
+  inv_variable_table.push_back(key);
 
   // Setting maximum and minimum lags
   if (max_lead < lag)
@@ -55,7 +56,7 @@ VariableTable::addVariable(SymbolType type, int symb_id, int lag) throw (DynJaco
   else if (-max_lag > lag)
     max_lag = -lag;
 
-  switch(type)
+  switch(symbol_table.getType(symb_id))
     {
     case eEndogenous:
       var_endo_nbr++;
@@ -93,25 +94,22 @@ VariableTable::computeDynJacobianCols() throw (DynJacobianColsAlreadyComputedExc
 
   dyn_jacobian_cols_table.resize(size());
 
-  variable_table_type::const_iterator it = variable_table.begin();
+  variable_table_type::const_iterator it;
 
   // Assign the first columns to endogenous, using the lexicographic order over (lag, symbol_id) implemented in variable_table map
   int sorted_id = 0;
-  while(it->first.first.first == eEndogenous && it != variable_table.end())
+  for(it = variable_table.begin(); it != variable_table.end(); it++)
     {
-      dyn_jacobian_cols_table[it->second] = sorted_id++;
-      it++;
+      if (symbol_table.getType(it->first.second) == eEndogenous)
+        dyn_jacobian_cols_table[it->second] = sorted_id++;
     }
 
-  // Assign subsequent columns to exogenous and then exogenous deterministic, using an offset + symbol_id
-  while(it->first.first.first == eExogenous && it != variable_table.end())
+  // Assign subsequent columns to exogenous and then exogenous deterministic, using an offset + symbol_type_specific_id
+  for(it = variable_table.begin(); it != variable_table.end(); it++)
     {
-      dyn_jacobian_cols_table[it->second] = var_endo_nbr + it->first.second;
-      it++;
-    }
-  while(it->first.first.first == eExogenousDet && it != variable_table.end())
-    {
-      dyn_jacobian_cols_table[it->second] = var_endo_nbr + symbol_table.exo_nbr + it->first.second;
-      it++;
+      if (symbol_table.getType(it->first.second) == eExogenous)
+        dyn_jacobian_cols_table[it->second] = var_endo_nbr + symbol_table.getTypeSpecificID(it->first.second);
+      if (symbol_table.getType(it->first.second) == eExogenousDet)
+        dyn_jacobian_cols_table[it->second] = var_endo_nbr + symbol_table.exo_nbr() + symbol_table.getTypeSpecificID(it->first.second);
     }
 }
diff --git a/include/CodeInterpreter.hh b/include/CodeInterpreter.hh
index 27e9edeebbd1e33b283d7ba74d867f266149816f..86d4218c1b15e9db798ada2365db9b046bfdd2be 100644
--- a/include/CodeInterpreter.hh
+++ b/include/CodeInterpreter.hh
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007-2008 Dynare Team
+ * Copyright (C) 2007-2009 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -80,7 +80,7 @@ enum BlockSimulationType
   };
 
 //! Enumeration of possible symbol types
-/*! Warning: do not to change existing values: the order matters for VariableTable (at least for endogenous and exogenous types), and the values matter for homotopy_setup command */
+/*! Warning: do not to change existing values for 0 to 4: the values matter for homotopy_setup command */
 enum SymbolType
   {
     eEndogenous = 0,               //!< Endogenous
diff --git a/include/ComputingTasks.hh b/include/ComputingTasks.hh
index 7cb3d9ce2ed9dc7cf52a2076bfb6f4594735512f..0f268d2b0f1b8ff9ce67a6c3a18e0fb2688f01ce 100644
--- a/include/ComputingTasks.hh
+++ b/include/ComputingTasks.hh
@@ -287,27 +287,6 @@ public:
   virtual void writeOutput(ostream &output, const string &basename) const;
 };
 
-class SaveParamsAndSteadyStateStatement : public Statement
-{
-private:
-  const string filename;
-public:
-  SaveParamsAndSteadyStateStatement(const string &filename_arg);
-  virtual void writeOutput(ostream &output, const string &basename) const;
-};
-
-class LoadParamsAndSteadyStateStatement : public Statement
-{
-private:
-  const string filename;
-public:
-  LoadParamsAndSteadyStateStatement(const string &filename_arg);
-  virtual void writeOutput(ostream &output, const string &basename) const;
-  virtual void checkPass(ModFileStructure &mod_file_struct);
-  string get_filename() const {return(filename);};
-};
-
-
 class ModelComparisonStatement : public Statement
 {
 public:
diff --git a/include/DataTree.hh b/include/DataTree.hh
index db77f657b9a92fce77339d015449f49c14f69c4e..0b25a8924e15c30b6d4814e66df94a830bf14321 100644
--- a/include/DataTree.hh
+++ b/include/DataTree.hh
@@ -59,8 +59,8 @@ protected:
 
   typedef map<int, NodeID> num_const_node_map_type;
   num_const_node_map_type num_const_node_map;
-  //! Type (symbol_id, type, lag) used as key
-  typedef map<pair<pair<int, SymbolType>, int>, NodeID> variable_node_map_type;
+  //! Pair (symbol_id, lag) used as key
+  typedef map<pair<int, int>, NodeID> variable_node_map_type;
   variable_node_map_type variable_node_map;
   typedef map<pair<NodeID, int>, NodeID> unary_op_node_map_type;
   unary_op_node_map_type unary_op_node_map;
@@ -73,14 +73,16 @@ protected:
   inline NodeID AddUnaryOp(UnaryOpcode op_code, NodeID arg);
   inline NodeID AddBinaryOp(NodeID arg1, BinaryOpcode op_code, NodeID arg2);
   inline NodeID AddTrinaryOp(NodeID arg1, TrinaryOpcode op_code, NodeID arg2, NodeID arg3);
+
+  //! Stores local variables value (maps symbol ID to corresponding node)
+  map<int, NodeID> local_variables_table;
+
 public:
   DataTree(SymbolTable &symbol_table_arg, NumericalConstants &num_constants_arg);
   virtual ~DataTree();
   //! The variable table
   VariableTable variable_table;
   NodeID Zero, One, MinusOne, NaN, Infinity, MinusInfinity;
-  //! Stores local variables value
-  map<int, NodeID> local_variables_table;
 
   //! Raised when a local parameter is declared twice
   class LocalParameterException
@@ -160,6 +162,8 @@ public:
   //! Adds an unknown function node
   /*! \todo Use a map to share identical nodes */
   NodeID AddUnknownFunction(const string &function_name, const vector<NodeID> &arguments);
+  //! Fill eval context with values of local variables
+  void fillEvalContext(eval_context_type &eval_context) const;
 };
 
 inline NodeID
diff --git a/include/ExprNode.hh b/include/ExprNode.hh
index 7f714a6ca99e8ef382956777cea616e5c823a85c..e3134e874229a85af67c5a4eb6db7a4206fe98a0 100644
--- a/include/ExprNode.hh
+++ b/include/ExprNode.hh
@@ -60,9 +60,8 @@ enum ExprNodeOutputType
   };
 
 //! Type for evaluation contexts
-/*! The key is a pair (symbol id, symbol type)
-  Lags are assumed to be null */
-typedef map<pair<int, SymbolType>, double> eval_context_type;
+/*! The key is a symbol id. Lags are assumed to be null */
+typedef map<int, double> eval_context_type;
 
 /* Equal to 1 for Matlab langage, or to 0 for C language
    In Matlab, array indexes begin at 1, while they begin at 0 in C */
@@ -201,7 +200,7 @@ private:
   int var_id;
   virtual NodeID computeDerivative(int varID);
 public:
-  VariableNode(DataTree &datatree_arg, int symb_id_arg, SymbolType type_arg, int lag_arg);
+  VariableNode(DataTree &datatree_arg, int symb_id_arg, int lag_arg);
   virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms = temporary_terms_type()) const;
   virtual void collectEndogenous(set<pair<int, int> > &result) const;
   virtual void collectExogenous(set<pair<int, int> > &result) const;
diff --git a/include/ModFile.hh b/include/ModFile.hh
index f20cf40b81191ba9fc091b7e539fc6463e29ffc5..1ea1a26b54e738500d245029b2df3349ca71af20 100644
--- a/include/ModFile.hh
+++ b/include/ModFile.hh
@@ -25,14 +25,12 @@ using namespace std;
 #include <ostream>
 #include <ctime>
 
-
 #include "SymbolTable.hh"
 #include "NumericalConstants.hh"
 #include "NumericalInitialization.hh"
 #include "ModelTree.hh"
 #include "VariableTable.hh"
 #include "Statement.hh"
-#include "MatlabFile.hh"
 
 //! The abstract representation of a "mod" file
 class ModFile
@@ -48,15 +46,11 @@ public:
   DataTree expressions_tree;
   //! Model equations and their derivatives
   ModelTree model_tree;
-  //! MatFile reading
-  MatlabFile matlab_file;
   //! Option linear
   bool linear;
   //! Global evaluation context
   /*! Filled using initval blocks and parameters initializations */
   eval_context_type global_eval_context;
-  //! Temporary storage for initval/endval blocks
-  InitOrEndValStatement::init_values_type init_values;
 
 private:
   //! List of statements
diff --git a/include/ModelTree.hh b/include/ModelTree.hh
index b6bbc15d66364fbddd7fbd134e93820c1559a376..b5ff7fb4bef67eb535002c464e66836548dceff9 100644
--- a/include/ModelTree.hh
+++ b/include/ModelTree.hh
@@ -82,7 +82,7 @@ private:
   //! Computes derivatives of ModelTree
   void derive(int order);
   //! Write derivative of an equation w.r. to a variable
-  void writeDerivative(ostream &output, int eq, int symb_id, int lag, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms, SymbolType type) const;
+  void writeDerivative(ostream &output, int eq, int symb_id, int lag, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms) const;
   //! Write derivative code of an equation w.r. to a variable
   void compileDerivative(ofstream &code_file, int eq, int symb_id, int lag, ExprNodeOutputType output_type, map_idx_type &map_idx) const;
   //! Computes temporary terms
diff --git a/include/NumericalInitialization.hh b/include/NumericalInitialization.hh
index d9fd9360c1e3bb6e31a65d9fd9a972b7a4e736aa..77972ca529095a1490c94fda7c5dc4f118053874 100644
--- a/include/NumericalInitialization.hh
+++ b/include/NumericalInitialization.hh
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003-2008 Dynare Team
+ * Copyright (C) 2003-2009 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -23,6 +23,7 @@
 using namespace std;
 
 #include <string>
+#include <vector>
 #include <map>
 
 #include "SymbolTable.hh"
@@ -32,15 +33,15 @@ using namespace std;
 class InitParamStatement : public Statement
 {
 private:
-  const string param_name;
+  const int symb_id;
   const NodeID param_value;
   const SymbolTable &symbol_table;
 public:
-  InitParamStatement(const string &param_name_arg, const NodeID param_value_arg,
+  InitParamStatement(int symb_id_arg, const NodeID param_value_arg,
                      const SymbolTable &symbol_table_arg);
   virtual void writeOutput(ostream &output, const string &basename) const;
-  NodeID get_expression() const;
-  string get_name() const;
+  //! Fill eval context with parameter value
+  void fillEvalContext(eval_context_type &eval_context) const;
 };
 
 class InitOrEndValStatement : public Statement
@@ -50,13 +51,15 @@ public:
     We use a vector instead of a map, since the order of declaration matters:
     an initialization can depend on a previously initialized variable inside the block
   */
-  typedef vector<pair<string, NodeID> > init_values_type;
+  typedef vector<pair<int, NodeID> > init_values_type;
 protected:
   const init_values_type init_values;
   const SymbolTable &symbol_table;
 public:
   InitOrEndValStatement(const init_values_type &init_values_arg,
                         const SymbolTable &symbol_table_arg);
+  //! Fill eval context with variables values
+  void fillEvalContext(eval_context_type &eval_context) const;
 protected:
   void writeInitValues(ostream &output) const;
 };
@@ -83,8 +86,9 @@ public:
   /*!
     Contrary to Initval and Endval, we use a map, since it is impossible to reuse
     a given initialization value in a second initialization inside the block.
+    Maps pairs (symbol_id, lag) to NodeID
   */
-  typedef map<pair<string, int>, NodeID> hist_values_type;
+  typedef map<pair<int, int>, NodeID> hist_values_type;
 private:
   const hist_values_type hist_values;
   const SymbolTable &symbol_table;
@@ -108,7 +112,7 @@ class HomotopyStatement : public Statement
 public:
   //! Stores the declarations of homotopy_setup
   /*! Order matter so we use a vector. First NodeID can be NULL if no initial value given. */
-  typedef vector<pair<string, pair<NodeID, NodeID> > > homotopy_values_type;
+  typedef vector<pair<int, pair<NodeID, NodeID> > > homotopy_values_type;
 private:
   const homotopy_values_type homotopy_values;
   const SymbolTable &symbol_table;
@@ -117,4 +121,27 @@ public:
                     const SymbolTable &symbol_table_arg);
   virtual void writeOutput(ostream &output, const string &basename) const;
 };
+
+class SaveParamsAndSteadyStateStatement : public Statement
+{
+private:
+  const string filename;
+public:
+  SaveParamsAndSteadyStateStatement(const string &filename_arg);
+  virtual void writeOutput(ostream &output, const string &basename) const;
+};
+
+class LoadParamsAndSteadyStateStatement : public Statement
+{
+private:
+  const string filename;
+  const SymbolTable &symbol_table;
+public:
+  LoadParamsAndSteadyStateStatement(const string &filename_arg,
+                                    const SymbolTable &symbol_table_arg);
+  virtual void writeOutput(ostream &output, const string &basename) const;
+  //! Fill eval context with parameters/variables values
+  void fillEvalContext(eval_context_type &eval_context) const;
+};
+
 #endif
diff --git a/include/ParsingDriver.hh b/include/ParsingDriver.hh
index 7120acb8d79e083f51b637da602ce17f03ce7dab..a1d7f86174663b24d524b87dedd116fe48b67362 100644
--- a/include/ParsingDriver.hh
+++ b/include/ParsingDriver.hh
@@ -129,6 +129,8 @@ private:
   SigmaeStatement::row_type sigmae_row;
   //! Temporary storage for Sigma_e matrix
   SigmaeStatement::matrix_type sigmae_matrix;
+  //! Temporary storage for initval/endval blocks
+  InitOrEndValStatement::init_values_type init_values;
   //! Temporary storage for histval blocks
   HistValStatement::hist_values_type hist_values;
   //! Temporary storage for homotopy_setup blocks
diff --git a/include/Statement.hh b/include/Statement.hh
index 324e0a143286b77d52777f2fb9f7c94429ffe8f4..deba172a86bfb66bf69083b407129665a051ee07 100644
--- a/include/Statement.hh
+++ b/include/Statement.hh
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006-2008 Dynare Team
+ * Copyright (C) 2006-2009 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -54,10 +54,6 @@ public:
   bool bvar_density_present;
   //! Whether a bvar_forecast statement is present
   bool bvar_forecast_present;
-  //! Wether load_params_and_steady_state is present
-  bool load_params_and_steady_state_present;
-  //! save the load_params_and_steady state_filename
-  string load_params_and_steady_state_filename;
 };
 
 class Statement
diff --git a/include/SymbolTable.hh b/include/SymbolTable.hh
index 622261041c64a360db8a295d4e2cee0d9311d125..f33e07f95e38e5b748d602922b15a976b2f6d6bc 100644
--- a/include/SymbolTable.hh
+++ b/include/SymbolTable.hh
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003-2008 Dynare Team
+ * Copyright (C) 2003-2009 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -26,32 +26,50 @@ using namespace std;
 #include <string>
 #include <vector>
 #include <ostream>
-#include <iostream>
+
 #include "CodeInterpreter.hh"
 
 //! Stores the symbol table
 /*!
-  A symbol is given by its name, and is internally represented by a pair (type, id).
+  A symbol is given by its name, and is internally represented by a unique integer.
 
-  There is a distinct sequence of ids for each type, so two symbol of different types can have the same id.
+  When method freeze() is called, computes a distinct sequence of IDs for some types
+  (endogenous, exogenous, parameters), which are used by the Matlab/Octave functions.
+  We call these "type specific IDs".
 
   Also manages a TeX name for each symbol, which by default is an empty string.
 */
 class SymbolTable
 {
 private:
-  //! A symbol is represented by a pair (type, id)
-  typedef pair<SymbolType, int> named_symbol_type;
+  //! Has method freeze() been called?
+  bool frozen;
+
+  //! Number of symbols contained in the table
+  int size;
 
-  typedef map<string, named_symbol_type> symbol_table_type;
-  //! Maps strings to pairs (type,id)
+  typedef map<string, int> symbol_table_type;
+  //! Maps strings to symbol IDs
   symbol_table_type symbol_table;
 
-  typedef map<named_symbol_type, string> inv_symbol_table_type;
-  //! Maps pairs (type, id) to names
-  inv_symbol_table_type name_table;
-  //! Maps pairs (type, id) to TeX names
-  inv_symbol_table_type tex_name_table;
+  //! Maps IDs to names
+  vector<string> name_table;
+  //! Maps IDs to TeX names
+  vector<string> tex_name_table;
+  //! Maps IDs to types
+  vector<SymbolType> type_table;
+
+  //! Maps symbol IDs to type specific IDs
+  vector<int> type_specific_ids;
+
+  //! Maps type specific IDs of endogenous to symbol IDs
+  vector<int> endo_ids;
+  //! Maps type specific IDs of exogenous to symbol IDs
+  vector<int> exo_ids;
+  //! Maps type specific IDs of exogenous deterministic to symbol IDs
+  vector<int> exo_det_ids;
+  //! Maps type specific IDs of parameters to symbol IDs
+  vector<int> param_ids;
 public:
   SymbolTable();
   //! Thrown when trying to access an unknown symbol (by name)
@@ -62,15 +80,21 @@ public:
     string name;
     UnknownSymbolNameException(const string &name_arg) : name(name_arg) {}
   };
-  //! Thrown when trying to access an unknown symbol (by type+id pair)
+  //! Thrown when trying to access an unknown symbol (by id)
   class UnknownSymbolIDException
   {
   public:
-    //! Symbol type
-    SymbolType type;
     //! Symbol ID
     int id;
-    UnknownSymbolIDException(SymbolType type_arg, int id_arg) : type(type_arg), id(id_arg) {}
+    UnknownSymbolIDException(int id_arg) : id(id_arg) {}
+  };
+  //! Thrown when trying to access an unknown type specific ID
+  class UnknownTypeSpecificIDException
+  {
+  public:
+    int tsid;
+    SymbolType type;
+    UnknownTypeSpecificIDException(int tsid_arg, SymbolType type_arg) : tsid(tsid_arg), type(type_arg) {}
   };
   //! Thrown when trying to declare a symbol twice
   class AlreadyDeclaredException
@@ -82,34 +106,50 @@ public:
     bool same_type;
     AlreadyDeclaredException(const string &name_arg, bool same_type_arg) : name(name_arg), same_type(same_type_arg) {}
   };
-  //! Number of declared endogenous variables
-  int endo_nbr;
-  //! Number of declared exogenous variables
-  int exo_nbr;
-  //! Number of declared deterministic exogenous variables
-  int exo_det_nbr;
-  //! Number of declared parameters
-  int parameter_nbr;
-  //! Number of model local variables
-  int model_local_variable_nbr;
-  //! Number of modfile local variables
-  int modfile_local_variable_nbr;
-  //! Number of unknown functions
-  int unknown_function_nbr;
+  //! Thrown when table is frozen and trying to modify it
+  class FrozenException
+  {
+  };
+  //! Thrown when trying to use the result of freeze() while this method has not yet been called
+  class NotYetFrozenException
+  {
+  };
   //! Add a symbol
-  void addSymbol(const string &name, SymbolType type, const string &tex_name = "") throw (AlreadyDeclaredException);
+  void addSymbol(const string &name, SymbolType type, const string &tex_name = "") throw (AlreadyDeclaredException, FrozenException);
   //! Tests if symbol already exists
   inline bool exists(const string &name) const;
-  //! Get symbol name by type and ID
-  inline string getNameByID(SymbolType type, int id) const throw (UnknownSymbolIDException);
-  //! Get TeX name by type and ID
-  inline string getTeXNameByID(SymbolType type, int id) const throw (UnknownSymbolIDException);
-  //! Get type by name
+  //! Get symbol name (by ID)
+  inline string getName(int id) const throw (UnknownSymbolIDException);
+  //! Get TeX name
+  inline string getTeXName(int id) const throw (UnknownSymbolIDException);
+  //! Get type (by ID)
+  inline SymbolType getType(int id) const throw (UnknownSymbolIDException);
+  //! Get type (by name)
   inline SymbolType getType(const string &name) const throw (UnknownSymbolNameException);
-  //! Get ID by name
+  //! Get ID (by name)
   inline int getID(const string &name) const throw (UnknownSymbolNameException);
+  //! Get ID (by type specific ID)
+  int getID(SymbolType type, int tsid) const throw (UnknownTypeSpecificIDException, NotYetFrozenException);
+  //! Freeze symbol table
+  void freeze() throw (FrozenException);
+  //! Change the type of a symbol
+  void changeType(int id, SymbolType newtype) throw (UnknownSymbolIDException, FrozenException);
+  //! Get type specific ID (by symbol ID)
+  inline int getTypeSpecificID(int id) const throw (UnknownSymbolIDException, NotYetFrozenException);
+  //! Get type specific ID (by symbol name)
+  inline int getTypeSpecificID(const string &name) const throw (UnknownSymbolNameException, NotYetFrozenException);
+  //! Get number of endogenous variables
+  inline int endo_nbr() const throw (NotYetFrozenException);
+  //! Get number of exogenous variables
+  inline int exo_nbr() const throw (NotYetFrozenException);
+  //! Get number of exogenous deterministic variables
+  inline int exo_det_nbr() const throw (NotYetFrozenException);
+  //! Get number of parameters
+  inline int param_nbr() const throw (NotYetFrozenException);
+  //! Returns the greatest symbol ID (the smallest is zero)
+  inline int maxID();
   //! Write output of this class
-  void writeOutput(ostream &output) const;
+  void writeOutput(ostream &output) const throw (NotYetFrozenException);
 };
 
 inline bool
@@ -120,33 +160,36 @@ SymbolTable::exists(const string &name) const
 }
 
 inline string
-SymbolTable::getNameByID(SymbolType type, int id) const throw (UnknownSymbolIDException)
+SymbolTable::getName(int id) const throw (UnknownSymbolIDException)
 {
-  inv_symbol_table_type::const_iterator iter = name_table.find(make_pair(type, id));
-  if (iter != name_table.end())
-    return iter->second;
+  if (id < 0 || id >= size)
+    throw UnknownSymbolIDException(id);
   else
-    throw UnknownSymbolIDException(type, id);
+    return name_table[id];
 }
 
 inline string
-SymbolTable::getTeXNameByID(SymbolType type, int id) const throw (UnknownSymbolIDException)
+SymbolTable::getTeXName(int id) const throw (UnknownSymbolIDException)
 {
-  inv_symbol_table_type::const_iterator iter = tex_name_table.find(make_pair(type, id));
-  if (iter != tex_name_table.end())
-    return iter->second;
+  if (id < 0 || id >= size)
+    throw UnknownSymbolIDException(id);
   else
-    throw UnknownSymbolIDException(type, id);
+    return tex_name_table[id];
 }
 
 inline SymbolType
-SymbolTable::getType(const string &name) const throw (UnknownSymbolNameException)
+SymbolTable::getType(int id) const throw (UnknownSymbolIDException)
 {
-  symbol_table_type::const_iterator iter = symbol_table.find(name);
-  if (iter != symbol_table.end())
-    return iter->second.first;
+  if (id < 0 || id >= size)
+    throw UnknownSymbolIDException(id);
   else
-    throw UnknownSymbolNameException(name);
+    return type_table[id];
+}
+
+inline SymbolType
+SymbolTable::getType(const string &name) const throw (UnknownSymbolNameException)
+{
+  return getType(getID(name));
 }
 
 inline int
@@ -154,9 +197,69 @@ SymbolTable::getID(const string &name) const throw (UnknownSymbolNameException)
 {
   symbol_table_type::const_iterator iter = symbol_table.find(name);
   if (iter != symbol_table.end())
-    return iter->second.second;
+    return iter->second;
   else
     throw UnknownSymbolNameException(name);
 }
 
+inline int
+SymbolTable::getTypeSpecificID(int id) const throw (UnknownSymbolIDException, NotYetFrozenException)
+{
+  if (!frozen)
+    throw NotYetFrozenException();
+
+  if (id < 0 || id >= size)
+    throw UnknownSymbolIDException(id);
+
+  return type_specific_ids[id];
+}
+
+inline int
+SymbolTable::getTypeSpecificID(const string &name) const throw (UnknownSymbolNameException, NotYetFrozenException)
+{
+  return getTypeSpecificID(getID(name));
+}
+
+inline int
+SymbolTable::endo_nbr() const throw (NotYetFrozenException)
+{
+  if (!frozen)
+    throw NotYetFrozenException();
+
+  return endo_ids.size();
+}
+
+inline int
+SymbolTable::exo_nbr() const throw (NotYetFrozenException)
+{
+  if (!frozen)
+    throw NotYetFrozenException();
+
+  return exo_ids.size();
+}
+
+inline int
+SymbolTable::exo_det_nbr() const throw (NotYetFrozenException)
+{
+  if (!frozen)
+    throw NotYetFrozenException();
+
+  return exo_det_ids.size();
+}
+
+inline int
+SymbolTable::param_nbr() const throw (NotYetFrozenException)
+{
+  if (!frozen)
+    throw NotYetFrozenException();
+
+  return param_ids.size();
+}
+
+inline int
+SymbolTable::maxID()
+{
+  return(size-1);
+}
+
 #endif
diff --git a/include/VariableTable.hh b/include/VariableTable.hh
index 0df13c4faa40481a872055b9f9a30cf6dac975f7..df6978a01f84a97fe2bf478ef54442cad23fb763 100644
--- a/include/VariableTable.hh
+++ b/include/VariableTable.hh
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003-2008 Dynare Team
+ * Copyright (C) 2003-2009 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -28,23 +28,21 @@ using namespace std;
 #include "SymbolTable.hh"
 
 //! Used to keep track of variables in the sense of the models, i.e. pairs (symbol, lead/lag)
-/*! Warning: some methods access variables through the tuple (type, symbol_id, lag), but internally the class uses a lexicographic order over (type, lag, symbol_id) */
+/*! Warning: some methods access variables through the pair (symbol_id, lag), but internally the class uses a lexicographic order over (lag, symbol_id) */
 class VariableTable
 {
 private:
   //! A reference to the symbol table
   const SymbolTable &symbol_table;
-  //! A variable is a tuple (type, lag, symbol_id)
-  /*! Warning: don't change the order of elements in the tuple, since this determines the lexicographic ordering in computeDynJacobianCols() */
-  typedef pair<pair<SymbolType, int>, int> var_key_type;
+  //! A variable is a pair (lag, symbol_id)
+  typedef pair<int, int> var_key_type;
 
   typedef map<var_key_type, int> variable_table_type;
-  //! Maps a tuple (type, lag, symbol_id) to a variable ID
+  //! Maps a pair (lag, symbol_id) to a variable ID
   variable_table_type variable_table;
 
-  typedef map<int, var_key_type> inv_variable_table_type;
-  //! Maps a variable ID to a tuple (type, lag, symbol_id)
-  inv_variable_table_type inv_variable_table;
+  //! Maps a variable ID to a pair (lag, symbol_id)
+  vector<var_key_type> inv_variable_table;
 
   //! Number of dynamic endogenous variables inside the model block
   int var_endo_nbr;
@@ -73,13 +71,12 @@ public:
   int max_exo_det_lag;
   //! Maximum lead over deterministic exogenous variables
   int max_exo_det_lead;
-  //! Thrown when trying to access an unknown variable by (type, symb_id, lag)
+  //! Thrown when trying to access an unknown variable by (symb_id, lag)
   class UnknownVariableKeyException
   {
   public:
-    SymbolType type;
     int symb_id, lag;
-    UnknownVariableKeyException(SymbolType type_arg, int symb_id_arg, int lag_arg) : type(type_arg), symb_id(symb_id_arg), lag(lag_arg) {}
+    UnknownVariableKeyException(int symb_id_arg, int lag_arg) : symb_id(symb_id_arg), lag(lag_arg) {}
   };
   //! Thrown when trying to access an unknown variable by var_id
   class UnknownVariableIDException
@@ -99,9 +96,9 @@ public:
   };
   //! Adds a variable in the table, and returns its (newly allocated) variable ID
   /*! Also works if the variable already exists */
-  int addVariable(SymbolType type, int symb_id, int lag) throw (DynJacobianColsAlreadyComputedException);
+  int addVariable(int symb_id, int lag) throw (DynJacobianColsAlreadyComputedException);
   //! Return variable ID
-  inline int getID(SymbolType type, int symb_id, int lag) const throw (UnknownVariableKeyException);
+  inline int getID(int symb_id, int lag) const throw (UnknownVariableKeyException);
   //! Return lag of variable
   inline int getLag(int var_id) const throw (UnknownVariableIDException);
   //! Return symbol ID of variable
@@ -131,11 +128,11 @@ VariableTable::getDynJacobianCol(int var_id) const throw (DynJacobianColsNotYetC
 }
 
 inline int
-VariableTable::getID(SymbolType type, int symb_id, int lag) const throw (UnknownVariableKeyException)
+VariableTable::getID(int symb_id, int lag) const throw (UnknownVariableKeyException)
 {
-  variable_table_type::const_iterator it = variable_table.find(make_pair(make_pair(type, lag), symb_id));
+  variable_table_type::const_iterator it = variable_table.find(make_pair(lag, symb_id));
   if (it == variable_table.end())
-    throw UnknownVariableKeyException(type, symb_id, lag);
+    throw UnknownVariableKeyException(symb_id, lag);
   else
     return it->second;
 }
@@ -143,31 +140,28 @@ VariableTable::getID(SymbolType type, int symb_id, int lag) const throw (Unknown
 inline SymbolType
 VariableTable::getType(int var_id) const throw (UnknownVariableIDException)
 {
-  inv_variable_table_type::const_iterator it = inv_variable_table.find(var_id);
-  if (it != inv_variable_table.end())
-    return it->second.first.first;
-  else
+  if (var_id < 0 || var_id >= size())
     throw UnknownVariableIDException(var_id);
+
+  return symbol_table.getType(inv_variable_table[var_id].second);
 }
 
 inline int
 VariableTable::getSymbolID(int var_id) const throw (UnknownVariableIDException)
 {
-  inv_variable_table_type::const_iterator it = inv_variable_table.find(var_id);
-  if (it != inv_variable_table.end())
-    return it->second.second;
-  else
+  if (var_id < 0 || var_id >= size())
     throw UnknownVariableIDException(var_id);
+
+  return inv_variable_table[var_id].second;
 }
 
 inline int
 VariableTable::getLag(int var_id) const throw (UnknownVariableIDException)
 {
-  inv_variable_table_type::const_iterator it = inv_variable_table.find(var_id);
-  if (it != inv_variable_table.end())
-    return it->second.first.second;
-  else
+  if (var_id < 0 || var_id >= size())
     throw UnknownVariableIDException(var_id);
+
+  return inv_variable_table[var_id].first;
 }
 
 inline int
@@ -180,7 +174,7 @@ inline int
 VariableTable::getDynJacobianColsNbr(bool computeJacobianExo) const
 {
   if (computeJacobianExo)
-    return var_endo_nbr + symbol_table.exo_nbr + symbol_table.exo_det_nbr;
+    return var_endo_nbr + symbol_table.exo_nbr() + symbol_table.exo_det_nbr();
   else
     return var_endo_nbr;
 }