diff --git a/ComputingTasks.cc b/ComputingTasks.cc
index 1af68165fbf0b55b33b166d9632b41aac1155f1d..2daf075dc1891d21cce3837fc530bb16fc28aeaa 100644
--- a/ComputingTasks.cc
+++ b/ComputingTasks.cc
@@ -2053,7 +2053,7 @@ PlannerObjectiveStatement::getPlannerObjective() const
 void
 PlannerObjectiveStatement::computingPass()
 {
-  model_tree->computingPass(eval_context_t(), false, true, true, none, false, false);
+  model_tree->computingPass(eval_context_t(), false, true, true, none, false, false, false);
   computing_pass_called = true;
 }
 
@@ -4686,3 +4686,141 @@ Smoother2histvalStatement::writeJsonOutput(ostream &output) const
     }
   output << "}";
 }
+
+GMMEstimationStatement::GMMEstimationStatement(const SymbolList &symbol_list_arg,
+                                               const OptionsList &options_list_arg) :
+  symbol_list(symbol_list_arg),
+  options_list(options_list_arg)
+{
+}
+
+void
+GMMEstimationStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const
+{
+  symbol_list.writeOutput("var_list_", output);
+  options_list.writeOutput(output);
+  output << "[M_, oo_, estim_params_, bayestopt_, dataset_, dataset_info] = "
+         << "GMM_SMM_estimation_core(var_list_, M_, options_, oo_, estim_params_, bayestopt_, dataset_, dataset_info, 'GMM');" << endl;
+}
+
+void
+GMMEstimationStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"gmm_estimation\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  if (!symbol_list.empty())
+    {
+      output << ", ";
+      symbol_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
+SMMEstimationStatement::SMMEstimationStatement(const SymbolList &symbol_list_arg,
+                                               const OptionsList &options_list_arg) :
+  symbol_list(symbol_list_arg),
+  options_list(options_list_arg)
+{
+}
+
+void
+SMMEstimationStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const
+{
+  symbol_list.writeOutput("var_list_", output);
+  options_list.writeOutput(output);
+  output << "[M_, oo_, estim_params_, bayestopt_, dataset_, dataset_info] = "
+         << "GMM_SMM_estimation_core(var_list_, M_, options_, oo_, estim_params_, bayestopt_, dataset_, dataset_info, 'SMM');" << endl;
+}
+
+void
+SMMEstimationStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"smm_estimation\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  if (!symbol_list.empty())
+    {
+      output << ", ";
+      symbol_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
+GenerateIRFsStatement::GenerateIRFsStatement(const OptionsList &options_list_arg,
+                                             const vector<string> &generate_irf_names_arg,
+                                             const vector<map<string, double> > &generate_irf_elements_arg) :
+  options_list(options_list_arg),
+  generate_irf_names(generate_irf_names_arg),
+  generate_irf_elements(generate_irf_elements_arg)
+{
+}
+
+void
+GenerateIRFsStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const
+{
+  options_list.writeOutput(output);
+
+  if (generate_irf_names.empty())
+    return;
+
+  output << "options_.irf_opt.irf_shock_graphtitles = { ";
+  for (vector<string>::const_iterator it = generate_irf_names.begin();
+       it != generate_irf_names.end(); it++)
+    output << "'" << *it << "'; ";
+  output << "};" << endl;
+
+  output << "options_.irf_opt.irf_shocks = zeros(M_.exo_nbr, "
+         << generate_irf_names.size() << ");" << endl;
+
+  for (size_t i = 0; i < generate_irf_names.size(); i++)
+    {
+      map<string, double> m = generate_irf_elements[i];
+      for (map<string, double>::const_iterator it = m.begin();
+         it != m.end(); it++)
+        output << "options_.irf_opt.irf_shocks(M_.exo_names == '"
+               << it->first << "', " << i + 1 << ") = "
+               << it->second << ";" << endl;
+    }
+}
+
+void
+GenerateIRFsStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"generate_irfs\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+
+  if (!generate_irf_names.empty())
+    {
+      output << ", \"irf_elements\": [";
+      for (size_t i = 0; i < generate_irf_names.size(); i++)
+        {
+          output << "{\"name\": \"" << generate_irf_names[i] << "\", \"shocks\": [";
+          map<string, double> m = generate_irf_elements[i];
+          size_t idx = 0;
+          for (map<string, double>::const_iterator it = m.begin();
+               it != m.end(); it++, idx++)
+            {
+              output << "{\"exogenous_variable\": \"" << it->first << "\", "
+                     << "\"exogenous_variable_value\": \"" << it->second << "\"}";
+              if (idx + 1 < m.size())
+                output << ", ";
+            }
+          output << "]}";
+          if (i + 1 < generate_irf_names.size())
+            output << ", ";
+        }
+      output << "]";
+    }
+  output << "}";
+}
diff --git a/ComputingTasks.hh b/ComputingTasks.hh
index 3f09c1a7cb260684e3108a93efd5d5d2280b97e2..8432be9fa28f6dc70168b503633b4405b56f71ba 100644
--- a/ComputingTasks.hh
+++ b/ComputingTasks.hh
@@ -1138,4 +1138,41 @@ public:
   virtual void writeJsonOutput(ostream &output) const;
 };
 
+class GMMEstimationStatement : public Statement
+{
+private:
+  const SymbolList symbol_list;
+  const OptionsList options_list;
+public:
+  GMMEstimationStatement(const SymbolList &symbol_list_arg, const OptionsList &options_list_arg);
+  virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
+};
+
+class SMMEstimationStatement : public Statement
+{
+private:
+  const SymbolList symbol_list;
+  const OptionsList options_list;
+public:
+  SMMEstimationStatement(const SymbolList &symbol_list_arg, const OptionsList &options_list_arg);
+  virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
+};
+
+class GenerateIRFsStatement : public Statement
+{
+public:
+private:
+  const OptionsList options_list;
+  const vector<string> generate_irf_names;
+  const vector<map<string, double> > generate_irf_elements;
+public:
+  GenerateIRFsStatement(const OptionsList &options_list_arg,
+                        const vector<string> &generate_irf_names_arg,
+                        const vector<map<string, double> > &generate_irf_elements_arg);
+  virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
+};
+
 #endif
diff --git a/DynamicModel.cc b/DynamicModel.cc
index aba9a8740b3d00600191aaab4042dba3a186c345..19072ce71dab3aef3fbeca6c6bfdc6b8d93309aa 100644
--- a/DynamicModel.cc
+++ b/DynamicModel.cc
@@ -2539,6 +2539,7 @@ DynamicModel::writeDynamicModel(ostream &DynamicOutput, bool use_dll, bool julia
 
       DynamicOutput << "#=" << endl << comments.str() << "=#" << endl
                     << "  @assert size(g2) == (" << nrows << ", " << hessianColsNbr << ")" << endl
+                    << "  fill!(g2, 0.0)" << endl
                     << "  dynamic!(y, x, params, steady_state, it_, residual, g1)" << endl;
       if (second_derivatives.size())
         DynamicOutput << model_local_vars_output.str()
@@ -2562,6 +2563,7 @@ DynamicModel::writeDynamicModel(ostream &DynamicOutput, bool use_dll, bool julia
 
       DynamicOutput << "#=" << endl << comments.str() << "=#" << endl
                     << "  @assert size(g3) == (" << nrows << ", " << ncols << ")" << endl
+                    << "  fill!(g3, 0.0)" << endl
                     << "  dynamic!(y, x, params, steady_state, it_, residual, g1, g2)" << endl;
       if (third_derivatives.size())
         DynamicOutput << model_local_vars_output.str()
@@ -3270,7 +3272,7 @@ DynamicModel::addEquationsForVar(map<string, pair<SymbolList, int> > var_model_i
 void
 DynamicModel::computingPass(bool jacobianExo, bool hessian, bool thirdDerivatives, int paramsDerivsOrder,
                             const eval_context_t &eval_context, bool no_tmp_terms, bool block, bool use_dll,
-                            bool bytecode)
+                            bool bytecode, const bool nopreprocessoroutput)
 {
   assert(jacobianExo || !(hessian || thirdDerivatives || paramsDerivsOrder));
 
@@ -3293,19 +3295,22 @@ DynamicModel::computingPass(bool jacobianExo, bool hessian, bool thirdDerivative
     }
 
   // Launch computations
-  cout << "Computing dynamic model derivatives:" << endl
-       << " - order 1" << endl;
+  if (!nopreprocessoroutput)
+    cout << "Computing dynamic model derivatives:" << endl
+         << " - order 1" << endl;
   computeJacobian(vars);
 
   if (hessian)
     {
-      cout << " - order 2" << endl;
+      if (!nopreprocessoroutput)
+        cout << " - order 2" << endl;
       computeHessian(vars);
     }
 
   if (paramsDerivsOrder > 0)
     {
-      cout << " - derivatives of Jacobian/Hessian w.r. to parameters" << endl;
+      if (!nopreprocessoroutput)
+        cout << " - derivatives of Jacobian/Hessian w.r. to parameters" << endl;
       computeParamsDerivatives(paramsDerivsOrder);
 
       if (!no_tmp_terms)
@@ -3314,7 +3319,8 @@ DynamicModel::computingPass(bool jacobianExo, bool hessian, bool thirdDerivative
 
   if (thirdDerivatives)
     {
-      cout << " - order 3" << endl;
+      if (!nopreprocessoroutput)
+        cout << " - order 3" << endl;
       computeThirdDerivatives(vars);
     }
 
@@ -3336,7 +3342,8 @@ DynamicModel::computingPass(bool jacobianExo, bool hessian, bool thirdDerivative
 
       equation_type_and_normalized_equation = equationTypeDetermination(first_order_endo_derivatives, variable_reordered, equation_reordered, mfs);
 
-      cout << "Finding the optimal block decomposition of the model ...\n";
+      if (!nopreprocessoroutput)
+        cout << "Finding the optimal block decomposition of the model ...\n";
 
       lag_lead_vector_t equation_lag_lead, variable_lag_lead;
 
@@ -3858,7 +3865,7 @@ DynamicModel::replaceMyEquations(DynamicModel &dynamic_model) const
 }
 
 void
-DynamicModel::computeRamseyPolicyFOCs(const StaticModel &static_model)
+DynamicModel::computeRamseyPolicyFOCs(const StaticModel &static_model, const bool nopreprocessoroutput)
 {
   // Add aux LM to constraints in equations
   // equation[i]->lhs = rhs becomes equation[i]->MULT_(i+1)*(lhs-rhs) = 0
@@ -3869,8 +3876,8 @@ DynamicModel::computeRamseyPolicyFOCs(const StaticModel &static_model)
       assert(substeq != NULL);
       equations[i] = substeq;
     }
-
-  cout << "Ramsey Problem: added " << i << " Multipliers." << endl;
+  if (!nopreprocessoroutput)
+    cout << "Ramsey Problem: added " << i << " Multipliers." << endl;
 
   // Add Planner Objective to equations to include in computeDerivIDs
   assert(static_model.equations.size() == 1);
@@ -5633,16 +5640,15 @@ DynamicModel::writeJsonOutput(ostream &output) const
 }
 
 void
-DynamicModel::writeJsonXrefs(ostream &output) const
+DynamicModel::writeJsonXrefsHelper(ostream &output, const map<pair<int, int>, set<int> > &xrefs) const
 {
-  output << "\"xrefs\": {"
-         << "\"parameters\": [";
-  for (map<pair<int, int>, set<int> >::const_iterator it = xref_param.begin();
-       it != xref_param.end(); it++)
+  for (map<pair<int, int>, set<int> >::const_iterator it = xrefs.begin();
+       it != xrefs.end(); it++)
     {
-      if (it != xref_param.begin())
+      if (it != xrefs.begin())
         output << ", ";
-      output << "{\"parameter\": \"" << symbol_table.getName(it->first.first) << "\""
+      output << "{\"name\": \"" << symbol_table.getName(it->first.first) << "\""
+             << ", \"shift\": " << it->first.second
              << ", \"equations\": [";
       for (set<int>::const_iterator it1 = it->second.begin();
            it1 != it->second.end(); it1++)
@@ -5653,63 +5659,23 @@ DynamicModel::writeJsonXrefs(ostream &output) const
         }
       output << "]}";
     }
+}
+
+void
+DynamicModel::writeJsonXrefs(ostream &output) const
+{
+  output << "\"xrefs\": {"
+         << "\"parameters\": [";
+  writeJsonXrefsHelper(output, xref_param);
   output << "]"
          << ", \"endogenous\": [";
-  for (map<pair<int, int>, set<int> >::const_iterator it = xref_endo.begin();
-       it != xref_endo.end(); it++)
-    {
-      if (it != xref_endo.begin())
-        output << ", ";
-      output << "{\"endogenous\": \"" << symbol_table.getName(it->first.first) << "\""
-             << ", \"shift\": " << it->first.second
-             << ", \"equations\": [";
-      for (set<int>::const_iterator it1 = it->second.begin();
-           it1 != it->second.end(); it1++)
-        {
-          if (it1 != it->second.begin())
-            output << ", ";
-          output << *it1 + 1;
-        }
-      output << "]}";
-    }
+  writeJsonXrefsHelper(output, xref_endo);
   output << "]"
          << ", \"exogenous\": [";
-  for (map<pair<int, int>, set<int> >::const_iterator it = xref_exo.begin();
-       it != xref_exo.end(); it++)
-    {
-      if (it != xref_exo.begin())
-        output << ", ";
-      output << "{\"exogenous\": \"" << symbol_table.getName(it->first.first) << "\""
-             << ", \"shift\": " << it->first.second
-             << ", \"equations\": [";
-      for (set<int>::const_iterator it1 = it->second.begin();
-           it1 != it->second.end(); it1++)
-        {
-          if (it1 != it->second.begin())
-            output << ", ";
-          output << *it1 + 1;
-        }
-      output << "]}";
-    }
+    writeJsonXrefsHelper(output, xref_exo);
   output << "]"
          << ", \"exogenous_deterministic\": [";
-  for (map<pair<int, int>, set<int> >::const_iterator it = xref_exo_det.begin();
-       it != xref_exo_det.end(); it++)
-    {
-      if (it != xref_exo_det.begin())
-        output << ", ";
-      output << "{\"exogenous_det\": \"" << symbol_table.getName(it->first.first) << "\""
-             << ", \"shift\": " << it->first.second
-             << ", \"equations\": [";
-      for (set<int>::const_iterator it1 = it->second.begin();
-           it1 != it->second.end(); it1++)
-        {
-          if (it1 != it->second.begin())
-            output << ", ";
-          output << *it1 + 1;
-        }
-      output << "]}";
-    }
+  writeJsonXrefsHelper(output, xref_exo_det);
   output << "]}" << endl;
 }
 
diff --git a/DynamicModel.hh b/DynamicModel.hh
index 9bc5c29591505caf44c21095a3fe4947dc2b1538..c9eaec7fff9fc3e0e6d935db2e9b33428dbba6d1 100644
--- a/DynamicModel.hh
+++ b/DynamicModel.hh
@@ -248,7 +248,7 @@ public:
     \param no_tmp_terms if true, no temporary terms will be computed in the dynamic files
   */
   void computingPass(bool jacobianExo, bool hessian, bool thirdDerivatives, int paramsDerivsOrder,
-                     const eval_context_t &eval_context, bool no_tmp_terms, bool block, bool use_dll, bool bytecode);
+                     const eval_context_t &eval_context, bool no_tmp_terms, bool block, bool use_dll, bool bytecode, const bool nopreprocessoroutput);
   //! 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, bool compute_xrefs, bool julia) const;
 
@@ -269,6 +269,7 @@ public:
 
   //! Write cross reference output if the xref maps have been filed
   void writeJsonXrefs(ostream &output) const;
+  void writeJsonXrefsHelper(ostream &output, const map<pair<int, int>, set<int> > &xrefs) const;
 
   //! Return true if the hessian is equal to zero
   inline bool checkHessianZero() const;
@@ -306,7 +307,7 @@ public:
   void cloneDynamic(DynamicModel &dynamic_model) const;
 
   //! Replaces model equations with derivatives of Lagrangian w.r.t. endogenous
-  void computeRamseyPolicyFOCs(const StaticModel &static_model);
+  void computeRamseyPolicyFOCs(const StaticModel &static_model, const bool nopreprocessoroutput);
   //! Replaces the model equations in dynamic_model with those in this model
   void replaceMyEquations(DynamicModel &dynamic_model) const;
 
diff --git a/DynareBison.yy b/DynareBison.yy
index a6bfaf79c4e462f9942787721584c1fbf9dc23bd..821e97f2b0eee440fbfe71f9dd7a0f90356107ac 100644
--- a/DynareBison.yy
+++ b/DynareBison.yy
@@ -113,9 +113,9 @@ class ParsingDriver;
 %token CPF_WEIGHTS AMISANOTRISTANI MURRAYJONESPARSLOW WRITE_EQUATION_TAGS METHOD
 %token NONLINEAR_FILTER_INITIALIZATION FILTER_ALGORITHM PROPOSAL_APPROXIMATION CUBATURE UNSCENTED MONTECARLO DISTRIBUTION_APPROXIMATION
 %token <string_val> NAME
-%token USE_PENALIZED_OBJECTIVE_FOR_HESSIAN INIT_STATE RESCALE_PREDICTION_ERROR_COVARIANCE
+%token USE_PENALIZED_OBJECTIVE_FOR_HESSIAN INIT_STATE RESCALE_PREDICTION_ERROR_COVARIANCE GENERATE_IRFS
 %token NAN_CONSTANT NO_STATIC NOBS NOCONSTANT NODISPLAY NOCORR NODIAGNOSTIC NOFUNCTIONS NO_HOMOTOPY
-%token NOGRAPH POSTERIOR_NOGRAPH POSTERIOR_GRAPH NOMOMENTS NOPRINT NORMAL_PDF SAVE_DRAWS MODEL_NAME
+%token NOGRAPH POSTERIOR_NOGRAPH POSTERIOR_GRAPH NOMOMENTS NOPRINT NORMAL_PDF SAVE_DRAWS MODEL_NAME STDERR_MULTIPLES DIAGONAL_ONLY
 %token OBSERVATION_TRENDS OPTIM OPTIM_WEIGHTS ORDER OSR OSR_PARAMS MAX_DIM_COVA_GROUP ADVANCED OUTFILE OUTVARS OVERWRITE
 %token PARALLEL_LOCAL_FILES PARAMETERS PARAMETER_SET PARTIAL_INFORMATION PERIODS PERIOD PLANNER_OBJECTIVE PLOT_CONDITIONAL_FORECAST PLOT_PRIORS PREFILTER PRESAMPLE
 %token PERFECT_FORESIGHT_SETUP PERFECT_FORESIGHT_SOLVER NO_POSTERIOR_KERNEL_DENSITY FUNCTION
@@ -151,7 +151,7 @@ class ParsingDriver;
 %token VLISTLOG VLISTPER SPECTRAL_DENSITY
 %token RESTRICTION RESTRICTION_FNAME CROSS_RESTRICTIONS NLAGS CONTEMP_REDUCED_FORM REAL_PSEUDO_FORECAST
 %token DUMMY_OBS NSTATES INDXSCALESSTATES NO_BAYESIAN_PRIOR SPECIFICATION SIMS_ZHA
-%token <string_val> ALPHA BETA ABAND NINV CMS NCMS CNUM GAMMA INV_GAMMA INV_GAMMA1 INV_GAMMA2 NORMAL UNIFORM EPS PDF FIG DR NONE PRIOR PRIOR_VARIANCE HESSIAN IDENTITY_MATRIX DIRICHLET
+%token <string_val> ALPHA BETA ABAND NINV CMS NCMS CNUM GAMMA INV_GAMMA INV_GAMMA1 INV_GAMMA2 NORMAL UNIFORM EPS PDF FIG DR NONE PRIOR PRIOR_VARIANCE HESSIAN IDENTITY_MATRIX DIRICHLET DIAGONAL OPTIMAL
 %token GSIG2_LMDM Q_DIAG FLAT_PRIOR NCSK NSTD WEIBULL WEIBULL_PDF
 %token INDXPARR INDXOVR INDXAP APBAND INDXIMF IMFBAND INDXFORE FOREBAND INDXGFOREHAT INDXGIMFHAT
 %token INDXESTIMA INDXGDLS EQ_MS FILTER_COVARIANCE FILTER_DECOMPOSITION SMOOTHED_STATE_UNCERTAINTY
@@ -168,13 +168,17 @@ class ParsingDriver;
 %token SHOCK_DRAWS FREE_PARAMETERS MEDIAN DATA_OBS_NBR NEIGHBORHOOD_WIDTH PVALUE_KS PVALUE_CORR
 %token FILTERED_PROBABILITIES REAL_TIME_SMOOTHED PRIOR_FUNCTION POSTERIOR_FUNCTION SAMPLING_DRAWS
 %token PROPOSAL_TYPE PROPOSAL_UPPER_BOUND PROPOSAL_LOWER_BOUND PROPOSAL_DRAWS USE_MEAN_CENTER
-%token ADAPTIVE_MH_DRAWS THINNING_FACTOR COEFFICIENTS_PRIOR_HYPERPARAMETERS
+%token ADAPTIVE_MH_DRAWS THINNING_FACTOR COEFFICIENTS_PRIOR_HYPERPARAMETERS SMM_ESTIMATION GMM_ESTIMATION
 %token CONVERGENCE_STARTING_VALUE CONVERGENCE_ENDING_VALUE CONVERGENCE_INCREMENT_VALUE
 %token MAX_ITERATIONS_STARTING_VALUE MAX_ITERATIONS_INCREMENT_VALUE MAX_BLOCK_ITERATIONS
 %token MAX_REPEATED_OPTIMIZATION_RUNS FUNCTION_CONVERGENCE_CRITERION SAVE_REALTIME
 %token PARAMETER_CONVERGENCE_CRITERION NUMBER_OF_LARGE_PERTURBATIONS NUMBER_OF_SMALL_PERTURBATIONS
 %token NUMBER_OF_POSTERIOR_DRAWS_AFTER_PERTURBATION MAX_NUMBER_OF_STAGES
 %token RANDOM_FUNCTION_CONVERGENCE_CRITERION RANDOM_PARAMETER_CONVERGENCE_CRITERION
+%token CENTERED_MOMENTS AUTOLAG RECURSIVE_ORDER_ESTIMATION BARTLETT_KERNEL_LAG WEIGHTING_MATRIX PENALIZED_ESTIMATOR VERBOSE
+%token SIMULATION_MULTIPLE SEED BOUNDED_SHOCK_SUPPORT
+%token ANALYTICAL_GIRF IRF_IN_PERCENT EMAS_GIRF EMAS_DROP EMAS_TOLF EMAS_MAX_ITER
+
 %token <vector_string_val> SYMBOL_VEC
 
 %type <node_val> expression expression_or_empty
@@ -280,6 +284,7 @@ statement : parameters
           | external_function
           | steady_state_model
           | trend_var
+          | generate_irfs
           | log_trend_var
           | ms_estimation
           | ms_simulation
@@ -299,6 +304,8 @@ statement : parameters
           | perfect_foresight_solver
           | prior_function
           | posterior_function
+          | gmm_estimation
+          | smm_estimation
           | shock_groups
           ;
 
@@ -1215,6 +1222,100 @@ perfect_foresight_solver_options : o_stack_solve_algo
                                  | o_pf_tolx
                                  ;
 
+gmm_smm_common_option : o_datafile
+                      | o_nobs
+                      | o_first_obs
+                      | o_optim
+                      | o_mode_file
+                      | o_mode_compute
+                      | o_prior_trunc
+                      | o_loglinear
+                      | o_logdata
+                      | o_relative_irf
+                      | o_irf
+                      | o_tex
+                      | o_xls_sheet
+                      | o_xls_range
+                      | o_solve_algo
+                      | o_plot_priors
+                      | o_aim_solver
+                      | o_selected_variables_only
+                      | o_irf_shocks
+                      | o_sylvester
+                      | o_sylvester_fixed_point_tol
+                      | o_lyapunov
+                      | o_lyapunov_fixed_point_tol
+                      | o_lyapunov_doubling_tol
+                      | o_dr
+                      | o_dr_cycle_reduction_tol
+                      | o_dr_logarithmic_reduction_tol
+                      | o_dr_logarithmic_reduction_maxiter
+                      | o_qz_zero_threshold
+                      | o_irf_plot_threshold
+                      | o_consider_all_endogenous
+                      | o_consider_only_observed
+                      | o_dirname
+                      | o_huge_number
+                      | o_silent_optimizer
+                      | o_nograph
+                      | o_nodisplay
+                      | o_graph_format
+                      | o_analytical_girf
+                      | o_irf_in_percent
+                      | o_emas_girf
+                      | o_emas_drop
+                      | o_emas_tolf
+                      | o_emas_max_iter
+                      | o_stderr_multiples
+                      | o_diagonal_only
+                      ;
+
+gmm_estimation : GMM_ESTIMATION '(' gmm_estimation_options_list ')' ';'
+                { driver.gmm_estimation(); }
+               | GMM_ESTIMATION '(' gmm_estimation_options_list ')' symbol_list ';'
+                { driver.gmm_estimation(); }
+               ;
+
+gmm_estimation_options_list : gmm_estimation_option COMMA gmm_estimation_options_list
+                            | gmm_estimation_option
+                            ;
+
+gmm_estimation_option : gmm_smm_common_option
+                       | o_gmm_order
+                       | o_gmm_centered_moments
+                       | o_gmm_autolag
+                       | o_gmm_recursive_order_estimation
+                       | o_gmm_bartlett_kernel_lag
+                       | o_gmm_weighting_matrix
+                       | o_gmm_penalized_estimator
+                       | o_gmm_verbose
+                       ;
+
+smm_estimation : SMM_ESTIMATION '(' smm_estimation_options_list ')' ';'
+                { driver.smm_estimation(); }
+               | SMM_ESTIMATION '(' smm_estimation_options_list ')' symbol_list ';'
+                { driver.smm_estimation(); }
+               ;
+
+smm_estimation_options_list : smm_estimation_option COMMA smm_estimation_options_list
+                            | smm_estimation_option
+                            ;
+
+smm_estimation_option : gmm_smm_common_option
+                       | o_smm_order
+                       | o_smm_centered_moments
+                       | o_smm_autolag
+                       | o_smm_recursive_order_estimation
+                       | o_smm_bartlett_kernel_lag
+                       | o_smm_weighting_matrix
+                       | o_smm_penalized_estimator
+                       | o_smm_verbose
+                       | o_smm_simulation_multiple
+                       | o_smm_drop
+                       | o_smm_seed
+                       | o_smm_bounded_shock_support
+                       ;
+
 prior_function : PRIOR_FUNCTION '(' prior_posterior_function_options_list ')' ';'
                 { driver.prior_posterior_function(true); }
                ;
@@ -1291,6 +1392,14 @@ stoch_simul_primary_options : o_dr_algo
                             | o_irf
                             | o_irf_shocks
                             | o_relative_irf
+                            | o_analytical_girf
+                            | o_irf_in_percent
+                            | o_emas_girf
+                            | o_emas_drop
+                            | o_emas_tolf
+                            | o_emas_max_iter
+                            | o_stderr_multiples
+                            | o_diagonal_only
                             | o_hp_filter
                             | o_hp_ngrid
                             | o_periods
@@ -1975,6 +2084,14 @@ estimation_options : o_datafile
                    | o_keep_kalman_algo_if_singularity_is_detected
                    | o_use_penalized_objective_for_hessian
                    | o_rescale_prediction_error_covariance
+                   | o_analytical_girf
+                   | o_irf_in_percent
+                   | o_emas_girf
+                   | o_emas_drop
+                   | o_emas_tolf
+                   | o_emas_max_iter
+                   | o_stderr_multiples
+                   | o_diagonal_only
                    ;
 
 list_optim_option : QUOTED_STRING COMMA QUOTED_STRING
@@ -2843,6 +2960,38 @@ calib_smoother_option : o_filtered_vars
                       | o_parameter_set
                       ;
 
+generate_irfs : GENERATE_IRFS ';' END ';'
+                { driver.end_generate_irfs(); }
+              | GENERATE_IRFS ';' generate_irfs_element_list END ';'
+                { driver.end_generate_irfs(); }
+              | GENERATE_IRFS '(' generate_irfs_options_list ')' ';' END ';'
+                { driver.end_generate_irfs(); }
+              | GENERATE_IRFS '(' generate_irfs_options_list ')' ';' generate_irfs_element_list END ';'
+                { driver.end_generate_irfs(); }
+              ;
+
+generate_irfs_options_list : generate_irfs_option COMMA generate_irfs_options_list
+                           | generate_irfs_option
+                           ;
+
+generate_irfs_option : o_stderr_multiples
+                     | o_diagonal_only
+                     ;
+
+generate_irfs_element_list : generate_irfs_element_list generate_irfs_element
+                           | generate_irfs_element
+                           ;
+
+generate_irfs_element : NAME COMMA generate_irfs_exog_element_list ';'
+                        { driver.add_generate_irfs_element($1); }
+                      ;
+
+generate_irfs_exog_element_list : generate_irfs_exog_element_list COMMA symbol EQUAL signed_number
+                                  { driver.add_generate_irfs_exog_element($3, $5); }
+                                | symbol EQUAL signed_number
+                                  { driver.add_generate_irfs_exog_element($1, $3); }
+                                ;
+
 extended_path : EXTENDED_PATH ';'
                 { driver.extended_path(); }
               | EXTENDED_PATH '(' extended_path_options_list ')' ';'            
@@ -3238,7 +3387,8 @@ o_bvar_prior_omega : BVAR_PRIOR_OMEGA EQUAL INT_NUMBER { driver.option_num("bvar
 o_bvar_prior_flat : BVAR_PRIOR_FLAT { driver.option_num("bvar_prior_flat", "1"); };
 o_bvar_prior_train : BVAR_PRIOR_TRAIN EQUAL INT_NUMBER { driver.option_num("bvar_prior_train", $3); };
 o_bvar_replic : BVAR_REPLIC EQUAL INT_NUMBER { driver.option_num("bvar_replic", $3); };
-
+o_stderr_multiples : STDERR_MULTIPLES { driver.option_num("irf_opt.stderr_multiples", "1"); };
+o_diagonal_only : DIAGONAL_ONLY { driver.option_num("irf_opt.diagonal_only", "1"); };
 o_number_of_particles : NUMBER_OF_PARTICLES EQUAL INT_NUMBER { driver.option_num("particle.number_of_particles", $3); };
 o_resampling : RESAMPLING EQUAL SYSTEMATIC
               | RESAMPLING EQUAL NONE {driver.option_num("particle.resampling.status.systematic", "0"); driver.option_num("particle.resampling.status.none", "1"); }
@@ -3542,6 +3692,59 @@ o_use_shock_groups : USE_SHOCK_GROUPS { driver.option_str("plot_shock_decomp.use
                    ;
 o_colormap : COLORMAP EQUAL symbol { driver.option_num("plot_shock_decomp.colormap",$3); };
 
+o_gmm_order : ORDER EQUAL INT_NUMBER { driver.option_num("gmm.order", $3); };
+o_smm_order : ORDER EQUAL INT_NUMBER { driver.option_num("smm.order", $3); };
+o_gmm_centered_moments : CENTERED_MOMENTS { driver.option_num("gmm.centered_moments", "1"); };
+o_smm_centered_moments : CENTERED_MOMENTS { driver.option_num("smm.centered_moments", "1"); };
+o_gmm_autolag : AUTOLAG EQUAL vec_int 
+                { driver.option_vec_int("gmm.autolag", $3); }
+              | AUTOLAG EQUAL vec_int_number
+                { driver.option_vec_int("gmm.autolag", $3); }
+              ;
+o_smm_autolag : AUTOLAG EQUAL vec_int 
+                { driver.option_vec_int("smm.autolag", $3); }
+              | AUTOLAG EQUAL vec_int_number
+                { driver.option_vec_int("smm.autolag", $3); }
+              ;
+o_gmm_recursive_order_estimation : RECURSIVE_ORDER_ESTIMATION { driver.option_num("gmm.recursive_estimation", "1"); };
+o_smm_recursive_order_estimation : RECURSIVE_ORDER_ESTIMATION { driver.option_num("smm.recursive_estimation", "1"); };
+o_gmm_bartlett_kernel_lag : BARTLETT_KERNEL_LAG EQUAL INT_NUMBER { driver.option_num("gmm.qLag", $3); };
+o_smm_bartlett_kernel_lag : BARTLETT_KERNEL_LAG EQUAL INT_NUMBER { driver.option_num("smm.qLag", $3); };
+o_gmm_weighting_matrix : WEIGHTING_MATRIX EQUAL OPTIMAL
+                     { driver.option_str("gmm.weighting_matrix", $3); }                                  
+                   | WEIGHTING_MATRIX EQUAL IDENTITY_MATRIX
+                     { driver.option_str("gmm.weighting_matrix", $3); }
+                   | WEIGHTING_MATRIX EQUAL DIAGONAL
+                     { driver.option_str("gmm.weighting_matrix", $3); }
+                   | WEIGHTING_MATRIX EQUAL filename
+                     { driver.option_str("gmm.weighting_matrix", $3); }
+                   ;
+o_smm_weighting_matrix : WEIGHTING_MATRIX EQUAL OPTIMAL
+                     { driver.option_str("smm.weighting_matrix", $3); }                                  
+                   | WEIGHTING_MATRIX EQUAL IDENTITY_MATRIX
+                     { driver.option_str("smm.weighting_matrix", $3); }
+                   | WEIGHTING_MATRIX EQUAL DIAGONAL
+                     { driver.option_str("smm.weighting_matrix", $3); }
+                   | WEIGHTING_MATRIX EQUAL filename
+                     { driver.option_str("smm.weighting_matrix", $3); }
+                   ;
+o_gmm_penalized_estimator : PENALIZED_ESTIMATOR { driver.option_num("gmm.penalized_estimator", "1"); };
+o_smm_penalized_estimator : PENALIZED_ESTIMATOR { driver.option_num("smm.penalized_estimator", "1"); };
+o_gmm_verbose : VERBOSE { driver.option_num("gmm.verbose", "1"); };
+o_smm_verbose : VERBOSE { driver.option_num("smm.verbose", "1"); };
+
+o_smm_simulation_multiple : SIMULATION_MULTIPLE EQUAL INT_NUMBER { driver.option_num("smm.simulation_multiple", $3); };
+o_smm_drop : DROP EQUAL INT_NUMBER { driver.option_num("smm.drop", $3); };
+o_smm_seed : SEED EQUAL INT_NUMBER { driver.option_num("smm.seed", $3); };
+o_smm_bounded_shock_support : BOUNDED_SHOCK_SUPPORT { driver.option_num("smm.bounded_support", "1"); };
+
+o_analytical_girf : ANALYTICAL_GIRF { driver.option_num("irf_opt.analytical_GIRF", "1"); };
+o_irf_in_percent : IRF_IN_PERCENT { driver.option_num("irf_opt.percent", "1"); };
+o_emas_girf : EMAS_GIRF { driver.option_num("irf_opt.ergodic_mean_irf", "1"); };
+o_emas_drop : EMAS_DROP EQUAL INT_NUMBER { driver.option_num("irf_opt.EM.drop", $3); };
+o_emas_tolf : EMAS_TOLF EQUAL non_negative_number { driver.option_num("irf_opt.EM.tolf", $3); };
+o_emas_max_iter : EMAS_MAX_ITER EQUAL INT_NUMBER { driver.option_num("irf_opt.EM.iter", $3); };
+
 range : symbol ':' symbol
         {
           $1->append(":");
diff --git a/DynareFlex.ll b/DynareFlex.ll
index 034bda4aed15d0e1fafdde452e7c7862e10e19bf..668db31e45fe1b61a4f20dcfd106ee5d575b7387 100644
--- a/DynareFlex.ll
+++ b/DynareFlex.ll
@@ -168,6 +168,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
 <INITIAL>ms_variance_decomposition {BEGIN DYNARE_STATEMENT; return token::MS_VARIANCE_DECOMPOSITION;}
 <INITIAL>conditional_forecast {BEGIN DYNARE_STATEMENT; return token::CONDITIONAL_FORECAST;}
 <INITIAL>plot_conditional_forecast {BEGIN DYNARE_STATEMENT; return token::PLOT_CONDITIONAL_FORECAST;}
+<INITIAL>gmm_estimation {BEGIN DYNARE_STATEMENT; return token::GMM_ESTIMATION;}
+<INITIAL>smm_estimation {BEGIN DYNARE_STATEMENT; return token::SMM_ESTIMATION;}
 
 <INITIAL>markov_switching {BEGIN DYNARE_STATEMENT; return token::MARKOV_SWITCHING;}
 <INITIAL>svar {BEGIN DYNARE_STATEMENT; return token::SVAR;}
@@ -212,6 +214,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>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;}
+<INITIAL>generate_irfs {BEGIN DYNARE_BLOCK; return token::GENERATE_IRFS;}
 
  /* For the semicolon after an "end" keyword */
 <INITIAL>; {return Dynare::parser::token_type (yytext[0]);}
@@ -640,6 +643,30 @@ 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>silent_optimizer {return token::SILENT_OPTIMIZER;}
 <DYNARE_STATEMENT>lmmcp {return token::LMMCP;}
 <DYNARE_STATEMENT>occbin {return token::OCCBIN;}
+<DYNARE_STATEMENT>centered_moments {return token::CENTERED_MOMENTS; }
+<DYNARE_STATEMENT>autolag {return token::AUTOLAG; }
+<DYNARE_STATEMENT>recursive_order_estimation {return token::RECURSIVE_ORDER_ESTIMATION; }
+<DYNARE_STATEMENT>bartlett_kernel_lag {return token::BARTLETT_KERNEL_LAG; }
+<DYNARE_STATEMENT>optimal {
+  yylval->string_val = new string(yytext);
+  return token::OPTIMAL;
+}
+<DYNARE_STATEMENT>diagonal  {
+  yylval->string_val = new string(yytext);
+  return token::DIAGONAL;
+}
+<DYNARE_STATEMENT>weighting_matrix {return token::WEIGHTING_MATRIX; }
+<DYNARE_STATEMENT>penalized_estimator {return token::PENALIZED_ESTIMATOR; }
+<DYNARE_STATEMENT>verbose {return token::VERBOSE; }
+<DYNARE_STATEMENT>simulation_multiple {return token::SIMULATION_MULTIPLE; }
+<DYNARE_STATEMENT>seed {return token::SEED; }
+<DYNARE_STATEMENT>bounded_shock_support {return token::BOUNDED_SHOCK_SUPPORT; }
+<DYNARE_STATEMENT>analytical_girf {return token::ANALYTICAL_GIRF; }
+<DYNARE_STATEMENT>irf_in_percent {return token::IRF_IN_PERCENT; }
+<DYNARE_STATEMENT>emas_girf {return token::EMAS_GIRF; }
+<DYNARE_STATEMENT>emas_drop {return token::EMAS_DROP; }
+<DYNARE_STATEMENT>emas_tolf {return token::EMAS_TOLF; }
+<DYNARE_STATEMENT>emas_max_iter {return token::EMAS_MAX_ITER; }
 
 <DYNARE_STATEMENT>[\$][^$]*[\$] {
   strtok(yytext+1, "$");
@@ -714,6 +741,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>irf_plot_threshold {return token::IRF_PLOT_THRESHOLD;}
 <DYNARE_STATEMENT>no_homotopy {return token::NO_HOMOTOPY;}
 
+<DYNARE_BLOCK>stderr_multiples {return token::STDERR_MULTIPLES;}
+<DYNARE_BLOCK>diagonal_only {return token::DIAGONAL_ONLY;}
 <DYNARE_BLOCK>equation {return token::EQUATION;}
 <DYNARE_BLOCK>exclusion {return token::EXCLUSION;}
 <DYNARE_BLOCK>lag {return token::LAG;}
diff --git a/DynareMain.cc b/DynareMain.cc
index d37b2314d061060b27ab4601d5b5d6dc7aa6edb7..eb2891a6e30235df2d17a4e08e2714511a84033c 100644
--- a/DynareMain.cc
+++ b/DynareMain.cc
@@ -46,6 +46,7 @@ void main2(stringstream &in, string &basename, bool debug, bool clear_all, bool
            , bool cygwin, bool msvc, bool mingw
 #endif
            , JsonOutputPointType json, JsonFileOutputType json_output_mode, bool onlyjson, bool jsonderivsimple
+           , bool nopreprocessoroutput
            );
 
 void main1(string &modfile, string &basename, string &modfiletxt, bool debug, bool save_macro, string &save_macro_file,
@@ -120,6 +121,7 @@ main(int argc, char **argv)
   bool onlyjson = false;
   bool jsonderivsimple = false;
   LanguageOutputType language = matlab;
+  bool nopreprocessoroutput = false;
 
   // Parse options
   for (int arg = 2; arg < argc; arg++)
@@ -303,6 +305,8 @@ main(int argc, char **argv)
         json_output_mode = standardout;
       else if (!strcmp(argv[arg], "onlyjson"))
         onlyjson = true;
+      else if (!strcmp(argv[arg], "nopreprocessoroutput"))
+        nopreprocessoroutput = true;
       else if (!strcmp(argv[arg], "jsonderivsimple"))
         jsonderivsimple = true;
       else if (strlen(argv[arg]) >= 4 && !strncmp(argv[arg], "json", 4))
@@ -333,8 +337,9 @@ main(int argc, char **argv)
         }
     }
 
-  cout << "Starting Dynare (version " << PACKAGE_VERSION << ")." << endl
-       << "Starting preprocessing of the model file ..." << endl;
+  if (!nopreprocessoroutput)
+    cout << "Starting Dynare (version " << PACKAGE_VERSION << ")." << endl
+         << "Starting preprocessing of the model file ..." << endl;
 
   // Construct basename (i.e. remove file extension if there is one)
   string basename = argv[1];
@@ -397,7 +402,7 @@ main(int argc, char **argv)
 #if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__)
         , cygwin, msvc, mingw
 #endif
-        , json, json_output_mode, onlyjson, jsonderivsimple
+        , json, json_output_mode, onlyjson, jsonderivsimple, nopreprocessoroutput
         );
 
   return EXIT_SUCCESS;
diff --git a/DynareMain2.cc b/DynareMain2.cc
index 6f0e113917835db3c9d1263904e38398ae7db017..d61df45b5039433290c4a67cc0e50dffd0c42276 100644
--- a/DynareMain2.cc
+++ b/DynareMain2.cc
@@ -35,6 +35,7 @@ main2(stringstream &in, string &basename, bool debug, bool clear_all, bool clear
       , bool cygwin, bool msvc, bool mingw
 #endif
       , JsonOutputPointType json, JsonFileOutputType json_output_mode, bool onlyjson, bool jsonderivsimple
+      , bool nopreprocessoroutput
       )
 {
   ParsingDriver p(warnings, nostrict);
@@ -42,38 +43,40 @@ main2(stringstream &in, string &basename, bool debug, bool clear_all, bool clear
   // Do parsing and construct internal representation of mod file
   ModFile *mod_file = p.parse(in, debug);
   if (json == parsing)
-    mod_file->writeJsonOutput(basename, json, json_output_mode, onlyjson);
+    mod_file->writeJsonOutput(basename, json, json_output_mode, onlyjson, nopreprocessoroutput);
 
   // Run checking pass
   mod_file->checkPass(nostrict, stochastic);
   if (json == checkpass)
-    mod_file->writeJsonOutput(basename, json, json_output_mode, onlyjson);
+    mod_file->writeJsonOutput(basename, json, json_output_mode, onlyjson, nopreprocessoroutput);
 
   // Perform transformations on the model (creation of auxiliary vars and equations)
-  mod_file->transformPass(nostrict, stochastic, compute_xrefs || json == transformpass);
+  mod_file->transformPass(nostrict, stochastic, compute_xrefs || json == transformpass, nopreprocessoroutput);
   if (json == transformpass)
-    mod_file->writeJsonOutput(basename, json, json_output_mode, onlyjson);
+    mod_file->writeJsonOutput(basename, json, json_output_mode, onlyjson, nopreprocessoroutput);
 
   // Evaluate parameters initialization, initval, endval and pounds
-  mod_file->evalAllExpressions(warn_uninit);
+  mod_file->evalAllExpressions(warn_uninit, nopreprocessoroutput);
 
   // Do computations
-  mod_file->computingPass(no_tmp_terms, output_mode, params_derivs_order);
+  mod_file->computingPass(no_tmp_terms, output_mode, params_derivs_order, nopreprocessoroutput);
   if (json == computingpass)
-    mod_file->writeJsonOutput(basename, json, json_output_mode, onlyjson, jsonderivsimple);
+    mod_file->writeJsonOutput(basename, json, json_output_mode, onlyjson, nopreprocessoroutput, jsonderivsimple);
 
   // Write outputs
   if (output_mode != none)
-    mod_file->writeExternalFiles(basename, output_mode, language);
+    mod_file->writeExternalFiles(basename, output_mode, language, nopreprocessoroutput);
   else
     mod_file->writeOutputFiles(basename, clear_all, clear_global, no_log, no_warn, console, nograph,
                                nointeractive, config_file, check_model_changes, minimal_workspace, compute_xrefs
 #if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__)
                                , cygwin, msvc, mingw
 #endif
+                               , nopreprocessoroutput
                                );
 
   delete mod_file;
 
-  cout << "Preprocessing completed." << endl;
+  if (!nopreprocessoroutput)
+    cout << "Preprocessing completed." << endl;
 }
diff --git a/ModFile.cc b/ModFile.cc
index 2ab5a4b787d3e9f425dc13f75bafce204d5047de..416de5043fb61022b88c9e3c81c24bb2dfa0d9ba 100644
--- a/ModFile.cc
+++ b/ModFile.cc
@@ -53,9 +53,10 @@ ModFile::~ModFile()
 }
 
 void
-ModFile::evalAllExpressions(bool warn_uninit)
+ModFile::evalAllExpressions(bool warn_uninit, const bool nopreprocessoroutput)
 {
-  cout << "Evaluating expressions...";
+  if (!nopreprocessoroutput)
+    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++)
@@ -76,7 +77,8 @@ ModFile::evalAllExpressions(bool warn_uninit)
   // Evaluate model local variables
   dynamic_model.fillEvalContext(global_eval_context);
 
-  cout << "done" << endl;
+  if (!nopreprocessoroutput)
+    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++)
@@ -340,7 +342,7 @@ ModFile::checkPass(bool nostrict, bool stochastic)
 }
 
 void
-ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs)
+ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const bool nopreprocessoroutput)
 {
   // Save the original model (must be done before any model transformations by preprocessor)
   // - except adl and diff which we always want expanded
@@ -408,7 +410,7 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs)
       if (linear)
         dynamic_model.cloneDynamic(orig_ramsey_dynamic_model);
       dynamic_model.cloneDynamic(ramsey_FOC_equations_dynamic_model);
-      ramsey_FOC_equations_dynamic_model.computeRamseyPolicyFOCs(*planner_objective);
+      ramsey_FOC_equations_dynamic_model.computeRamseyPolicyFOCs(*planner_objective, nopreprocessoroutput);
       ramsey_FOC_equations_dynamic_model.replaceMyEquations(dynamic_model);
       mod_file_struct.ramsey_eq_nbr = dynamic_model.equation_number() - mod_file_struct.orig_eq_nbr;
     }
@@ -517,13 +519,14 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs)
       exit(EXIT_FAILURE);
     }
 
-  if (!mod_file_struct.ramsey_model_present)
-    cout << "Found " << dynamic_model.equation_number() << " equation(s)." << endl;
-  else
-    {
-      cout << "Found " << mod_file_struct.orig_eq_nbr  << " equation(s)." << endl;
-      cout << "Found " << dynamic_model.equation_number() << " FOC equation(s) for Ramsey Problem." << endl;
-    }
+  if (!nopreprocessoroutput)
+    if (!mod_file_struct.ramsey_model_present)
+      cout << "Found " << dynamic_model.equation_number() << " equation(s)." << endl;
+    else
+      {
+        cout << "Found " << mod_file_struct.orig_eq_nbr  << " equation(s)." << endl;
+        cout << "Found " << dynamic_model.equation_number() << " FOC equation(s) for Ramsey Problem." << endl;
+      }
 
   if (symbol_table.exists("dsge_prior_weight"))
     if (mod_file_struct.bayesian_irf_present)
@@ -545,7 +548,7 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs)
 }
 
 void
-ModFile::computingPass(bool no_tmp_terms, FileOutputType output, int params_derivs_order)
+ModFile::computingPass(bool no_tmp_terms, FileOutputType output, int params_derivs_order, const bool nopreprocessoroutput)
 {
   // Mod file may have no equation (for example in a standalone BVAR estimation)
   if (dynamic_model.equation_number() > 0)
@@ -569,7 +572,7 @@ ModFile::computingPass(bool no_tmp_terms, FileOutputType output, int params_deri
           if (mod_file_struct.identification_present || mod_file_struct.estimation_analytic_derivation)
             paramsDerivsOrder = params_derivs_order;
           static_model.computingPass(global_eval_context, no_tmp_terms, static_hessian,
-                                     false, paramsDerivsOrder, block, byte_code);
+                                     false, paramsDerivsOrder, block, byte_code, nopreprocessoroutput);
         }
       // Set things to compute for dynamic model
       if (mod_file_struct.perfect_foresight_solver_present || mod_file_struct.check_present
@@ -579,7 +582,7 @@ ModFile::computingPass(bool no_tmp_terms, FileOutputType output, int params_deri
           || mod_file_struct.calib_smoother_present)
         {
           if (mod_file_struct.perfect_foresight_solver_present)
-            dynamic_model.computingPass(true, false, false, none, global_eval_context, no_tmp_terms, block, use_dll, byte_code);
+            dynamic_model.computingPass(true, false, false, none, global_eval_context, no_tmp_terms, block, use_dll, byte_code, nopreprocessoroutput);
           else
             {
               if (mod_file_struct.stoch_simul_present
@@ -604,13 +607,13 @@ ModFile::computingPass(bool no_tmp_terms, FileOutputType output, int params_deri
               int paramsDerivsOrder = 0;
               if (mod_file_struct.identification_present || mod_file_struct.estimation_analytic_derivation)
                 paramsDerivsOrder = params_derivs_order;
-              dynamic_model.computingPass(true, hessian, thirdDerivatives, paramsDerivsOrder, global_eval_context, no_tmp_terms, block, use_dll, byte_code);
+              dynamic_model.computingPass(true, hessian, thirdDerivatives, paramsDerivsOrder, global_eval_context, no_tmp_terms, block, use_dll, byte_code, nopreprocessoroutput);
               if (linear && mod_file_struct.ramsey_model_present)
-                orig_ramsey_dynamic_model.computingPass(true, true, false, paramsDerivsOrder, global_eval_context, no_tmp_terms, block, use_dll, byte_code);
+                orig_ramsey_dynamic_model.computingPass(true, true, false, paramsDerivsOrder, global_eval_context, no_tmp_terms, block, use_dll, byte_code, nopreprocessoroutput);
             }
         }
       else // No computing task requested, compute derivatives up to 2nd order by default
-        dynamic_model.computingPass(true, true, false, none, global_eval_context, no_tmp_terms, block, use_dll, byte_code);
+        dynamic_model.computingPass(true, true, false, none, global_eval_context, no_tmp_terms, block, use_dll, byte_code, nopreprocessoroutput);
 
       if ((linear && !mod_file_struct.ramsey_model_present && !dynamic_model.checkHessianZero())
           || (linear && mod_file_struct.ramsey_model_present && !orig_ramsey_dynamic_model.checkHessianZero()))
@@ -646,6 +649,7 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo
 #if defined(_WIN32) || defined(__CYGWIN32__)
                           , bool cygwin, bool msvc, bool mingw
 #endif
+                          , const bool nopreprocessoroutput
                           ) const
 {
   ofstream mOutputFile;
@@ -718,7 +722,8 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo
   if (param_used_with_lead_lag)
     mOutputFile << "M_.parameter_used_with_lead_lag = true;" << endl;
 
-  cout << "Processing outputs ..." << endl;
+  if (!nopreprocessoroutput)
+    cout << "Processing outputs ..." << endl;
 
   symbol_table.writeOutput(mOutputFile);
 
@@ -960,11 +965,12 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo
       steady_state_model.writeSteadyStateFile(basename, mod_file_struct.ramsey_model_present, false);
     }
 
-  cout << "done" << endl;
+  if (!nopreprocessoroutput)
+    cout << "done" << endl;
 }
 
 void
-ModFile::writeExternalFiles(const string &basename, FileOutputType output, LanguageOutputType language) const
+ModFile::writeExternalFiles(const string &basename, FileOutputType output, LanguageOutputType language, const bool nopreprocessoroutput) const
 {
   switch (language)
     {
@@ -975,7 +981,7 @@ ModFile::writeExternalFiles(const string &basename, FileOutputType output, Langu
       writeExternalFilesCC(basename, output);
       break;
     case julia:
-      writeExternalFilesJulia(basename, output);
+      writeExternalFilesJulia(basename, output, nopreprocessoroutput);
       break;
     default:
       cerr << "This case shouldn't happen. Contact the authors of Dynare" << endl;
@@ -1193,7 +1199,7 @@ ModFile::writeModelCC(const string &basename) const
 }
 
 void
-ModFile::writeExternalFilesJulia(const string &basename, FileOutputType output) const
+ModFile::writeExternalFilesJulia(const string &basename, FileOutputType output, const bool nopreprocessoroutput) const
 {
   ofstream jlOutputFile;
   if (basename.size())
@@ -1270,7 +1276,8 @@ ModFile::writeExternalFilesJulia(const string &basename, FileOutputType output)
     jlOutputFile << "model_.h = zeros(Float64, 1, 1)" << endl
                  << "model_.correlation_matrix_me = ones(Float64, 1, 1)" << endl;
 
-  cout << "Processing outputs ..." << endl;
+  if (!nopreprocessoroutput)
+    cout << "Processing outputs ..." << endl;
   symbol_table.writeJuliaOutput(jlOutputFile);
 
   if (dynamic_model.equation_number() > 0)
@@ -1314,11 +1321,12 @@ ModFile::writeExternalFilesJulia(const string &basename, FileOutputType output)
                << "end" << endl
                << "end" << endl;
   jlOutputFile.close();
-  cout << "done" << endl;
+  if (!nopreprocessoroutput)
+    cout << "done" << endl;
 }
 
 void
-ModFile::writeJsonOutput(const string &basename, JsonOutputPointType json, JsonFileOutputType json_output_mode, bool onlyjson, bool jsonderivsimple)
+ModFile::writeJsonOutput(const string &basename, JsonOutputPointType json, JsonFileOutputType json_output_mode, bool onlyjson, const bool nopreprocessoroutput, bool jsonderivsimple)
 {
   if (json == nojson)
     return;
@@ -1342,24 +1350,25 @@ ModFile::writeJsonOutput(const string &basename, JsonOutputPointType json, JsonF
     cout << "}" << endl
          << "//-- END JSON --// " << endl;
 
-  switch (json)
-    {
-    case parsing:
-      cout << "JSON written after Parsing step." << endl;
-      break;
-    case checkpass:
-      cout << "JSON written after Check step." << endl;
-      break;
-    case transformpass:
-      cout << "JSON written after Transform step." << endl;
-      break;
-    case computingpass:
-      cout << "JSON written after Computing step." << endl;
-      break;
-    case nojson:
-      cerr << "ModFile::writeJsonOutput: should not arrive here." << endl;
-      exit(EXIT_FAILURE);
-    }
+  if (!nopreprocessoroutput)
+    switch (json)
+      {
+      case parsing:
+        cout << "JSON written after Parsing step." << endl;
+        break;
+      case checkpass:
+        cout << "JSON written after Check step." << endl;
+        break;
+      case transformpass:
+        cout << "JSON written after Transform step." << endl;
+        break;
+      case computingpass:
+        cout << "JSON written after Computing step." << endl;
+        break;
+      case nojson:
+        cerr << "ModFile::writeJsonOutput: should not arrive here." << endl;
+        exit(EXIT_FAILURE);
+      }
 
   if (onlyjson)
     exit(EXIT_SUCCESS);
diff --git a/ModFile.hh b/ModFile.hh
index 216542cbfa14c212734e94a2dc37fbf20438c945..ac678b5b52ba79970f086d25b72a0c50878e3410 100644
--- a/ModFile.hh
+++ b/ModFile.hh
@@ -128,17 +128,17 @@ public:
   void addStatementAtFront(Statement *st);
   //! Evaluate all the statements
   /*! \param warn_uninit Should a warning be displayed for uninitialized endogenous/exogenous/parameters ? */
-  void evalAllExpressions(bool warn_uninit);
+  void evalAllExpressions(bool warn_uninit, const bool nopreprocessoroutput);
   //! Do some checking and fills mod_file_struct
   /*! \todo add check for number of equations and endogenous if ramsey_policy is present */
   void checkPass(bool nostrict, bool stochastic);
   //! Perform some transformations on the model (creation of auxiliary vars and equations)
   /*! \param compute_xrefs if true, equation cross references will be computed */
-  void transformPass(bool nostrict, bool stochastic, bool compute_xrefs);
+  void transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const bool nopreprocessoroutput);
   //! Execute computations
   /*! \param no_tmp_terms if true, no temporary terms will be computed in the static and dynamic files */
   /*! \param params_derivs_order compute this order of derivs wrt parameters */
-  void computingPass(bool no_tmp_terms, FileOutputType output, int params_derivs_order);
+  void computingPass(bool no_tmp_terms, FileOutputType output, int params_derivs_order, const bool nopreprocessoroutput);
   //! Writes Matlab/Octave output files
   /*!
     \param basename The base name used for writing output files. Should be the name of the mod file without its extension
@@ -157,11 +157,12 @@ public:
 #if defined(_WIN32) || defined(__CYGWIN32__) || defined(__MINGW32__)
                         , bool cygwin, bool msvc, bool mingw
 #endif
+                        , const bool nopreprocessoroutput
                         ) const;
-  void writeExternalFiles(const string &basename, FileOutputType output, LanguageOutputType language) const;
+  void writeExternalFiles(const string &basename, FileOutputType output, LanguageOutputType language, const bool nopreprocessoroutput) const;
   void writeExternalFilesC(const string &basename, FileOutputType output) const;
   void writeExternalFilesCC(const string &basename, FileOutputType output) const;
-  void writeExternalFilesJulia(const string &basename, FileOutputType output) const;
+  void writeExternalFilesJulia(const string &basename, FileOutputType output, const bool nopreprocessoroutput) const;
   //! Writes C output files only => No further Matlab processing
   void writeCOutputFiles(const string &basename) const;
   void writeModelC(const string &basename) const;
@@ -174,7 +175,7 @@ public:
   //! Initially created to enable Julia to work with .mod files
   //! Potentially outputs ModFile after the various parts of processing (parsing, checkPass, transformPass, computingPass)
   //! Allows user of other host language platforms (python, fortran, etc) to provide support for dynare .mod files
-  void writeJsonOutput(const string &basename, JsonOutputPointType json, JsonFileOutputType json_output_mode, bool onlyjson, bool jsonderivsimple = false);
+  void writeJsonOutput(const string &basename, JsonOutputPointType json, JsonFileOutputType json_output_mode, bool onlyjson, const bool nopreprocessoroutput, bool jsonderivsimple = false);
 };
 
 #endif // ! MOD_FILE_HH
diff --git a/ParsingDriver.cc b/ParsingDriver.cc
index fbade4c562cfa192870bd59659d804a25d43b42f..5d2639f009c403732fd024944f4b6f55cb2d7706 100644
--- a/ParsingDriver.cc
+++ b/ParsingDriver.cc
@@ -746,6 +746,46 @@ ParsingDriver::homotopy_val(string *name, expr_t val1, expr_t val2)
   delete name;
 }
 
+void
+ParsingDriver::end_generate_irfs()
+{
+  mod_file->addStatement(new GenerateIRFsStatement(options_list, generate_irf_names, generate_irf_elements));
+
+  generate_irf_elements.clear();
+  generate_irf_names.clear();
+  options_list.clear();
+}
+
+void
+ParsingDriver::add_generate_irfs_element(string *name)
+{
+  for (vector<string>::const_iterator it = generate_irf_names.begin();
+       it != generate_irf_names.end(); it++)
+    if (*it == *name)
+      error("Names in the generate_irfs block must be unique but you entered '"
+            + *name + "' more than once.");
+
+  generate_irf_names.push_back(*name);
+  generate_irf_elements.push_back(generate_irf_exos);
+
+  generate_irf_exos.clear();
+
+  delete name;
+}
+
+void
+ParsingDriver::add_generate_irfs_exog_element(string *exo, string *value)
+{
+  check_symbol_is_exogenous(exo);
+  if (generate_irf_exos.find(*exo) != generate_irf_exos.end())
+    error("You have set the exogenous variable " + *exo + " twice.");
+
+  generate_irf_exos[*exo] = atof(value->c_str());
+
+  delete exo;
+  delete value;
+}
+
 void
 ParsingDriver::forecast()
 {
@@ -1809,6 +1849,21 @@ ParsingDriver::check_symbol_is_endogenous_or_exogenous(string *name)
     }
 }
 
+void
+ParsingDriver::check_symbol_is_exogenous(string *name)
+{
+  check_symbol_existence(*name);
+  int symb_id = mod_file->symbol_table.getID(*name);
+  switch (mod_file->symbol_table.getType(symb_id))
+    {
+    case eExogenous:
+    case eExogenousDet:
+      break;
+    default:
+      error(*name + " is not exogenous.");
+    }
+}
+
 void
 ParsingDriver::set_std_prior(string *name, string *subsample_name)
 {
@@ -3221,6 +3276,22 @@ ParsingDriver::perfect_foresight_solver()
   options_list.clear();
 }
 
+void
+ParsingDriver::gmm_estimation()
+{
+  mod_file->addStatement(new GMMEstimationStatement(symbol_list, options_list));
+  symbol_list.clear();
+  options_list.clear();
+}
+
+void
+ParsingDriver::smm_estimation()
+{
+  mod_file->addStatement(new SMMEstimationStatement(symbol_list, options_list));
+  symbol_list.clear();
+  options_list.clear();
+}
+
 void
 ParsingDriver::prior_posterior_function(bool prior_func)
 {
diff --git a/ParsingDriver.hh b/ParsingDriver.hh
index 252d79ee4169f17f4d487e9b0cc6cd531269459e..e7f54b0a9a21cccee2c82071c6262b99ddfec1cb 100644
--- a/ParsingDriver.hh
+++ b/ParsingDriver.hh
@@ -93,6 +93,9 @@ private:
   //! Checks that a given symbol exists and is a endogenous or exogenous, and stops with an error message if it isn't
   void check_symbol_is_endogenous_or_exogenous(string *name);
 
+  //! Checks that a given symbol exists and is a exogenous, and stops with an error message if it isn't
+  void check_symbol_is_exogenous(string *name);
+
   //! Checks for symbol existence in model block. If it doesn't exist, an error message is stored to be printed at
   //! the end of the model block
   void check_symbol_existence_in_model_block(const string &name);
@@ -196,7 +199,10 @@ private:
       Ri_TYPE
     };
   SvarRestrictionType svar_restriction_type;
-
+  //! Temporary storage for generate_irfs
+  vector<string> generate_irf_names;
+  vector<map<string, double> > generate_irf_elements;
+  map<string, double> generate_irf_exos;
   //! Temporary storage for argument list of external function
   stack<vector<expr_t> >  stack_external_function_args;
   //! Temporary storage for parameters in joint prior statement
@@ -553,6 +559,10 @@ public:
   void add_lower_cholesky();
   //! Svar_Global_Identification_Check Statement
   void add_svar_global_identification_check();
+  //! generate_irfs Block
+  void end_generate_irfs();
+  void add_generate_irfs_element(string *name);
+  void add_generate_irfs_exog_element(string *exo, string *value);
   //! Forecast Statement
   void forecast();
   void set_trends();
@@ -810,6 +820,10 @@ public:
   void add_VAR_covariance_pair_restriction(string *name11, string *name12, string *name21, string *name22);
   //! Runs VAR estimation process
   void run_var_estimation();
+  //! GMM Estimation statement
+  void gmm_estimation();
+  //! SMM Estimation statement
+  void smm_estimation();
 };
 
 #endif // ! PARSING_DRIVER_HH
diff --git a/StaticModel.cc b/StaticModel.cc
index 37133f8a3de9d08e996181593c6b69867ce89f66..ea6ed05e19bf67a078e3cb9cd48f40b538cad9eb 100644
--- a/StaticModel.cc
+++ b/StaticModel.cc
@@ -1047,7 +1047,7 @@ StaticModel::collect_first_order_derivatives_endogenous()
 }
 
 void
-StaticModel::computingPass(const eval_context_t &eval_context, bool no_tmp_terms, bool hessian, bool thirdDerivatives, int paramsDerivsOrder, bool block, bool bytecode)
+StaticModel::computingPass(const eval_context_t &eval_context, bool no_tmp_terms, bool hessian, bool thirdDerivatives, int paramsDerivsOrder, bool block, bool bytecode, const bool nopreprocessoroutput)
 {
   initializeVariablesAndEquations();
 
@@ -1077,27 +1077,31 @@ StaticModel::computingPass(const eval_context_t &eval_context, bool no_tmp_terms
     }
 
   // Launch computations
-  cout << "Computing static model derivatives:" << endl
-       << " - order 1" << endl;
+  if (!nopreprocessoroutput)
+    cout << "Computing static model derivatives:" << endl
+         << " - order 1" << endl;
   first_derivatives.clear();
 
   computeJacobian(vars);
 
   if (hessian)
     {
-      cout << " - order 2" << endl;
+      if (!nopreprocessoroutput)
+        cout << " - order 2" << endl;
       computeHessian(vars);
     }
 
   if (thirdDerivatives)
     {
-      cout << " - order 3" << endl;
+      if (!nopreprocessoroutput)
+        cout << " - order 3" << endl;
       computeThirdDerivatives(vars);
     }
 
   if (paramsDerivsOrder > 0)
     {
-      cout << " - derivatives of Jacobian/Hessian w.r. to parameters" << endl;
+      if (!nopreprocessoroutput)
+        cout << " - derivatives of Jacobian/Hessian w.r. to parameters" << endl;
       computeParamsDerivatives(paramsDerivsOrder);
 
       if (!no_tmp_terms)
@@ -1122,7 +1126,8 @@ StaticModel::computingPass(const eval_context_t &eval_context, bool no_tmp_terms
 
       equation_type_and_normalized_equation = equationTypeDetermination(first_order_endo_derivatives, variable_reordered, equation_reordered, mfs);
 
-      cout << "Finding the optimal block decomposition of the model ...\n";
+      if (!nopreprocessoroutput)
+        cout << "Finding the optimal block decomposition of the model ...\n";
 
       lag_lead_vector_t equation_lag_lead, variable_lag_lead;
 
@@ -1550,6 +1555,7 @@ StaticModel::writeStaticModel(ostream &StaticOutput, bool use_dll, bool julia) c
 
       StaticOutput << "#=" << endl << comments.str() << "=#" << endl
                    << "  @assert size(g2) == (" << equations.size() << ", " << g2ncols << ")" << endl
+                   << "  fill!(g2, 0.0)" << endl
                    << "  static!(y, x, params, residual, g1)" << endl;
       if (second_derivatives.size())
         StaticOutput << model_local_vars_output.str()
@@ -1573,6 +1579,7 @@ StaticModel::writeStaticModel(ostream &StaticOutput, bool use_dll, bool julia) c
 
       StaticOutput << "#=" << endl << comments.str() << "=#" << endl
                    << "  @assert size(g3) == (" << nrows << ", " << ncols << ")" << endl
+                   << "  fill!(g3, 0.0)" << endl
                    << "  static!(y, x, params, residual, g1, g2)" << endl;
       if (third_derivatives.size())
         StaticOutput << model_local_vars_output.str()
diff --git a/StaticModel.hh b/StaticModel.hh
index 09abf2067c52f27166df8ed6e389117e429d9c0c..68b6db3d87843fa4c834677e97380529f3a47af4 100644
--- a/StaticModel.hh
+++ b/StaticModel.hh
@@ -161,7 +161,7 @@ public:
     \param hessian whether 2nd derivatives w.r. to exo, exo_det and endo should be computed
     \param paramsDerivsOrder order of derivatives w.r. to a pair (endo/exo/exo_det, parameter) to be computed
   */
-  void computingPass(const eval_context_t &eval_context, bool no_tmp_terms, bool hessian, bool thirdDerivatices, int paramsDerivsOrder, bool block, bool bytecode);
+  void computingPass(const eval_context_t &eval_context, bool no_tmp_terms, bool hessian, bool thirdDerivatices, int paramsDerivsOrder, bool block, bool bytecode, const bool nopreprocessoroutput);
 
   //! Adds informations for simulation in a binary file for a block decomposed model
   void Write_Inf_To_Bin_File_Block(const string &static_basename, const string &bin_basename, const int &num,