diff --git a/preprocessor/ComputingTasks.cc b/preprocessor/ComputingTasks.cc
index f802f917d00816d443beb2b1d7b5c588ed9e510b..7bb76ad0a937ee55da3c2693681f247f1eba0904 100644
--- a/preprocessor/ComputingTasks.cc
+++ b/preprocessor/ComputingTasks.cc
@@ -1025,3 +1025,119 @@ PlotConditionalForecastStatement::writeOutput(ostream &output, const string &bas
   else
     output << "plot_icforecast(var_list_, " << periods << ");" << endl;
 }
+
+SvarIdentificationStatement::SvarIdentificationStatement(const svar_identification_exclusion_type &exclusion_arg,
+                                                         const bool &upper_cholesky_present_arg,
+                                                         const bool &lower_cholesky_present_arg,
+                                                         const SymbolTable &symbol_table_arg) :
+  exclusion(exclusion_arg),
+  upper_cholesky_present(upper_cholesky_present_arg),
+  lower_cholesky_present(lower_cholesky_present_arg),
+  symbol_table(symbol_table_arg)
+{
+}
+
+int
+SvarIdentificationStatement::getMaxLag() const
+{
+  int max_lag = 0;
+  for (svar_identification_exclusion_type::const_iterator it = exclusion.begin(); it != exclusion.end(); it++)
+    if (it->first.first > max_lag)
+      max_lag = it->first.first;
+
+  return max_lag;
+}
+
+void
+SvarIdentificationStatement::checkPass(ModFileStructure &mod_file_struct)
+{
+  if (!mod_file_struct.svar_identification_present)
+    mod_file_struct.svar_identification_present = true;
+  else
+    {
+      cerr << "ERROR: You may only have one svar_identification block in your .mod file." << endl;
+      exit(EXIT_FAILURE);
+    }
+}
+
+void
+SvarIdentificationStatement::writeOutput(ostream &output, const string &basename) const
+{
+  if (upper_cholesky_present && lower_cholesky_present)
+    {
+      cerr << "SvarIdentificationStatement::writeOutput() Should not arrive here (1). Please report this to the Dynare Team." << endl;
+      exit(EXIT_FAILURE);
+    }
+
+  output << "%" << endl
+         << "% SVAR IDENTIFICATION" << endl
+         << "%" << endl;
+
+  if (upper_cholesky_present)
+    output << "options_.ms.upper_cholesky=1;" << endl;
+
+  if (lower_cholesky_present)
+    output << "options_.ms.lower_cholesky=1;" << endl;
+
+  if (!upper_cholesky_present && !lower_cholesky_present)
+    {
+      int n = symbol_table.endo_nbr();
+      int m = symbol_table.exo_nbr();
+      int r = getMaxLag();
+      int k = r*n+m;
+
+      if (k<1)
+        {
+          cerr << "ERROR: lag = " << r
+               << ", number of endogenous variables = " << n
+               << ", number of exogenous variables = " << m
+               << ". If this is not a logical error in the specification"
+               << " of the .mod file, please report it to the Dynare Team." << endl;
+          exit(EXIT_FAILURE);
+        }
+      if (n<1)
+        {
+          cerr << "ERROR: Number of endogenous variables = " << n << "< 1. If this is not a logical "
+               << "error in the specification of the .mod file, please report it to the Dynare Team." << endl;
+          exit(EXIT_FAILURE);
+        }
+      output << "options_.ms.Qi = zeros(" << n << ", " << n << ", " << n << ");" << endl;
+      output << "options_.ms.Ri = zeros(" << k << ", " << k << ", " << n << ");" << endl;
+
+      for (svar_identification_exclusion_type::const_iterator it = exclusion.begin(); it != exclusion.end(); it++)
+        {
+          for (unsigned int h = 0; h < it->second.size(); h++)
+            {
+              int j = symbol_table.getTypeSpecificID(it->second.at(h)) + 1;
+              int i = it->first.second;
+              if (j < 1 || j > n || (int)h+1 > n || i < 1)
+                {
+                  cerr << "SvarIdentificationStatement::writeOutput() Should not arrive here (2). Please report this to the Dynare Team." << endl;
+                  exit(EXIT_FAILURE);
+                }
+              if (i > n)
+                {
+                  cerr << "ERROR: equation number " << i << " is greater than the number of endogenous variables, " << n << "." << endl;
+                  exit(EXIT_FAILURE);
+                }
+
+              if (it->first.first == 0)
+                output << "options_.ms.Qi(" << h+1 << ", " << j << ", "<< i << ");" << endl;
+              else if (it->first.first > 0)
+                {
+                  if ((it->first.first-1)*n+j > k)
+                    {
+                      cerr << "ERROR: lag =" << it->first.first << ", num endog vars = " << n << "current endog var index = " << j << ". Index "
+                           << "out of bounds. If the above does not represent a logical error, please report this to the Dyanre Team." << endl;
+                    }
+                  output << "options_.ms.Ri(" << h+1 << ", " << (it->first.first-1)*n+j << ", "<< i << ");" << endl;
+                }
+              else
+                {
+                  cerr << "SvarIdentificationStatement::writeOutput() Should not arrive here (3). Please report this to the Dynare Team." << endl;
+                  exit(EXIT_FAILURE);
+                }
+            }
+        }
+    }
+}
diff --git a/preprocessor/ComputingTasks.hh b/preprocessor/ComputingTasks.hh
index 8529acd2ab6e0cc6674657c0fe8c860e91ea2427..afd27fa43dbb4a2493794dbb3b4dfc4d7d0f37f9 100644
--- a/preprocessor/ComputingTasks.hh
+++ b/preprocessor/ComputingTasks.hh
@@ -489,4 +489,23 @@ public:
   virtual void writeOutput(ostream &output, const string &basename) const;
 };
 
+class SvarIdentificationStatement : public Statement
+{
+public:
+  typedef map<pair<int, int>, vector<string> > svar_identification_exclusion_type;
+private:
+  const svar_identification_exclusion_type exclusion;
+  const bool upper_cholesky_present;
+  const bool lower_cholesky_present;
+  const SymbolTable &symbol_table;
+  int getMaxLag() const;
+public:
+  SvarIdentificationStatement(const svar_identification_exclusion_type &exclusion_arg,
+                              const bool &upper_cholesky_present_arg,
+                              const bool &lower_cholesky_present_arg,
+                              const SymbolTable &symbol_table_arg);
+  virtual void checkPass(ModFileStructure &mod_file_struct);
+  virtual void writeOutput(ostream &output, const string &basename) const;
+};
+
 #endif
diff --git a/preprocessor/DynareBison.yy b/preprocessor/DynareBison.yy
index 61ca875f42f8b64596dcbaf59413c352af85f940..36ec425c7769db653590285b4983fde3339c0c9e 100644
--- a/preprocessor/DynareBison.yy
+++ b/preprocessor/DynareBison.yy
@@ -598,15 +598,14 @@ det_shock_elem : VAR symbol ';' PERIODS period_list ';' VALUES value_list ';'
                ;
 
 svar_identification : SVAR_IDENTIFICATION ';' svar_identification_list END
-                      { ;}
+                      { driver.end_svar_identification(); }
                     ;
 
 svar_identification_list : svar_exclusion_list
-                           { ;}
                          | UPPER_CHOLESKY ';'
-                           { ;}
+                           { driver.add_upper_cholesky(); }
                          | LOWER_CHOLESKY ';'
-                           { ;}
+                           { driver.add_lower_cholesky(); }
                          ;
 
 svar_exclusion_list : svar_exclusion_list svar_exclusion_elem
@@ -614,19 +613,19 @@ svar_exclusion_list : svar_exclusion_list svar_exclusion_elem
                     ;
 
 svar_exclusion_elem : EXCLUSION LAG INT_NUMBER ';' svar_equation_list
-                      { ;}
+                      { driver.combine_lag_and_restriction($3); }
                     ;
 
 svar_equation_list : svar_equation_list EQUATION INT_NUMBER COMMA svar_var_list ';'
-                     { ;}
+                     { driver.add_restriction_in_equation($3); }
                    | EQUATION INT_NUMBER COMMA svar_var_list ';'
-                     { ;}
+                     { driver.add_restriction_in_equation($2); }
                    ;
 
 svar_var_list : svar_var_list COMMA symbol
-                { ;}
+                { driver.add_in_svar_restriction_symbols($3); }
               | symbol
-                { ;}
+                { driver.add_in_svar_restriction_symbols($1); }
               ;
 
 markov_switching : MARKOV_SWITCHING '(' ms_options_list ')' ';'
diff --git a/preprocessor/ParsingDriver.cc b/preprocessor/ParsingDriver.cc
index 890f5741492bad899aae50efacdf609516f8df46..ebed17e6fe3ee8355981ac0d7c40ac0c4f3a7f16 100644
--- a/preprocessor/ParsingDriver.cc
+++ b/preprocessor/ParsingDriver.cc
@@ -584,6 +584,82 @@ ParsingDriver::add_value(string *p1)
   det_shocks_values.push_back(add_constant(p1));
 }
 
+void
+ParsingDriver::end_svar_identification()
+{
+  mod_file->addStatement(new SvarIdentificationStatement(svar_ident_exclusion_values,
+                                                         svar_upper_cholesky,
+                                                         svar_lower_cholesky,
+                                                         mod_file->symbol_table));
+  svar_upper_cholesky = false;
+  svar_lower_cholesky = false;
+  svar_restriction_symbols.clear();
+  svar_equation_restrictions.clear();
+  svar_ident_exclusion_values.clear();
+}
+
+void
+ParsingDriver::combine_lag_and_restriction(string *lag)
+{
+  int current_lag = atoi(lag->c_str());
+
+  for (SvarIdentificationStatement::svar_identification_exclusion_type::const_iterator it = svar_ident_exclusion_values.begin();
+       it != svar_ident_exclusion_values.end(); it++)
+    if (it->first.first == current_lag)
+      error("lag " + *lag + " used more than once.");
+
+  for(map<int, vector<string> >::const_iterator it = svar_equation_restrictions.begin();
+      it != svar_equation_restrictions.end(); it++ )
+    svar_ident_exclusion_values[make_pair(current_lag, it->first)] = it->second;
+
+  svar_upper_cholesky = false;
+  svar_lower_cholesky = false;
+  svar_equation_restrictions.clear();
+  delete lag;
+}
+
+void
+ParsingDriver::add_restriction_in_equation(string *equation)
+{
+  int eqn = atoi(equation->c_str());
+  if (eqn < 1)
+    error("equation numbers must be greater than or equal to 1.");
+
+  if (svar_equation_restrictions.count(eqn) > 0)
+    error("equation number " + *equation + " referenced more than once under a single lag.");
+
+  svar_equation_restrictions[eqn] = svar_restriction_symbols;
+
+  svar_restriction_symbols.clear();
+  delete equation;
+}
+
+void
+ParsingDriver::add_in_svar_restriction_symbols(string *tmp_var)
+{
+  check_symbol_existence(*tmp_var);
+  for (unsigned int i=0; i<svar_restriction_symbols.size(); i++)
+    if (*tmp_var==svar_restriction_symbols.at(i))
+      error(*tmp_var + " restriction added twice.");
+
+  svar_restriction_symbols.push_back(*tmp_var);
+  delete tmp_var;
+}
+
+void
+ParsingDriver::add_upper_cholesky()
+{
+  svar_upper_cholesky = true;
+  svar_lower_cholesky = false;
+}
+
+void
+ParsingDriver::add_lower_cholesky()
+{
+  svar_upper_cholesky = false;
+  svar_lower_cholesky = true;
+}
+
 void
 ParsingDriver::do_sigma_e()
 {
diff --git a/preprocessor/ParsingDriver.hh b/preprocessor/ParsingDriver.hh
index 7ad71f27d52466415b4e56c180b74920e1edbe92..4dc42a9449fb6d54b9991ed2da327637e089badd 100644
--- a/preprocessor/ParsingDriver.hh
+++ b/preprocessor/ParsingDriver.hh
@@ -143,6 +143,12 @@ private:
   HistValStatement::hist_values_type hist_values;
   //! Temporary storage for homotopy_setup blocks
   HomotopyStatement::homotopy_values_type homotopy_values;
+  //! Temporary storage for svar_identification blocks
+  SvarIdentificationStatement::svar_identification_exclusion_type svar_ident_exclusion_values;
+  map<int, vector<string> > svar_equation_restrictions;
+  vector<string> svar_restriction_symbols;
+  bool svar_upper_cholesky;
+  bool svar_lower_cholesky;
 
   //! Temporary storage for argument list of unknown function
   vector<NodeID> unknown_function_args;
@@ -318,6 +324,13 @@ public:
   void optim_options_num(string *name, string *value);
   //! Prints varops instructions
   void set_varobs();
+  //! Svar_Identification Statement
+  void end_svar_identification();
+  void combine_lag_and_restriction(string *lag);
+  void add_restriction_in_equation(string *equation);
+  void add_in_svar_restriction_symbols(string *name);
+  void add_upper_cholesky();
+  void add_lower_cholesky();
   //! Forecast Statement
   void forecast();
   void set_trends();
diff --git a/preprocessor/Statement.cc b/preprocessor/Statement.cc
index 786fbc4271451c8929a99ac7601fcbabe515ea28..ccd1549e5bc5a005dd69cbdc394abb9f083f7232 100644
--- a/preprocessor/Statement.cc
+++ b/preprocessor/Statement.cc
@@ -28,6 +28,7 @@ ModFileStructure::ModFileStructure() :
   ramsey_policy_present(false),
   order_option(0),
   bvar_present(false),
+  svar_identification_present(false),
   identification_present(false),
   partial_information(false),
   shocks_present(false)
diff --git a/preprocessor/Statement.hh b/preprocessor/Statement.hh
index 5469bb979e4bbe5a7a31eeab22fc36b8dc621f26..55844d425e52f4118faab237f513f686629fdd62 100644
--- a/preprocessor/Statement.hh
+++ b/preprocessor/Statement.hh
@@ -50,6 +50,8 @@ public:
   int order_option;
   //! Whether a bvar_density, bvar_forecast, sbvar, ms_sbvar statement is present
   bool bvar_present;
+  //! Whether an svar_identification statement is present
+  bool svar_identification_present;
   //! Whether an identification statement is present or the identification option of dynare_sensitivity statement is equal to one
   bool identification_present;
   //! Whether the option partial_information is given to stoch_simul/estimation/osr/ramsey_policy