diff --git a/DynamicModel.cc b/DynamicModel.cc
index 0bbf6e5bd4e2c5062430ca1075c11171bbc66855..5a97ef2a55dc628410f66dbc790b26b9b388bd4a 100644
--- a/DynamicModel.cc
+++ b/DynamicModel.cc
@@ -1995,6 +1995,15 @@ DynamicModel::writeDynamicModel(ostream &DynamicOutput, bool use_dll) const
 void
 DynamicModel::writeOutput(ostream &output, const string &basename, bool block, bool byte_code, bool use_dll) const
   {
+    // Write list of predetermined variables in M_.predetermined_variables
+    if (predetermined_variables_vec.size() > 0)
+      {
+        output << "M_.predetermined_variables = '';" <<  endl;
+        for(vector <string>::const_iterator it = predetermined_variables_vec.begin();
+            it != predetermined_variables_vec.end(); it++)
+          output << "M_.predetermined_variables = strvcat(M_.predetermined_variables, '" << *it << "');" << endl;
+      }
+
     /* Writing initialisation for M_.lead_lag_incidence matrix
        M_.lead_lag_incidence is a matrix with as many columns as there are
        endogenous variables and as many rows as there are periods in the
@@ -3078,6 +3087,40 @@ DynamicModel::substituteExpectation(bool partial_information_model)
       cout << "Substitution of Expectation operator: added " << neweqs.size() << " auxiliary variables and equations." << endl;
 }
 
+void
+DynamicModel::transformPredeterminedVariables()
+{
+  for(vector <string>::const_iterator it = predetermined_variables_vec.begin();
+      it != predetermined_variables_vec.end(); it++)
+    {
+      try
+        {
+          if(symbol_table.getType(*it)!=eEndogenous)
+            {
+              cerr << "Error: You must declare predetermined variable " << *it << " as an endogenous variable." << endl;
+              exit(EXIT_FAILURE);
+            }
+        }
+      catch(SymbolTable::UnknownSymbolNameException &e)
+        {
+          cerr << "Error: predetermind variable " << *it << " has not been declared." << endl;
+          exit(EXIT_FAILURE);
+        }
+      catch(...)
+        {
+          cerr << "error in DynamicModel::transformPredeterminedVariables(), should not arrive here" << endl;
+          exit(EXIT_FAILURE);
+        }
+
+      for(int i = 0; i < (int) equations.size(); i++)
+        {
+          BinaryOpNode *substeq = dynamic_cast<BinaryOpNode *>(equations[i]->decreaseLeadsLagsPredeterminedVariables(*it));
+          assert(substeq != NULL);
+          equations[i] = substeq;
+        }
+    }
+}
+
 void
 DynamicModel::fillEvalContext(eval_context_type &eval_context) const
 {
diff --git a/DynamicModel.hh b/DynamicModel.hh
index a17fab51cbf69a29ad1e75adb8dd746824abf4e5..785f06e61b6756832ba20cbcf26afbe2d142926a 100644
--- a/DynamicModel.hh
+++ b/DynamicModel.hh
@@ -165,6 +165,8 @@ public:
   int mfs;
   //! the file containing the model and the derivatives code
   ofstream code_file;
+  //! Stores variables declared to be predetermined by "predetermined_variables" statement
+  vector<string> predetermined_variables_vec;
   //! Execute computations (variable sorting + derivation)
   /*!
     \param jacobianExo whether derivatives w.r. to exo and exo_det should be in the Jacobian (derivatives w.r. to endo are always computed)
@@ -220,6 +222,9 @@ public:
   //! Transforms the model by removing all oExpectation
   void substituteExpectation(bool partial_information_model);
 
+  //! Transforms the model by decreasing the lead/lag of predetermined variables in model equations by one
+  void transformPredeterminedVariables();
+
   //! Fills eval context with values of model local variables and auxiliary variables
   void fillEvalContext(eval_context_type &eval_context) const;
 };
diff --git a/DynareBison.yy b/DynareBison.yy
index 74afd2d00889839fa94e28637996a9cf60bcc873..81eafe0ef0a6134f0b1aa4b85596ea76c5b28c05 100644
--- a/DynareBison.yy
+++ b/DynareBison.yy
@@ -123,7 +123,7 @@ class ParsingDriver;
 %token TEX RAMSEY_POLICY PLANNER_DISCOUNT
 %token <string_val> TEX_NAME
 %token UNIFORM_PDF UNIT_ROOT_VARS USE_DLL USEAUTOCORR
-%token VALUES VAR VAREXO VAREXO_DET VAROBS
+%token VALUES VAR VAREXO VAREXO_DET VAROBS PREDETERMINED_VARIABLES
 %token WRITE_LATEX_DYNAMIC_MODEL WRITE_LATEX_STATIC_MODEL
 %token XLS_SHEET XLS_RANGE
 %left COMMA
@@ -177,6 +177,7 @@ statement : parameters
           | var
           | varexo
           | varexo_det
+          | predetermined_variables
           | change_type
           | periods
           | model
@@ -246,6 +247,8 @@ varexo : VAREXO varexo_list ';';
 
 varexo_det : VAREXO_DET varexo_det_list ';';
 
+predetermined_variables : PREDETERMINED_VARIABLES predetermined_variables_list ';';
+
 parameters : PARAMETERS parameter_list ';';
 
 var_list : var_list symbol
@@ -304,6 +307,14 @@ parameter_list : parameter_list symbol
                  { driver.declare_parameter($1, $2); }
                ;
 
+predetermined_variables_list : predetermined_variables_list symbol
+                               { driver.add_predetermined_variable($2); }
+                             | predetermined_variables_list COMMA symbol
+                               { driver.add_predetermined_variable($3); }
+                             | symbol
+                               { driver.add_predetermined_variable($1); }
+                             ;
+
 change_type : CHANGE_TYPE '(' change_type_arg ')' change_type_var_list ';'
               { driver.change_type($3, $5); }
             ;
diff --git a/DynareFlex.ll b/DynareFlex.ll
index 35bf2b8480f043c91853defd2ee8fff4477c1ecf..d91c0e119437328cfc27a583f9d5d9051f03e6e1 100644
--- a/DynareFlex.ll
+++ b/DynareFlex.ll
@@ -98,6 +98,7 @@ int sigma_e = 0;
 <INITIAL>var {BEGIN DYNARE_STATEMENT; return token::VAR;}
 <INITIAL>varexo {BEGIN DYNARE_STATEMENT; return token::VAREXO;}
 <INITIAL>varexo_det {BEGIN DYNARE_STATEMENT; return token::VAREXO_DET;}
+<INITIAL>predetermined_variables {BEGIN DYNARE_STATEMENT; return token::PREDETERMINED_VARIABLES;}
 <INITIAL>parameters {BEGIN DYNARE_STATEMENT; return token::PARAMETERS;}
 <INITIAL>periods 	{BEGIN DYNARE_STATEMENT; return token::PERIODS;}
 <INITIAL>model_info {BEGIN DYNARE_STATEMENT; return token::MODEL_INFO;}
@@ -317,6 +318,7 @@ int sigma_e = 0;
 <DYNARE_STATEMENT>varexo { return token::VAREXO; }
 <DYNARE_STATEMENT>varexo_det { return token::VAREXO_DET; }
 <DYNARE_STATEMENT>parameters { return token::PARAMETERS; }
+<DYNARE_STATEMENT>predetermined_variables { return token::PREDETERMINED_VARIABLES; }
 
 <DYNARE_STATEMENT>bvar_prior_tau { return token::BVAR_PRIOR_TAU; }
 <DYNARE_STATEMENT>bvar_prior_decay { return token::BVAR_PRIOR_DECAY; }
diff --git a/ExprNode.cc b/ExprNode.cc
index 9e997ebf1be63d4059c292361a92f16694961252..7715ca5e4389312088d52634a8220561f4d040e6 100644
--- a/ExprNode.cc
+++ b/ExprNode.cc
@@ -318,6 +318,12 @@ NumConstNode::decreaseLeadsLags(int n) const
   return const_cast<NumConstNode *>(this);
 }
 
+NodeID
+NumConstNode::decreaseLeadsLagsPredeterminedVariables(const string pv_name) const
+{
+  return decreaseLeadsLags(1);
+}
+
 NodeID
 NumConstNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
 {
@@ -824,6 +830,15 @@ VariableNode::decreaseLeadsLags(int n) const
     }
 }
 
+NodeID
+VariableNode::decreaseLeadsLagsPredeterminedVariables(const string pv_name) const
+{
+  if(datatree.symbol_table.getName(symb_id).compare(pv_name)==0)
+    return decreaseLeadsLags(1);
+  else
+    return const_cast<VariableNode *>(this);
+}
+
 NodeID
 VariableNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
 {
@@ -1625,6 +1640,13 @@ UnaryOpNode::decreaseLeadsLags(int n) const
   return buildSimilarUnaryOpNode(argsubst, datatree);
 }
 
+NodeID
+UnaryOpNode::decreaseLeadsLagsPredeterminedVariables(const string pv_name) const
+{
+  NodeID argsubst = arg->decreaseLeadsLagsPredeterminedVariables(pv_name);
+  return buildSimilarUnaryOpNode(argsubst, datatree);
+}
+
 NodeID
 UnaryOpNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
 {
@@ -2603,6 +2625,14 @@ BinaryOpNode::decreaseLeadsLags(int n) const
   return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree);
 }
 
+NodeID
+BinaryOpNode::decreaseLeadsLagsPredeterminedVariables(const string pv_name) const
+{
+  NodeID arg1subst = arg1->decreaseLeadsLagsPredeterminedVariables(pv_name);
+  NodeID arg2subst = arg2->decreaseLeadsLagsPredeterminedVariables(pv_name);
+  return buildSimilarBinaryOpNode(arg1subst, arg2subst, datatree);
+}
+
 NodeID
 BinaryOpNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
 {
@@ -3066,6 +3096,15 @@ TrinaryOpNode::decreaseLeadsLags(int n) const
   return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree);
 }
 
+NodeID
+TrinaryOpNode::decreaseLeadsLagsPredeterminedVariables(const string pv_name) const
+{
+  NodeID arg1subst = arg1->decreaseLeadsLagsPredeterminedVariables(pv_name);
+  NodeID arg2subst = arg2->decreaseLeadsLagsPredeterminedVariables(pv_name);
+  NodeID arg3subst = arg3->decreaseLeadsLagsPredeterminedVariables(pv_name);
+  return buildSimilarTrinaryOpNode(arg1subst, arg2subst, arg3subst, datatree);
+}
+
 NodeID
 TrinaryOpNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
 {
@@ -3269,6 +3308,13 @@ UnknownFunctionNode::decreaseLeadsLags(int n) const
   exit(EXIT_FAILURE);
 }
 
+NodeID
+UnknownFunctionNode::decreaseLeadsLagsPredeterminedVariables(const string pv_name) const
+{
+  cerr << "UnknownFunctionNode::decreaseLeadsLagsPredeterminedVariables: not implemented!" << endl;
+  exit(EXIT_FAILURE);
+}
+
 NodeID
 UnknownFunctionNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const
 {
diff --git a/ExprNode.hh b/ExprNode.hh
index 9091d33aea3f4c57190bba1ce6b0a1c50668788b..5ba198f9a90e4ced761e17a38e42f3fb30a38fc1 100644
--- a/ExprNode.hh
+++ b/ExprNode.hh
@@ -303,6 +303,9 @@ public:
     \param[out] neweqs Equations to be added to the model to match the creation of auxiliary variables.
   */
   virtual NodeID substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const = 0;
+
+  virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const = 0;
+
 };
 
 //! Object used to compare two nodes (using their indexes)
@@ -342,6 +345,7 @@ public:
   virtual NodeID substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const;
+  virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const;
 };
 
 //! Symbol or variable node
@@ -380,6 +384,7 @@ public:
   virtual NodeID substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const;
+  virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const;
 };
 
 //! Unary operator node
@@ -428,6 +433,7 @@ public:
   virtual NodeID substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const;
+  virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const;
 };
 
 //! Binary operator node
@@ -479,6 +485,7 @@ public:
   virtual NodeID substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const;
+  virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const;
 };
 
 //! Trinary operator node
@@ -524,6 +531,7 @@ public:
   virtual NodeID substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const;
+  virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const;
 };
 
 //! Unknown function node
@@ -561,6 +569,7 @@ public:
   virtual NodeID substituteExoLead(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExoLag(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const;
   virtual NodeID substituteExpectation(subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs, bool partial_information_model) const;
+  virtual NodeID decreaseLeadsLagsPredeterminedVariables(const string pv_name) const;
 };
 
 #endif
diff --git a/ModFile.cc b/ModFile.cc
index c9ac4e540d4d3260ed6c3ead9e744eae24dd8c99..125f193a38bea183db5c3830eda45573b2c3cb15 100644
--- a/ModFile.cc
+++ b/ModFile.cc
@@ -134,6 +134,8 @@ ModFile::checkPass()
 void
 ModFile::transformPass()
 {
+  dynamic_model.transformPredeterminedVariables();
+
   if (mod_file_struct.stoch_simul_present
       || mod_file_struct.estimation_present
       || mod_file_struct.osr_present
@@ -172,9 +174,6 @@ ModFile::transformPass()
 void
 ModFile::computingPass(bool no_tmp_terms)
 {
-
-  //  expressions_tree.replace_oExpectation_in_datatree();
-
   // Mod file may have no equation (for example in a standalone BVAR estimation)
   bool dynamic_model_needed = mod_file_struct.simul_present || mod_file_struct.check_present || mod_file_struct.stoch_simul_present
     || mod_file_struct.estimation_present|| mod_file_struct.osr_present
diff --git a/ParsingDriver.cc b/ParsingDriver.cc
index 45d3b2ea752ff93a81a3fa0159fe2ef91e6189b5..0be4a6d5ab5f2db4a3a61da7fd9e11914c61af3d 100644
--- a/ParsingDriver.cc
+++ b/ParsingDriver.cc
@@ -144,6 +144,13 @@ ParsingDriver::declare_parameter(string *name, string *tex_name)
   declare_symbol(name, eParameter, tex_name);
 }
 
+void
+ParsingDriver::add_predetermined_variable(string *name)
+{
+  mod_file->dynamic_model.predetermined_variables_vec.push_back(*name);
+  delete name;
+}
+
 void
 ParsingDriver::add_equation_tags(string *key, string *value)
 {
diff --git a/ParsingDriver.hh b/ParsingDriver.hh
index e2e35a91d99883fb5e2f248b08ffd549cf1b0495..7ad71f27d52466415b4e56c180b74920e1edbe92 100644
--- a/ParsingDriver.hh
+++ b/ParsingDriver.hh
@@ -193,6 +193,8 @@ public:
   void declare_exogenous_det(string *name, string *tex_name = NULL);
   //! Declares a parameter
   void declare_parameter(string *name, string *tex_name = NULL);
+  //! Adds a predetermined_variable
+  void add_predetermined_variable(string *name);
   //! Declares and initializes a local parameter
   void declare_and_init_model_local_variable(string *name, NodeID rhs);
   //! Changes type of a symbol