diff --git a/ComputingTasks.cc b/ComputingTasks.cc
index 7a8fe14d07fb0850426dfca32a98e2de09b86c79..a4084a52d703ae450f7f2c337e7c955473c99532 100644
--- a/ComputingTasks.cc
+++ b/ComputingTasks.cc
@@ -236,6 +236,145 @@ VarModelStatement::createVarModelMFunction(ostream &output, const map<string, se
   output << ");" << endl;
 }
 
+VarRestrictionsStatement::VarRestrictionsStatement(const string &var_model_name_arg,
+                                                   const map<int, map<int, SymbolList> > &exclusion_restrictions_arg,
+                                                   const equation_restrictions_t &equation_restrictions_arg,
+                                                   const crossequation_restrictions_t &crossequation_restrictions_arg,
+                                                   const map<pair<int, int>, double> &covariance_number_restriction_arg,
+                                                   const map<pair<int, int>, pair<int, int> > &covariance_pair_restriction_arg) :
+  var_model_name(var_model_name_arg),
+  exclusion_restrictions(exclusion_restrictions_arg),
+  equation_restrictions(equation_restrictions_arg),
+  crossequation_restrictions(crossequation_restrictions_arg),
+  covariance_number_restriction(covariance_number_restriction_arg),
+  covariance_pair_restriction(covariance_pair_restriction_arg)
+{
+}
+
+void
+VarRestrictionsStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const
+{
+  output << "nvarrest = 1;" << endl
+         << "if isfield(M_.var, 'restrictions')" << endl
+         << "  nvarrest = length(M_.var.restrictions);" << endl
+         << "end" << endl
+         << "M_.var.restrictions{nvarrest}.name = '" << var_model_name << "';" << endl;
+
+  // Exclusion Restrictions
+  int idx = 1;
+  for (map<int, map<int, SymbolList> >::const_iterator it = exclusion_restrictions.begin();
+       it != exclusion_restrictions.end(); it++, idx++)
+    {
+      output << "M_.var.restrictions{nvarrest}.exclusion_restrictions{" << idx<< "}.lag = "
+             << it->first << ";" << endl
+             << "M_.var.restrictions{nvarrest}.exclusion_restrictions{" << it->first << "}.restrictions = [";
+      for (map<int, SymbolList>::const_iterator it1 = it->second.begin();
+           it1 != it->second.end(); it1++)
+        {
+          if (it1 != it->second.begin())
+            output << " ";
+          output << "{" << it1->first + 1 << " ";
+          it1->second.write(output);
+          output << "};";
+        }
+      output << "];" << endl;
+    }
+
+  // Equation Restrictions
+  idx = 1;
+  for (equation_restrictions_t::const_iterator it = equation_restrictions.begin();
+       it != equation_restrictions.end(); it++, idx++)
+    {
+      output << "M_.var.restrictions{nvarrest}.equation_restriction{" << idx << "}.eqsymb_id = "
+             << it->first + 1 << ";" << endl
+             << "M_.var.restrictions{nvarrest}.equation_restriction{" << idx << "}.val = "
+             << it->second.second << ";" << endl;
+
+      var_restriction_eq_crosseq_t ls = it->second.first.first;
+      output << "M_.var.restrictions{nvarrest}.equation_restriction{" << idx << "}.lssymb_id = "
+             << ls.first.first + 1 << ";" << endl
+             << "M_.var.restrictions{nvarrest}.equation_restriction{" << idx << "}.lslag = "
+             << ls.first.second.second << ";" << endl
+             << "M_.var.restrictions{nvarrest}.equation_restriction{" << idx << "}.lscoeff = ";
+      ls.second->writeOutput(output);
+      output << ";" << endl;
+
+      var_restriction_eq_crosseq_t rs = it->second.first.second;
+      if (rs.first.first >= 0)
+        {
+          output << "M_.var.restrictions{nvarrest}.equation_restriction{" << idx << "}.rssymb_id = "
+                 << rs.first.first + 1 << ";" << endl
+                 << "M_.var.restrictions{nvarrest}.equation_restriction{" << idx << "}.rslag = "
+                 << rs.first.second.second << ";" << endl
+                 << "M_.var.restrictions{nvarrest}.equation_restriction{" << idx << "}.rscoeff = ";
+          rs.second->writeOutput(output);
+          output << ";" << endl;
+        }
+    }
+
+  // Cross Equation Restrictions
+  idx = 1;
+  for (crossequation_restrictions_t::const_iterator it = crossequation_restrictions.begin();
+       it != crossequation_restrictions.end(); it++, idx++)
+    {
+      output << "M_.var.restrictions{nvarrest}.crossequation_restriction{" << idx << "}.eqsymb_id1 = "
+             << it->first.first + 1 << ";" << endl
+             << "M_.var.restrictions{nvarrest}.crossequation_restriction{" << idx << "}.eqsymb_id2 = "
+             << it->first.second + 1 << ";" << endl
+             << "M_.var.restrictions{nvarrest}.crossequation_restriction{" << idx << "}.val = "
+             << it->second.second << ";" << endl;
+
+      var_restriction_eq_crosseq_t ls = it->second.first.first;
+      output << "M_.var.restrictions{nvarrest}.crossequation_restriction{" << idx << "}.lssymb_id1 = "
+             << ls.first.first + 1 << ";" << endl
+             << "M_.var.restrictions{nvarrest}.crossequation_restriction{" << idx << "}.lssymb_id2 = "
+             << ls.first.second.first + 1 << ";" << endl
+             << "M_.var.restrictions{nvarrest}.crossequation_restriction{" << idx << "}.lslag = "
+             << ls.first.second.second << ";" << endl
+             << "M_.var.restrictions{nvarrest}.crossequation_restriction{" << idx << "}.lscoeff = ";
+      ls.second->writeOutput(output);
+      output << ";" << endl;
+
+      var_restriction_eq_crosseq_t rs = it->second.first.second;
+      if (rs.first.first >= 0)
+        {
+          output << "M_.var.restrictions{nvarrest}.crossequation_restriction{" << idx << "}.rssymb_id1 = "
+                 << rs.first.first + 1 << ";" << endl
+                 << "M_.var.restrictions{nvarrest}.crossequation_restriction{" << idx << "}.rssymb_id2 = "
+                 << rs.first.second.first + 1 << ";" << endl
+                 << "M_.var.restrictions{nvarrest}.crossequation_restriction{" << idx << "}.rslag = "
+                 << rs.first.second.second << ";" << endl
+                 << "M_.var.restrictions{nvarrest}.crossequation_restriction{" << idx << "}.rscoeff = ";
+          rs.second->writeOutput(output);
+          output << ";" << endl;
+        }
+    }
+
+  // Covariance Const Restrictions
+  idx = 1;
+  for (map<pair<int, int>, double>::const_iterator it = covariance_number_restriction.begin();
+       it != covariance_number_restriction.end(); it++, idx++)
+    output << "M_.var.restrictions{nvarrest}.covariance_const_restriction{" << idx << "}.symb_id1 = "
+           << it->first.first << ";" << endl
+           << "M_.var.restrictions{nvarrest}.covariance_const_restriction{" << idx << "}.symb_id2 = "
+           << it->first.second << ";" << endl
+           << "M_.var.restrictions{nvarrest}.covariance_const_restriction{" << idx << "}.val = "
+           << it->second << ";" << endl;
+
+  // Covariance Pair Restrictions
+  idx = 1;
+  for (map<pair<int, int>, pair<int, int> >::const_iterator it = covariance_pair_restriction.begin();
+       it != covariance_pair_restriction.end(); it++, idx++)
+    output << "M_.var.restrictions{nvarrest}.covariance_pair_restriction{" << idx << "}.symb_id11 = "
+           << it->first.first << ";" << endl
+           << "M_.var.restrictions{nvarrest}.covariance_pair_restriction{" << idx << "}.symb_id12 = "
+           << it->first.second << ";" << endl
+           << "M_.var.restrictions{nvarrest}.covariance_pair_restriction{" << idx << "}.symb_id21 = "
+           << it->second.first << ";" << endl
+           << "M_.var.restrictions{nvarrest}.covariance_pair_restriction{" << idx << "}.symb_id22 = "
+           << it->second.second << ";" << endl;
+}
+
 StochSimulStatement::StochSimulStatement(const SymbolList &symbol_list_arg,
                                          const OptionsList &options_list_arg) :
   symbol_list(symbol_list_arg),
diff --git a/ComputingTasks.hh b/ComputingTasks.hh
index 1cbbafaa6b2351abfc24638edcddeb1bd49b84e1..5175d7cd5d8e2dd3cd710ec66b9b1973575707cd 100644
--- a/ComputingTasks.hh
+++ b/ComputingTasks.hh
@@ -126,6 +126,28 @@ public:
   void createVarModelMFunction(ostream &output, const map<string, set<int> > &var_expectation_functions_to_write) const;
 };
 
+class VarRestrictionsStatement : public Statement
+{
+private:
+  typedef pair<pair<int, pair<int, int> >, expr_t> var_restriction_eq_crosseq_t;
+  const string &var_model_name;
+  const map<int, map<int, SymbolList> > exclusion_restrictions;
+  typedef map<int, pair<pair<var_restriction_eq_crosseq_t, var_restriction_eq_crosseq_t>, double> > equation_restrictions_t;
+  const equation_restrictions_t equation_restrictions;
+  typedef map<pair<int, int>, pair<pair<var_restriction_eq_crosseq_t, var_restriction_eq_crosseq_t>, double> > crossequation_restrictions_t;
+  const crossequation_restrictions_t crossequation_restrictions;
+  const map<pair<int, int>, double> covariance_number_restriction;
+  const map<pair<int, int>, pair<int, int> > covariance_pair_restriction;
+public:
+  VarRestrictionsStatement(const string &var_model_name_arg,
+                           const map<int, map<int, SymbolList> > &exclusion_restrictions_arg,
+                           const equation_restrictions_t &equation_restrictions_arg,
+                           const crossequation_restrictions_t &crossequation_restrictions_arg,
+                           const map<pair<int, int>, double> &covariance_number_restriction_arg,
+                           const map<pair<int, int>, pair<int, int> > &covariance_pair_restriction_arg);
+  virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+};
+
 class ForecastStatement : public Statement
 {
 private:
diff --git a/DynareBison.yy b/DynareBison.yy
index 6eb1207f14b4d5dfff2ff5c583096f2c606c6ac5..e8c3d87155b2ac77e12d8b489465b29ddeee961b 100644
--- a/DynareBison.yy
+++ b/DynareBison.yy
@@ -130,7 +130,7 @@ class ParsingDriver;
 %token <string_val> TEX_NAME
 %token UNIFORM_PDF UNIT_ROOT_VARS USE_DLL USEAUTOCORR GSA_SAMPLE_FILE USE_UNIVARIATE_FILTERS_IF_SINGULARITY_IS_DETECTED
 %token VALUES VAR VAREXO VAREXO_DET VAROBS VAREXOBS PREDETERMINED_VARIABLES VAR_EXPECTATION PLOT_SHOCK_DECOMPOSITION
-%token WRITE_LATEX_DYNAMIC_MODEL WRITE_LATEX_STATIC_MODEL WRITE_LATEX_ORIGINAL_MODEL
+%token WRITE_LATEX_DYNAMIC_MODEL WRITE_LATEX_STATIC_MODEL WRITE_LATEX_ORIGINAL_MODEL CROSSEQUATIONS COVARIANCE
 %token XLS_SHEET XLS_RANGE LMMCP OCCBIN BANDPASS_FILTER COLORMAP VAR_MODEL QOQ YOY AOA
 %left COMMA
 %left EQUAL_EQUAL EXCLAMATION_EQUAL
@@ -180,7 +180,7 @@ class ParsingDriver;
 %type <node_val> expression expression_or_empty
 %type <node_val> equation hand_side
 %type <string_val> non_negative_number signed_number signed_integer date_str
-%type <string_val> filename symbol vec_of_vec_value vec_value_list date_expr
+%type <string_val> filename symbol vec_of_vec_value vec_value_list date_expr number
 %type <string_val> vec_value_1 vec_value signed_inf signed_number_w_inf
 %type <string_val> range vec_value_w_inf vec_value_1_w_inf
 %type <string_val> integer_range signed_integer_range sub_sampling_options list_sub_sampling_option
@@ -225,6 +225,7 @@ statement : parameters
           | set_time
           | data
           | var_model
+          | restrictions
           | prior
           | prior_eq
           | subsamples
@@ -371,6 +372,85 @@ var_model_options : o_var_name
                   | o_var_method
                   ;
 
+restrictions : RESTRICTIONS '(' symbol ')' ';' { driver.begin_VAR_restrictions(); }
+               restrictions_list END ';' { driver.end_VAR_restrictions($3); }
+             ;
+
+restrictions_list : restrictions_list restriction
+                  | restriction
+                  ;
+
+restriction : EXCLUSION LAG INT_NUMBER ';' restriction_exclusion_equation_list
+              { driver.add_VAR_exclusion_restriction($3); }
+            | RESTRICTION EQUATION '(' symbol ')' restriction_equation_equality ';'
+              { driver.add_VAR_restriction_equation_or_crossequation_final($4, NULL); }
+            | RESTRICTION CROSSEQUATIONS '(' symbol COMMA symbol ')' restriction_crossequation_equality ';'
+              { driver.add_VAR_restriction_equation_or_crossequation_final($4, $6); }
+            | RESTRICTION COVARIANCE '(' symbol COMMA symbol ')' EQUAL number ';'
+              { driver.add_VAR_covariance_number_restriction($4, $6, $9); }
+            | RESTRICTION COVARIANCE '(' symbol COMMA symbol ')' EQUAL '(' symbol COMMA symbol ')' ';'
+              { driver.add_VAR_covariance_pair_restriction($4, $6, $10, $12); }
+            ;
+
+restriction_equation_equality : restriction_equation_equality_side PLUS restriction_equation_equality_side EQUAL number
+                                { driver.add_VAR_restriction_equation_or_crossequation($5); }
+                              | restriction_equation_equality_side MINUS restriction_equation_equality_side EQUAL number
+                                {
+                                  driver.multiply_arg2_by_neg_one();
+                                  driver.add_VAR_restriction_equation_or_crossequation($5);
+                                }
+                              | restriction_equation_equality_side EQUAL number
+                                { driver.add_VAR_restriction_equation_or_crossequation($3); }
+                              ;
+
+restriction_equation_equality_side : coeff_def TIMES expression
+                                     { driver.add_VAR_restriction_eq_or_crosseq($3); }
+                                   | coeff_def DIVIDE expression
+                                     {
+                                       string *onestr = new string("1");
+                                       expr_t one = driver.add_non_negative_constant(onestr);
+                                       driver.add_VAR_restriction_eq_or_crosseq(driver.add_divide(one, $3));
+                                     }
+                                   ;
+
+coeff_def : COEFF '(' symbol COMMA INT_NUMBER ')'
+            { driver.add_VAR_restriction_coeff($3, NULL, $5); }
+          ;
+
+
+restriction_crossequation_equality : restriction_crossequation_equality_side PLUS restriction_crossequation_equality_side EQUAL number
+                                     { driver.add_VAR_restriction_equation_or_crossequation($5); }
+                                   | restriction_crossequation_equality_side MINUS restriction_crossequation_equality_side EQUAL number
+                                     {
+                                       driver.multiply_arg2_by_neg_one();
+                                       driver.add_VAR_restriction_equation_or_crossequation($5);
+                                     }
+                                   | restriction_crossequation_equality_side EQUAL number
+                                     { driver.add_VAR_restriction_equation_or_crossequation($3); }
+                                   ;
+
+restriction_crossequation_equality_side : coeff_def1 TIMES expression
+                                          { driver.add_VAR_restriction_eq_or_crosseq($3); }
+                                        | coeff_def1 DIVIDE expression
+                                          {
+                                            string *onestr = new string("1");
+                                            expr_t one = driver.add_non_negative_constant(onestr);
+                                            driver.add_VAR_restriction_eq_or_crosseq(driver.add_divide(one, $3));
+                                          }
+                                        ;
+
+coeff_def1 : COEFF '(' symbol COMMA symbol COMMA INT_NUMBER ')'
+             { driver.add_VAR_restriction_coeff($3, $5, $7); }
+           ;
+
+restriction_exclusion_equation_list : restriction_exclusion_equation_list restriction_exclusion_equation
+                                    | restriction_exclusion_equation
+                                    ;
+
+restriction_exclusion_equation : EQUATION '(' symbol ')' symbol_list ';'
+                                 { driver.add_VAR_restriction_exclusion_equation($3); }
+                               ;
+
 nonstationary_var_list : nonstationary_var_list symbol
                          { driver.declare_nonstationary_var($2); }
                        | nonstationary_var_list COMMA symbol
@@ -3572,6 +3652,10 @@ symbol : NAME
        | DR
        | PRIOR
        ;
+
+number : INT_NUMBER
+       | FLOAT_NUMBER
+       ;
 %%
 
 void
diff --git a/DynareFlex.ll b/DynareFlex.ll
index 88de8f3571d2cc28595a8533153c809e9737aa77..46b24dea9729528541e41ef2789ca7a6cf0e177c 100644
--- a/DynareFlex.ll
+++ b/DynareFlex.ll
@@ -208,6 +208,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
 <INITIAL>moment_calibration {BEGIN DYNARE_BLOCK; return token::MOMENT_CALIBRATION;}
 <INITIAL>irf_calibration {BEGIN DYNARE_BLOCK; return token::IRF_CALIBRATION;}
 <INITIAL>ramsey_constraints {BEGIN DYNARE_BLOCK; return token::RAMSEY_CONSTRAINTS;}
+<INITIAL>restrictions {BEGIN DYNARE_BLOCK; return token::RESTRICTIONS;}
 
  /* For the semicolon after an "end" keyword */
 <INITIAL>; {return Dynare::parser::token_type (yytext[0]);}
@@ -369,6 +370,8 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2
 <DYNARE_STATEMENT>restriction_fname {return token::RESTRICTION_FNAME;}
 <DYNARE_STATEMENT>nlags {return token::NLAGS;}
 <DYNARE_STATEMENT>restrictions {return token::RESTRICTIONS;}
+<DYNARE_BLOCK>crossequations {return token::CROSSEQUATIONS;}
+<DYNARE_BLOCK>covariance {return token::COVARIANCE;}
 <DYNARE_STATEMENT>cross_restrictions {return token::CROSS_RESTRICTIONS;}
 <DYNARE_STATEMENT>contemp_reduced_form {return token::CONTEMP_REDUCED_FORM;}
 <DYNARE_STATEMENT>real_pseudo_forecast {return token::REAL_PSEUDO_FORECAST;}
diff --git a/ParsingDriver.cc b/ParsingDriver.cc
index 6665bb358468b2516693ca9fa40ed718e2deaf96..e3e7e4ba94d5f446db3d2439e5f27957674c3983 100644
--- a/ParsingDriver.cc
+++ b/ParsingDriver.cc
@@ -481,6 +481,149 @@ ParsingDriver::end_nonstationary_var(bool log_deflator, expr_t deflator)
   reset_data_tree();
 }
 
+void
+ParsingDriver::begin_VAR_restrictions()
+{
+  clear_VAR_storage();
+}
+
+void
+ParsingDriver::end_VAR_restrictions(string *var_model_name)
+{
+  mod_file->addStatement(new VarRestrictionsStatement(*var_model_name,
+                                                      exclusion_restrictions,
+                                                      equation_restrictions,
+                                                      crossequation_restrictions,
+                                                      covariance_number_restriction,
+                                                      covariance_pair_restriction));
+  clear_VAR_storage();
+}
+
+void
+ParsingDriver::clear_VAR_storage()
+{
+  exclusion_restriction.clear();
+  exclusion_restrictions.clear();
+  symbol_list.clear();
+  var_restriction_eq_or_crosseq.clear();
+  equation_restrictions.clear();
+  crossequation_restrictions.clear();
+  covariance_number_restriction.clear();
+  covariance_pair_restriction.clear();
+}
+
+void
+ParsingDriver::add_VAR_exclusion_restriction(string *lagstr)
+{
+  int lag = atoi(lagstr->c_str());
+  map<int, map<int, SymbolList> >::iterator it = exclusion_restrictions.find(lag);
+  if (it == exclusion_restrictions.end())
+    exclusion_restrictions[lag] = exclusion_restriction;
+  else
+    for (map<int, SymbolList>::const_iterator it1 = exclusion_restriction.begin();
+         it1 != exclusion_restriction.end(); it1++)
+      it->second[it1->first] = it1->second;
+
+  exclusion_restriction.clear();
+  delete lagstr;
+}
+
+void
+ParsingDriver::add_VAR_restriction_coeff(string *name1, string *name2, string *lagstr)
+{
+  int symb_id1 = mod_file->symbol_table.getID(*name1);
+  int symb_id2 = name2 == NULL ? -1 : mod_file->symbol_table.getID(*name2);
+  int lag = atoi(lagstr->c_str());
+
+  var_restriction_coeff = make_pair(symb_id1, make_pair(symb_id2, lag));
+
+  delete name1;
+  if (name2 != NULL)
+    delete name2;
+  delete lagstr;
+}
+
+void
+ParsingDriver::add_VAR_restriction_eq_or_crosseq(expr_t expr)
+{
+  var_restriction_eq_or_crosseq.push_back(make_pair(var_restriction_coeff, expr));
+}
+
+void
+ParsingDriver::add_VAR_restriction_equation_or_crossequation(string *numberstr)
+{
+  assert(var_restriction_eq_or_crosseq.size() > 0 && var_restriction_eq_or_crosseq.size() < 3);
+  double number = atof(numberstr->c_str());
+  if (var_restriction_eq_or_crosseq.size() == 1)
+    var_restriction_equation_or_crossequation = make_pair(make_pair(var_restriction_eq_or_crosseq[0],
+                                                                    make_pair(make_pair(-1, make_pair(-1, -1)), (expr_t)NULL)),
+                                                          number);
+  else
+    var_restriction_equation_or_crossequation = make_pair(make_pair(var_restriction_eq_or_crosseq[0],
+                                                                    var_restriction_eq_or_crosseq[1]),
+                                                          number);
+  var_restriction_eq_or_crosseq.clear();
+}
+
+void
+ParsingDriver::multiply_arg2_by_neg_one()
+{
+  assert(var_restriction_eq_or_crosseq.size() == 2);
+  expr_t exprtm1 = add_times(var_restriction_eq_or_crosseq[1].second,
+                             add_uminus(add_non_negative_constant(new string("-1"))));
+  var_restriction_eq_or_crosseq[1] = make_pair(var_restriction_eq_or_crosseq[1].first, exprtm1);
+}
+
+void
+ParsingDriver::add_VAR_restriction_equation_or_crossequation_final(string *name1, string *name2)
+{
+  int symb_id1 = mod_file->symbol_table.getID(*name1);
+  if (name2 == NULL)
+    equation_restrictions[symb_id1] = var_restriction_equation_or_crossequation;
+  else
+    {
+      int symb_id2 = name2 == NULL ? -1 : mod_file->symbol_table.getID(*name2);
+      crossequation_restrictions[make_pair(symb_id1, symb_id2)] = var_restriction_equation_or_crossequation;
+      delete name2;
+    }
+  delete name1;
+}
+
+void
+ParsingDriver::add_VAR_restriction_exclusion_equation(string *name)
+{
+  int symb_id = mod_file->symbol_table.getID(*name);
+  exclusion_restriction[symb_id] = symbol_list;
+  symbol_list.clear();
+  delete name;
+}
+
+void
+ParsingDriver::add_VAR_covariance_number_restriction(string *name1, string *name2, string *valuestr)
+{
+  int symb_id1 = mod_file->symbol_table.getID(*name1);
+  int symb_id2 = mod_file->symbol_table.getID(*name2);
+  double value = atof(valuestr->c_str());
+  covariance_number_restriction[make_pair(symb_id1, symb_id2)] = value;
+  delete name1;
+  delete name2;
+  delete valuestr;
+}
+
+void
+ParsingDriver::add_VAR_covariance_pair_restriction(string *name11, string *name12, string *name21, string *name22)
+{
+  int symb_id11 = mod_file->symbol_table.getID(*name11);
+  int symb_id12 = mod_file->symbol_table.getID(*name12);
+  int symb_id21 = mod_file->symbol_table.getID(*name21);
+  int symb_id22 = mod_file->symbol_table.getID(*name22);
+  covariance_pair_restriction[make_pair(symb_id11, symb_id12)] = make_pair(symb_id21, symb_id22);
+  delete name11;
+  delete name12;
+  delete name21;
+  delete name22;
+}
+
 void
 ParsingDriver::periods(string *periods)
 {
diff --git a/ParsingDriver.hh b/ParsingDriver.hh
index 1d090da4797306be33dab9c5ed7e7e57f5b52e4f..af6a6865606db21846785ebde1f541af2fd23721 100644
--- a/ParsingDriver.hh
+++ b/ParsingDriver.hh
@@ -238,6 +238,8 @@ private:
 
   ostringstream model_errors;
 
+  //! Used by VAR restrictions
+  void clear_VAR_storage();
 public:
   ParsingDriver(WarningConsolidation &warnings_arg, bool nostrict_arg) : warnings(warnings_arg), nostrict(nostrict_arg), model_error_encountered(false) { };
 
@@ -260,6 +262,21 @@ public:
   //! Temporary storage for the prior shape
   PriorDistributions prior_shape;
 
+  //! VAR restrictions
+  //! > exclusion restrictions
+  map<int, SymbolList> exclusion_restriction;
+  map<int, map<int, SymbolList> > exclusion_restrictions;
+  //! > equation and crossequation restrictions
+  pair<int, pair<int, int> > var_restriction_coeff;
+  typedef pair<pair<int, pair<int, int> >, expr_t> var_restriction_eq_crosseq_t;
+  vector<var_restriction_eq_crosseq_t> var_restriction_eq_or_crosseq;
+  pair<pair<var_restriction_eq_crosseq_t, var_restriction_eq_crosseq_t>, double> var_restriction_equation_or_crossequation;
+  map<int, pair<pair<var_restriction_eq_crosseq_t, var_restriction_eq_crosseq_t>, double> > equation_restrictions;
+  map<pair<int, int>, pair<pair<var_restriction_eq_crosseq_t, var_restriction_eq_crosseq_t>, double> > crossequation_restrictions;
+  //! > covariance restrictions
+  map<pair<int, int>, double> covariance_number_restriction;
+  map<pair<int, int>, pair<int, int> > covariance_pair_restriction;
+
   //! Error handler with explicit location
   void error(const Dynare::parser::location_type &l, const string &m) __attribute__ ((noreturn));
   //! Error handler using saved location
@@ -763,6 +780,18 @@ public:
   void perfect_foresight_setup();
   void perfect_foresight_solver();
   void prior_posterior_function(bool prior_func);
+  //! VAR Restrictions
+  void begin_VAR_restrictions();
+  void end_VAR_restrictions(string *var_model_name);
+  void add_VAR_exclusion_restriction(string *lagstr);
+  void add_VAR_restriction_exclusion_equation(string *name);
+  void add_VAR_restriction_coeff(string *name1, string *name2, string *lagstr);
+  void add_VAR_restriction_eq_or_crosseq(expr_t expr);
+  void add_VAR_restriction_equation_or_crossequation(string *numberstr);
+  void multiply_arg2_by_neg_one();
+  void add_VAR_restriction_equation_or_crossequation_final(string *name1, string *name2);
+  void add_VAR_covariance_number_restriction(string *name1, string *name2, string *valuestr);
+  void add_VAR_covariance_pair_restriction(string *name11, string *name12, string *name21, string *name22);
 };
 
 #endif // ! PARSING_DRIVER_HH
diff --git a/SymbolList.cc b/SymbolList.cc
index dca1410ece165ec8bd8a846d6e0763a6b2e837a1..3d0e09183e594070d1cfd810b5a5d7ffdcbc66db 100644
--- a/SymbolList.cc
+++ b/SymbolList.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003-2014 Dynare Team
+ * Copyright (C) 2003-2017 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -28,7 +28,15 @@ SymbolList::addSymbol(const string &symbol)
 void
 SymbolList::writeOutput(const string &varname, ostream &output) const
 {
-  output << varname << " = char(";
+  output << varname << " = ";
+  write(output);
+  output << ";" << endl;
+}
+
+void
+SymbolList::write(ostream &output) const
+{
+  output << " char(";
   for (vector<string>::const_iterator it = symbols.begin();
        it != symbols.end(); ++it)
     {
@@ -36,7 +44,7 @@ SymbolList::writeOutput(const string &varname, ostream &output) const
         output << ",";
       output << "'" << *it << "'";
     }
-  output << ");" << endl;
+  output << ")";
 }
 
 void
diff --git a/SymbolList.hh b/SymbolList.hh
index 82f0b79401ced40b14b26ea0fe2a240fc784567a..4aeb1af68b9f1a874f6b98073abc0336b6c6a460 100644
--- a/SymbolList.hh
+++ b/SymbolList.hh
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003-2011 Dynare Team
+ * Copyright (C) 2003-2017 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -39,6 +39,8 @@ public:
   //! Output content in Matlab format
   /*! Creates a string array for Matlab, stored in variable "varname" */
   void writeOutput(const string &varname, ostream &output) const;
+  //! Output content in Matlab format without preceding varname of writeOutput
+  void write(ostream &output) const;
   //! Clears all content
   void clear();
   //! Get a copy of the string vector