diff --git a/ComputingTasks.cc b/ComputingTasks.cc
index 8f549dbf520fed77b615605af9ecb41964c55363..fcbda92303042618d8150f1a086b02e1c5f689f6 100644
--- a/ComputingTasks.cc
+++ b/ComputingTasks.cc
@@ -1612,6 +1612,9 @@ MarkovSwitchingStatement::checkPass(ModFileStructure &mod_file_struct, WarningCo
             }
         }
     }
+
+  if (options_list.symbol_list_options.find("ms.parameters") != options_list.symbol_list_options.end())
+    mod_file_struct.ms_dsge_present = true;
 }
 
 void
diff --git a/DynamicModel.cc b/DynamicModel.cc
index 87239eeafd9131fdb9d16bf0d17f35012d9acc2d..c0363d3ca16c9b44faa03e154120c36379bc42a1 100644
--- a/DynamicModel.cc
+++ b/DynamicModel.cc
@@ -2956,6 +2956,148 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block_de
 
 }
 
+void
+DynamicModel::writeCOutput(ostream &output, const string &basename, bool block_decomposition, bool byte_code, bool use_dll, int order, bool estimation_present) const
+{
+  /* 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
+     models (nbr of rows = M_.max_lag+M_.max_lead+1)
+
+     The matrix elements are equal to zero if a variable isn't present in the
+     model at a given period.
+  */
+
+  vector<int> state_var, state_equ;
+  output << endl
+         << "int lead_lag_incidence["
+         << max_lag+max_lead+1 <<"]["
+         << symbol_table.endo_nbr() << "];" << endl;
+  // Loop on endogenous variables
+  int nstatic = 0,
+      nfwrd   = 0,
+      npred   = 0,
+      nboth   = 0;
+  for (int endoID = 0; endoID < symbol_table.endo_nbr(); endoID++)
+    {
+      int sstatic = 1,
+          sfwrd   = 0,
+          spred   = 0,
+          sboth   = 0;
+      // Loop on periods
+      for (int lag = -max_endo_lag; lag <= max_endo_lead; lag++)
+        {
+          // Print variableID if exists with current period, otherwise print 0
+          try
+            {
+              int varID = getDerivID(symbol_table.getID(eEndogenous, endoID), lag);
+              output << "lead_lag_incidence[" << lag + max_endo_lag << "][" << endoID << "] = "
+                     << getDynJacobianCol(varID) <<  ";" << endl;
+              if (lag == -1)
+                {
+                  sstatic = 0;
+                  spred = 1;
+                }
+              else if (lag == 1)
+                {
+                  if (spred == 1)
+                    {
+                      sboth = 1;
+                      spred = 0;
+                    }
+                  else
+                    {
+                      sstatic = 0;
+                      sfwrd = 1;
+                    }
+                }
+            }
+          catch (UnknownDerivIDException &e)
+            {
+              output << "lead_lag_incidence[" << lag + max_endo_lag << "][" << endoID << "] = 0;" << endl;
+            }
+        }
+      nstatic += sstatic;
+      nfwrd   += sfwrd;
+      npred   += spred;
+      nboth   += sboth;
+    }
+  output << "int nstatic = " << nstatic << ";" << endl
+         << "int nfwrd   = " << nfwrd   << ";" << endl
+         << "int npred   = " << npred   << ";" << endl
+         << "int nboth   = " << nboth   << ";" << endl;
+  for (int endoID = 0; endoID < symbol_table.endo_nbr(); endoID++)
+    {
+      // Loop on periods
+      for (int lag = -max_endo_lag; lag < 0; lag++)
+        {
+          // Print variableID if exists with current period, otherwise print 0
+          try
+            {
+              getDerivID(symbol_table.getID(eEndogenous, variable_reordered[endoID]), lag);
+              if (lag < 0 && find(state_var.begin(), state_var.end(), variable_reordered[endoID]+1) == state_var.end())
+                state_var.push_back(variable_reordered[endoID]);
+            }
+          catch (UnknownDerivIDException &e)
+            {
+            }
+        }
+    }
+
+  // Writing initialization for some other variables
+  output << endl
+         << "int state_var[" << state_var.size() << "] = {";
+  for (size_t i = 0; i < state_var.size(); i++)
+    if (i+1 == state_var.size())
+      output << state_var[i];
+    else
+      output << state_var[i] << ", ";
+  output << "};" << endl;
+
+  output << endl
+         << "int maximum_lag = " << max_lag << ";" << endl
+         << "int maximum_lead = " << max_lead << ";" << endl;
+
+  if (symbol_table.endo_nbr())
+    output << endl
+           << "int maximum_endo_lag = " << max_endo_lag << ";" << endl
+           << "int maximum_endo_lead = " << max_endo_lead << ";" << endl
+           << "double steady_state[" << symbol_table.endo_nbr() << "];" << endl;
+
+  if (symbol_table.exo_nbr())
+    output << endl
+           << "int maximum_exo_lag = " << max_exo_lag << ";" << endl
+           << "int maximum_exo_lead = " << max_exo_lead << ";" << endl
+           << "double exo_steady_state[" << symbol_table.exo_nbr() << "];" << endl;
+
+  if (symbol_table.exo_det_nbr())
+    output << endl
+           << "int maximum_exo_det_lag = " << max_exo_det_lag << ";" << endl
+           << "int maximum_exo_det_lead = " << max_exo_det_lead << ";" << endl
+           << "double exo_det_steady_state[" << symbol_table.exo_det_nbr() << "];" << endl;
+
+  if (symbol_table.param_nbr())
+    output << endl
+           << "double params[" << symbol_table.param_nbr() << "];" << endl;
+
+  // Write number of non-zero derivatives
+  // Use -1 if the derivatives have not been computed
+  output << endl
+         << "int NNZDerivatives[3];" << endl
+         << "NNZDerivatives[0] = " << NNZDerivatives[0] << ";" << endl;
+  if (order > 1)
+    {
+      output << "NNZDerivatives[1] = " << NNZDerivatives[1] << ";" << endl;
+      if (order > 2)
+        output << "NNZDerivatives[2] = " << NNZDerivatives[2] << ";" << endl;
+      else
+        output << "NNZDerivatives[2] = -1;" << endl;
+    }
+  else
+    output << "NNZDerivatives[1] = -1;" << endl
+           << "NNZDerivatives[2] = -1;" << endl;
+}
+
 map<pair<int, pair<int, int > >, expr_t>
 DynamicModel::collect_first_order_derivatives_endogenous()
 {
diff --git a/DynamicModel.hh b/DynamicModel.hh
index 07716efe34a998eec3c8238fb656cd74aac6aace..e23816a0842129e5afcc2312980378f942907d0c 100644
--- a/DynamicModel.hh
+++ b/DynamicModel.hh
@@ -213,6 +213,8 @@ public:
                      const eval_context_t &eval_context, bool no_tmp_terms, bool block, bool use_dll, bool bytecode);
   //! Writes model initialization and lead/lag incidence matrix to output
   void writeOutput(ostream &output, const string &basename, bool block, bool byte_code, bool use_dll, int order, bool estimation_present) const;
+  //! Writes model initialization and lead/lag incidence matrix to C output
+  void writeCOutput(ostream &output, const string &basename, bool block, bool byte_code, bool use_dll, int order, bool estimation_present) const;
 
   //! Adds informations for simulation in a binary file
   void Write_Inf_To_Bin_File_Block(const string &dynamic_basename, const string &bin_basename,
diff --git a/DynareMain2.cc b/DynareMain2.cc
index 66ade0c849b7db39e0dec14d0cb253235009f6e5..c1704989588b883cb468579921b60ff527ef3dba 100644
--- a/DynareMain2.cc
+++ b/DynareMain2.cc
@@ -56,7 +56,10 @@ main2(stringstream &in, string &basename, bool debug, bool clear_all, bool no_tm
   mod_file->computingPass(no_tmp_terms);
 
   // Write outputs
-  mod_file->writeOutputFiles(basename, clear_all, no_log, no_warn, console, nograph, nointeractive, config_file
+  if (mod_file->c_driver)
+    mod_file->writeCOutputFiles(basename);
+  else
+    mod_file->writeOutputFiles(basename, clear_all, no_log, no_warn, console, nograph, nointeractive, config_file
 #if defined(_WIN32) || defined(__CYGWIN32__)
                              , cygwin, msvc
 #endif
@@ -64,6 +67,7 @@ main2(stringstream &in, string &basename, bool debug, bool clear_all, bool no_tm
 
   delete mod_file;
 
-  cout << "Preprocessing completed." << endl
-       << "Starting MATLAB/Octave computing." << endl;
+  cout << "Preprocessing completed." << endl;
+  if (!mod_file->use_dll)
+    cout << "Starting MATLAB/Octave computing." << endl;
 }
diff --git a/ModFile.cc b/ModFile.cc
index 2c44e3f2434c96d53e74db85772b701f7b4ad7ee..7571da2ddbc91f4b6d335a115add66865d407559 100644
--- a/ModFile.cc
+++ b/ModFile.cc
@@ -40,7 +40,7 @@ ModFile::ModFile(WarningConsolidation &warnings_arg)
     linear(false), block(false), byte_code(false), use_dll(false), no_static(false), 
     differentiate_forward_vars(false),
     nonstationary_variables(false), ramsey_policy_orig_eqn_nbr(0),
-    warnings(warnings_arg)
+    warnings(warnings_arg), c_driver(false)
 {
 }
 
@@ -444,6 +444,9 @@ ModFile::transformPass(bool nostrict)
                << "greater than or equal to the number of observed variables." << endl;
           exit(EXIT_FAILURE);
         }
+
+  if (mod_file_struct.ms_dsge_present)
+    c_driver = true;
 }
 
 void
@@ -797,3 +800,62 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool no_log, b
 
   cout << "done" << endl;
 }
+
+void
+ModFile::writeCOutputFiles(const string &basename) const
+{
+  // Erase possible remnants of previous runs
+  string dynfile = basename + "_dynamic.m";
+  unlink(dynfile.c_str());
+
+  dynfile = basename + "_dynamic.c";
+  unlink(dynfile.c_str());
+
+  dynfile = basename + "_dynamic_mex.c";
+  unlink(dynfile.c_str());
+
+  string statfile = basename + "_static.m";
+  unlink(statfile.c_str());
+
+  statfile = basename + "_static.c";
+  unlink(statfile.c_str());
+
+  statfile = basename + "_static_mex.c";
+  unlink(statfile.c_str());
+
+  string filename = "cdriver.cc";
+  unlink(filename.c_str());
+
+  ofstream mDriverCFile;
+  mDriverCFile.open(filename.c_str(), ios::out | ios::binary);
+  if (!mDriverCFile.is_open())
+    {
+      cerr << "Error: Can't open file " << filename << " for writing" << endl;
+      exit(EXIT_FAILURE);
+    }
+
+  mDriverCFile << "/*" << endl
+               << " * " << filename << " : Driver file for MS-DSGE code" << endl
+               << " *" << endl
+               << " * Warning : this file is generated automatically by Dynare" << endl
+               << " *           from model file (.mod)" << endl
+               << endl
+               << " */" << endl
+               << endl
+               << "#include \"ms_dsge_c_driver.hh\"" << endl
+               << endl
+               << "int main()" << endl
+               << "{" << endl;
+
+  // Write basic info
+  symbol_table.writeCOutput(mDriverCFile);
+
+  dynamic_model.writeCOutput(mDriverCFile, basename, false, false, true, mod_file_struct.order_option, mod_file_struct.estimation_present);
+
+  mDriverCFile << "}" << endl;
+  mDriverCFile.close();
+
+  dynamic_model.writeDynamicFile(basename, false, false, true, mod_file_struct.order_option);
+  if (!no_static)
+    static_model.writeStaticFile(basename, false, false, true);
+}
diff --git a/ModFile.hh b/ModFile.hh
index cdbca4453afbbb15e55423e1143374885c5d102c..1f8aa0c9afb809cbdf54804910e1c1b1bac58963 100644
--- a/ModFile.hh
+++ b/ModFile.hh
@@ -98,6 +98,9 @@ public:
   /*! (i.e. option parallel_local_files of model block) */
   vector<string> parallel_local_files;
 
+  //! Output C driver file as opposed to Matlab/Octave driver file
+  bool c_driver;
+
 private:
   //! List of statements
   vector<Statement *> statements;
@@ -137,6 +140,8 @@ public:
                         , bool cygwin, bool msvc
 #endif
                         ) const;
+  //! Writes C output files only => No further Matlab processing
+  void writeCOutputFiles(const string &basename) const;
 };
 
 #endif // ! MOD_FILE_HH
diff --git a/Statement.hh b/Statement.hh
index 7cd7b92141c156672a33f41084e75882990744e0..40e37818dc17b05a9efe586b39c851e78423fd0a 100644
--- a/Statement.hh
+++ b/Statement.hh
@@ -105,6 +105,20 @@ public:
   set<int> parameters_within_shocks_values;
   //! Set of estimated parameters (stored as symbol ids)
   set<int> estimated_parameters;
+  //! Whether there is a prior statement present
+  bool prior_statement_present;
+  //! Whether there is a std prior statement present
+  bool std_prior_statement_present;
+  //! Whether there is a corr prior statement present
+  bool corr_prior_statement_present;
+  //! Whether there is a options statement present
+  bool options_statement_present;
+  //! Whether there is a std options statement present
+  bool std_options_statement_present;
+  //! Whether there is a corr options statement present
+  bool corr_options_statement_present;
+  //! Whether a Markov Switching DSGE is present
+  bool ms_dsge_present;
 };
 
 class Statement
diff --git a/SymbolList.hh b/SymbolList.hh
index 45c7023fdf47fc8bfc8641990cf43a2bc570a4db..82f0b79401ced40b14b26ea0fe2a240fc784567a 100644
--- a/SymbolList.hh
+++ b/SymbolList.hh
@@ -43,6 +43,8 @@ public:
   void clear();
   //! Get a copy of the string vector
   vector<string> get_symbols() const { return symbols; };
+  //! Is Empty
+  int empty() const { return symbols.empty(); };
 };
 
 #endif
diff --git a/SymbolTable.cc b/SymbolTable.cc
index 1c8652e590eae3561f89e97dfd3a3527fb01290d..9f670e7f6e996e7a806cae729aca32d4be06e9fc 100644
--- a/SymbolTable.cc
+++ b/SymbolTable.cc
@@ -286,6 +286,78 @@ SymbolTable::writeOutput(ostream &output) const throw (NotYetFrozenException)
     }
 }
 
+void
+SymbolTable::writeCOutput(ostream &output) const throw (NotYetFrozenException)
+{
+  if (!frozen)
+    throw NotYetFrozenException();
+
+  output << endl
+         << "map <string, int > exo_names, exo_det_names, endo_names, param_names;" << endl;
+
+  output << endl
+         << "int exo_nbr = " << exo_nbr() << ";" << endl;
+  if (exo_nbr() > 0)
+    for (int id = 0; id < exo_nbr(); id++)
+      output << "exo_names[\"" << getName(exo_ids[id]) << "\"] = " << id << ";" << endl;
+
+  output << endl
+         << "int exo_det_nbr = " << exo_det_nbr() << ";" << endl;
+  if (exo_det_nbr() > 0)
+    for (int id = 0; id < exo_det_nbr(); id++)
+      output << "exo_det_names[\"" << getName(exo_det_ids[id]) << "\"] = " << id << " ;" << endl;
+
+  output << endl
+         << "int endo_nbr = " << endo_nbr() << ";" << endl
+         << "int orig_endo_nbr = " << orig_endo_nbr() << ";" << endl;
+  if (endo_nbr() > 0)
+    for (int id = 0; id < endo_nbr(); id++)
+      output << "endo_names[\"" << getName(endo_ids[id]) << "\"] = " << id << ";" << endl;
+
+  output << endl
+         << "int param_nbr = " << param_nbr() << ";" << endl;
+  if (param_nbr() > 0)
+    for (int id = 0; id < param_nbr(); id++)
+      output << "param_names[\"" << getName(param_ids[id]) << "\"] = " << id << ";" << endl;
+
+  // Write the auxiliary variable table
+  output << endl
+         << "vector <aux_vars_t> aux_vars;" << endl;
+  if (aux_vars.size() > 0)
+    for (int i = 0; i < (int) aux_vars.size(); i++)
+      {
+        output << "aux_vars_t av" << i << ";" << endl;
+        output << "av" << i << ".endo_index = " << getTypeSpecificID(aux_vars[i].get_symb_id()) << ";" << endl
+               << "av" << i << ".type = " << aux_vars[i].get_type() << ";" << endl;
+        switch (aux_vars[i].get_type())
+          {
+          case avEndoLead:
+          case avExoLead:
+          case avExpectation:
+          case avMultiplier:
+            break;
+          case avEndoLag:
+          case avExoLag:
+            output << "av" << i << ".orig_index = " << getTypeSpecificID(aux_vars[i].get_orig_symb_id()) << ";" << endl
+                   << "av" << i << ".orig_lead_lag = " << aux_vars[i].get_orig_lead_lag() << ";" << endl;
+            break;
+          }
+        output << "aux_vars.push_back(" << "av" << i << ");" << endl;
+      }
+
+  output << endl
+         << "vector <int> predetermined_variables, varobs;" << endl;
+  if (predeterminedNbr() > 0)
+    for (set<int>::const_iterator it = predetermined_variables.begin();
+         it != predetermined_variables.end(); it++)
+      output << "predetermined_variables.push_back(" << getTypeSpecificID(*it) << ");" << endl;
+
+  if (observedVariablesNbr() > 0)
+    for (vector<int>::const_iterator it = varobs.begin();
+         it != varobs.end(); it++)
+      output << "varobs.push_back(" << getTypeSpecificID(*it) << ");" << endl;
+}
+
 int
 SymbolTable::addLeadAuxiliaryVarInternal(bool endo, int index) throw (FrozenException)
 {
diff --git a/SymbolTable.hh b/SymbolTable.hh
index 49c208553d1b608f5ab48056e72a45af5d01cbe3..c87160145ac0e4efd3b2640afdcf7e4129987c86 100644
--- a/SymbolTable.hh
+++ b/SymbolTable.hh
@@ -276,6 +276,8 @@ public:
   inline int orig_endo_nbr() const throw (NotYetFrozenException);
   //! Write output of this class
   void writeOutput(ostream &output) const throw (NotYetFrozenException);
+  //! Write C output of this class
+  void writeCOutput(ostream &output) const throw (NotYetFrozenException);
   //! Mark a symbol as predetermined variable
   void markPredetermined(int symb_id) throw (UnknownSymbolIDException, FrozenException);
   //! Test if a given symbol is a predetermined variable