diff --git a/ComputingTasks.cc b/ComputingTasks.cc
index f12c40867588b3a1171e23e7683a9e20afd28c16..db2ac6249cbbf16f263cf54b2e3e435e3b63df86 100644
--- a/ComputingTasks.cc
+++ b/ComputingTasks.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003-2016 Dynare Team
+ * Copyright (C) 2003-2017 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -50,6 +50,18 @@ SteadyStatement::writeOutput(ostream &output, const string &basename, bool minim
   output << "steady;" << endl;
 }
 
+void
+SteadyStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"steady\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 CheckStatement::CheckStatement(const OptionsList &options_list_arg) :
   options_list(options_list_arg)
 {
@@ -68,6 +80,18 @@ CheckStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidatio
   mod_file_struct.check_present = true;
 }
 
+void
+CheckStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"check\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 ModelInfoStatement::ModelInfoStatement(const OptionsList &options_list_arg) :
   options_list(options_list_arg)
 {
@@ -86,6 +110,18 @@ ModelInfoStatement::writeOutput(ostream &output, const string &basename, bool mi
   output << "model_info();" << endl;
 }
 
+void
+ModelInfoStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"model_info\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 SimulStatement::SimulStatement(const OptionsList &options_list_arg) :
   options_list(options_list_arg)
 {
@@ -105,6 +141,18 @@ SimulStatement::writeOutput(ostream &output, const string &basename, bool minima
          << "perfect_foresight_solver;" << endl;
 }
 
+void
+SimulStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"simul\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 PerfectForesightSetupStatement::PerfectForesightSetupStatement(const OptionsList &options_list_arg) :
   options_list(options_list_arg)
 {
@@ -117,6 +165,18 @@ PerfectForesightSetupStatement::writeOutput(ostream &output, const string &basen
   output << "perfect_foresight_setup;" << endl;
 }
 
+void
+PerfectForesightSetupStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"perfect_foresight_setup\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 PerfectForesightSolverStatement::PerfectForesightSolverStatement(const OptionsList &options_list_arg) :
   options_list(options_list_arg)
 {
@@ -138,6 +198,18 @@ PerfectForesightSolverStatement::writeOutput(ostream &output, const string &base
   output << "perfect_foresight_solver;" << endl;
 }
 
+void
+PerfectForesightSolverStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"perfect_foresight_solver\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 PriorPosteriorFunctionStatement::PriorPosteriorFunctionStatement(const bool prior_func_arg,
                                                                  const OptionsList &options_list_arg) :
   prior_func(prior_func_arg),
@@ -171,6 +243,21 @@ PriorPosteriorFunctionStatement::writeOutput(ostream &output, const string &base
          << "'" << type << "');" << endl;
 }
 
+void
+PriorPosteriorFunctionStatement::writeJsonOutput(ostream &output) const
+{
+  string type = "posterior";
+  if (prior_func)
+      type = "prior";
+  output << "{\"statementName\": \"prior_posterior_function\", \"type\": \"" << type << "\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 StochSimulStatement::StochSimulStatement(const SymbolList &symbol_list_arg,
                                          const OptionsList &options_list_arg) :
   symbol_list(symbol_list_arg),
@@ -227,6 +314,23 @@ StochSimulStatement::writeOutput(ostream &output, const string &basename, bool m
   output << "info = stoch_simul(var_list_);" << endl;
 }
 
+void
+StochSimulStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"stoch_simul\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  if (!symbol_list.empty())
+    {
+      output << ", ";
+      symbol_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 ForecastStatement::ForecastStatement(const SymbolList &symbol_list_arg,
                                      const OptionsList &options_list_arg) :
   symbol_list(symbol_list_arg),
@@ -242,6 +346,23 @@ ForecastStatement::writeOutput(ostream &output, const string &basename, bool min
   output << "[oo_.forecast,info] = dyn_forecast(var_list_,M_,options_,oo_,'simul');" << endl;
 }
 
+void
+ForecastStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"forecast\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  if (!symbol_list.empty())
+    {
+      output << ", ";
+      symbol_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 RamseyModelStatement::RamseyModelStatement(const SymbolList &symbol_list_arg,
                                              const OptionsList &options_list_arg) :
   symbol_list(symbol_list_arg),
@@ -299,7 +420,20 @@ RamseyModelStatement::writeOutput(ostream &output, const string &basename, bool
   options_list.writeOutput(output);
 }
 
-RamseyConstraintsStatement::RamseyConstraintsStatement(const constraints_t &constraints_arg) :
+void
+RamseyModelStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"ramsey_model\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
+RamseyConstraintsStatement::RamseyConstraintsStatement(const SymbolTable &symbol_table_arg, const constraints_t &constraints_arg) :
+  symbol_table(symbol_table_arg),
   constraints(constraints_arg)
 {
 }
@@ -345,6 +479,43 @@ RamseyConstraintsStatement::writeOutput(ostream &output, const string &basename,
   output << "};" << endl;
 }
 
+void
+RamseyConstraintsStatement::writeJsonOutput(ostream &output) const
+{
+  deriv_node_temp_terms_t tef_terms;
+  output << "{\"statementName\": \"ramsey_constraints\""
+         << ", \"ramsey_model_constraints\": [" << endl;
+  for (RamseyConstraintsStatement::constraints_t::const_iterator it = constraints.begin(); it != constraints.end(); ++it)
+    {
+      if (it != constraints.begin())
+	output << ", ";
+      output << "{\"constraint\": \"" << symbol_table.getName(it->endo) << " ";
+      switch(it->code)
+	{
+	case oLess:
+	  output << '<';
+	  break;
+	case oGreater:
+	  output << '>';
+	  break;
+	case oLessEqual:
+	  output << "<=";
+	  break;
+	case oGreaterEqual:
+	  output << ">=";
+	  break;
+	default:
+	  cerr << "Ramsey constraints: this shouldn't happen." << endl;
+	  exit(1);
+	}
+      output << " ";
+      it->expression->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+      output << "\"}" << endl;
+    }
+  output << "]" << endl;
+  output << "}";
+}
+
 // Statement *
 // RamseyConstraintsStatement::cloneAndReindexSymbIds(DataTree &dynamic_datatree, SymbolTable &orig_symbol_table)
 // {
@@ -489,6 +660,28 @@ RamseyPolicyStatement::writeOutput(ostream &output, const string &basename, bool
          << "ramsey_policy(var_list_);" << endl;
 }
 
+void
+RamseyPolicyStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"ramsey_policy\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+      output << ", ";
+    }
+  output << "\"ramsey_policy_list\": [";
+  for (vector<string>::const_iterator it = ramsey_policy_list.begin();
+       it != ramsey_policy_list.end(); ++it)
+    {
+      if (it != ramsey_policy_list.begin())
+        output << ",";
+      output << "\"" << *it << "\"";
+    }
+  output << "]"
+         << "}";
+}
+
 DiscretionaryPolicyStatement::DiscretionaryPolicyStatement(const SymbolList &symbol_list_arg,
 							   const OptionsList &options_list_arg) :
   symbol_list(symbol_list_arg),
@@ -549,6 +742,23 @@ DiscretionaryPolicyStatement::writeOutput(ostream &output, const string &basenam
   output << "discretionary_policy(var_list_);" << endl;
 }
 
+void
+DiscretionaryPolicyStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"discretionary_policy\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  if (!symbol_list.empty())
+    {
+      output << ", ";
+      symbol_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 EstimationStatement::EstimationStatement(const SymbolList &symbol_list_arg,
                                          const OptionsList &options_list_arg) :
   symbol_list(symbol_list_arg),
@@ -654,6 +864,23 @@ EstimationStatement::writeOutput(ostream &output, const string &basename, bool m
   output << "oo_recursive_=dynare_estimation(var_list_);" << endl;
 }
 
+void
+EstimationStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"estimation\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  if (!symbol_list.empty())
+    {
+      output << ", ";
+      symbol_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 DynareSensitivityStatement::DynareSensitivityStatement(const OptionsList &options_list_arg) :
   options_list(options_list_arg)
 {
@@ -690,6 +917,18 @@ DynareSensitivityStatement::writeOutput(ostream &output, const string &basename,
   output << "dynare_sensitivity(options_gsa);" << endl;
 }
 
+void
+DynareSensitivityStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"dynare_sensitivity\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 RplotStatement::RplotStatement(const SymbolList &symbol_list_arg) :
   symbol_list(symbol_list_arg)
 {
@@ -702,6 +941,18 @@ RplotStatement::writeOutput(ostream &output, const string &basename, bool minima
   output << "rplot(var_list_);" << endl;
 }
 
+void
+RplotStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"rplot\"";
+  if (!symbol_list.empty())
+    {
+      output << ", ";
+      symbol_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 UnitRootVarsStatement::UnitRootVarsStatement(void)
 {
 }
@@ -713,6 +964,14 @@ UnitRootVarsStatement::writeOutput(ostream &output, const string &basename, bool
 	 << "options_.steadystate.nocheck = 1;" << endl;
 }
 
+void
+UnitRootVarsStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"unit_root_vars\", "
+         << "\"diffuse_filter\": 1, "
+         << "\"steady_state.nocheck\": 1}";
+}
+
 PeriodsStatement::PeriodsStatement(int periods_arg) : periods(periods_arg)
 {
 }
@@ -723,6 +982,13 @@ PeriodsStatement::writeOutput(ostream &output, const string &basename, bool mini
   output << "options_.periods = " << periods << ";" << endl;
 }
 
+void
+PeriodsStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"periods\", "
+         << "\"periods\": " << periods << "}";
+}
+
 DsampleStatement::DsampleStatement(int val1_arg) : val1(val1_arg), val2(-1)
 {
 }
@@ -740,6 +1006,14 @@ DsampleStatement::writeOutput(ostream &output, const string &basename, bool mini
     output << "dsample(" << val1 << ", " << val2 << ");" << endl;
 }
 
+void
+DsampleStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"dsample\", "
+         << "\"value1\": " << val1 << ", "
+         << "\"value2\": " << val2 << "}";
+}
+
 EstimatedParamsStatement::EstimatedParamsStatement(const vector<EstimationParams> &estim_params_list_arg,
                                                    const SymbolTable &symbol_table_arg) :
   estim_params_list(estim_params_list_arg),
@@ -870,6 +1144,55 @@ EstimatedParamsStatement::writeOutput(ostream &output, const string &basename, b
     }
 }
 
+void
+EstimatedParamsStatement::writeJsonOutput(ostream &output) const
+{
+  deriv_node_temp_terms_t tef_terms;
+  output << "{\"statementName\": \"estimated_params\", "
+         << "\"params\": [";
+  for (vector<EstimationParams>::const_iterator it = estim_params_list.begin(); it != estim_params_list.end(); it++)
+    {
+      if (it != estim_params_list.begin())
+        output << ", ";
+      output << "{";
+      switch (it->type)
+        {
+        case 1:
+          output << "\"var\": \"" << it->name << "\"";
+          break;
+        case 2:
+          output << "\"param\": \"" << it->name << "\"";
+          break;
+        case 3:
+          output << "\"var1\": \"" << it->name << "\","
+                 << "\"var2\": \"" << it->name2 << "\"";
+          break;
+        }
+
+      output << ", \"init_val\": \"";
+      it->init_val->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+      output << "\", \"lower_bound\": \"";
+      it->low_bound->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+      output << "\", \"upper_bound\": \"";
+      it->up_bound->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+      output << "\", \"prior_distribution\": "
+             << it->prior
+             << ", \"mean\": \"";
+      it->mean->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+      output << "\", \"std\": \"";
+      it->std->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+      output << "\", \"p3\": \"";
+      it->p3->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+      output << "\", \"p4\": \"";
+      it->p4->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+      output << "\", \"jscale\": \"";
+      it->jscale->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+      output << "\"}" << endl;
+    }
+  output << "]"
+         << "}";
+}
+
 EstimatedParamsInitStatement::EstimatedParamsInitStatement(const vector<EstimationParams> &estim_params_list_arg,
                                                            const SymbolTable &symbol_table_arg,
                                                            const bool use_calibration_arg) :
@@ -945,6 +1268,42 @@ EstimatedParamsInitStatement::writeOutput(ostream &output, const string &basenam
     }
 }
 
+void
+EstimatedParamsInitStatement::writeJsonOutput(ostream &output) const
+{
+  deriv_node_temp_terms_t tef_terms;
+  output << "{\"statementName\": \"estimated_params_init\"";
+
+  if (use_calibration)
+    output << ", \"use_calibration_initialization\": 1";
+
+  output << ", \"params\": [";
+  for (vector<EstimationParams>::const_iterator it = estim_params_list.begin(); it != estim_params_list.end(); it++)
+    {
+      if (it != estim_params_list.begin())
+        output << ", ";
+      output << "{";
+      switch (it->type)
+        {
+        case 1:
+          output << "\"var\": \"" << it->name << "\"";
+          break;
+        case 2:
+          output << "\"param\": \"" << it->name << "\"";
+          break;
+        case 3:
+          output << "\"var1\": \"" << it->name << "\","
+                 << "\"var2\": \"" << it->name2 << "\"";
+          break;
+        }
+      output << ", \"init_val\": \"";
+      it->init_val->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+      output << "\"}";
+    }
+  output << "]"
+         << "}";
+}
+
 EstimatedParamsBoundsStatement::EstimatedParamsBoundsStatement(const vector<EstimationParams> &estim_params_list_arg,
                                                                const SymbolTable &symbol_table_arg) :
   estim_params_list(estim_params_list_arg),
@@ -1033,6 +1392,40 @@ EstimatedParamsBoundsStatement::writeOutput(ostream &output, const string &basen
     }
 }
 
+void
+EstimatedParamsBoundsStatement::writeJsonOutput(ostream &output) const
+{
+  deriv_node_temp_terms_t tef_terms;
+  output << "{\"statementName\": \"estimated_params_bounds\", "
+         << "\"params\": [";
+
+  for (vector<EstimationParams>::const_iterator it = estim_params_list.begin(); it != estim_params_list.end(); it++)
+    {
+      if (it != estim_params_list.begin())
+        output << ", ";
+      output << "{";
+      switch (it->type)
+        {
+        case 1:
+          output << "\"var\": \"" << it->name << "\"";
+        case 2:
+          output << "\"param\": \"" << it->name << "\"";
+          break;
+        case 3:
+          output << "\"var1\": \"" << it->name << "\","
+                 << "\"var2\": \"" << it->name2 << "\"";
+          break;
+        }
+      output << ", \"lower_bound\": ";
+      it->low_bound->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+      output << ", \"upper_bound\": ";
+      it->up_bound->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+      output << "}";
+    }
+  output << "]"
+         << "}";
+}
+
 ObservationTrendsStatement::ObservationTrendsStatement(const trend_elements_t &trend_elements_arg,
                                                        const SymbolTable &symbol_table_arg) :
   trend_elements(trend_elements_arg),
@@ -1062,6 +1455,32 @@ ObservationTrendsStatement::writeOutput(ostream &output, const string &basename,
     }
 }
 
+void
+ObservationTrendsStatement::writeJsonOutput(ostream &output) const
+{
+  deriv_node_temp_terms_t tef_terms;
+  output << "{\"statementName\": \"observation_trends\", "
+         << "\"trends\" : {";
+  bool printed = false;
+  for (trend_elements_t::const_iterator it = trend_elements.begin();
+       it != trend_elements.end(); it++)
+    {
+      if (symbol_table.getType(it->first) == eEndogenous)
+        {
+          if (printed)
+            output << ", ";
+          output << "\"" << it->first << "\": \"";
+          it->second->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+          output << "\"" << endl;
+          printed = true;
+        }
+      else
+        cerr << "Warning : Non-variable symbol used in observation_trends: " << it->first << endl;
+    }
+  output << "}"
+         << "}";
+}
+
 OsrParamsStatement::OsrParamsStatement(const SymbolList &symbol_list_arg, const SymbolTable &symbol_table_arg) :
   symbol_list(symbol_list_arg),
   symbol_table(symbol_table_arg)
@@ -1088,6 +1507,18 @@ OsrParamsStatement::writeOutput(ostream &output, const string &basename, bool mi
     output << "M_.osr.param_indices(" << ++i <<") = " << symbol_table.getTypeSpecificID(*it) + 1 << ";" << endl;
 }
 
+void
+OsrParamsStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"osr_params\"";
+  if (!symbol_list.empty())
+    {
+      output << ", ";
+      symbol_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 OsrStatement::OsrStatement(const SymbolList &symbol_list_arg,
                            const OptionsList &options_list_arg) :
   symbol_list(symbol_list_arg),
@@ -1127,6 +1558,29 @@ OsrParamsBoundsStatement::writeOutput(ostream &output, const string &basename, b
     }
 }
 
+void
+OsrParamsBoundsStatement::writeJsonOutput(ostream &output) const
+{
+  deriv_node_temp_terms_t tef_terms;
+  output << "{\"statementName\": \"osr_params_bounds\""
+         << ", \"bounds\": [";
+  for (vector<OsrParams>::const_iterator it = osr_params_list.begin();
+       it != osr_params_list.end(); it++)
+    {
+      if (it != osr_params_list.begin())
+        output << ", ";
+      output << "{\"parameter\": \"" << it->name << "\","
+             << "\"bounds\": [\"";
+      it->low_bound->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+      output << "\", \"";
+      it->up_bound->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+      output << "\"]"
+             << "}";
+    }
+  output << "]"
+         << "}";
+}
+
 void
 OsrStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings)
 {
@@ -1164,6 +1618,23 @@ OsrStatement::writeOutput(ostream &output, const string &basename, bool minimal_
   output << "oo_.osr = osr(var_list_,M_.osr.param_names,M_.osr.variable_indices,M_.osr.variable_weights);" << endl;
 }
 
+void
+OsrStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"osr\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  if (!symbol_list.empty())
+    {
+      output << ", ";
+      symbol_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 OptimWeightsStatement::OptimWeightsStatement(const var_weights_t &var_weights_arg,
                                              const covar_weights_t &covar_weights_arg,
                                              const SymbolTable &symbol_table_arg) :
@@ -1215,6 +1686,38 @@ OptimWeightsStatement::writeOutput(ostream &output, const string &basename, bool
     }
 }
 
+void
+OptimWeightsStatement::writeJsonOutput(ostream &output) const
+{
+  deriv_node_temp_terms_t tef_terms;
+  output << "{\"statementName\": \"optim_weights\", "
+         << "\"weights\": [";
+  for (var_weights_t::const_iterator it = var_weights.begin();
+       it != var_weights.end(); it++)
+    {
+      if (it != var_weights.begin())
+        output << ", ";
+      output << "{\"name\": \"" << it->first << "\""
+             << ", \"value\": \"";
+      it->second->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+      output << "\"}";
+    }
+
+  for (covar_weights_t::const_iterator it = covar_weights.begin();
+       it != covar_weights.end(); it++)
+    {
+      if (it != covar_weights.begin() || !var_weights.empty())
+        output << ", ";
+      output << "{\"name1\": \"" << it->first.first << "\""
+             << ", \"name2\": \"" << it->first.second << "\""
+             << ", \"value\": \"";
+      it->second->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+      output << "\"}";
+    }
+  output << "]"
+         << "}";
+}
+
 DynaSaveStatement::DynaSaveStatement(const SymbolList &symbol_list_arg,
                                      const string &filename_arg) :
   symbol_list(symbol_list_arg),
@@ -1230,6 +1733,19 @@ DynaSaveStatement::writeOutput(ostream &output, const string &basename, bool min
          << "',var_list_);" << endl;
 }
 
+void
+DynaSaveStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"dynasave\", "
+         << "\"filename\": \"" << filename << "\"";
+  if (!symbol_list.empty())
+    {
+      output << ", ";
+      symbol_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 DynaTypeStatement::DynaTypeStatement(const SymbolList &symbol_list_arg,
                                      const string &filename_arg) :
   symbol_list(symbol_list_arg),
@@ -1245,6 +1761,19 @@ DynaTypeStatement::writeOutput(ostream &output, const string &basename, bool min
          << "',var_list_);" << endl;
 }
 
+void
+DynaTypeStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"dynatype\", "
+         << "\"filename\": \"" << filename << "\"";
+  if (!symbol_list.empty())
+    {
+      output << ", ";
+      symbol_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 ModelComparisonStatement::ModelComparisonStatement(const filename_list_t &filename_list_arg,
                                                    const OptionsList &options_list_arg) :
   filename_list(filename_list_arg),
@@ -1269,6 +1798,34 @@ ModelComparisonStatement::writeOutput(ostream &output, const string &basename, b
   output << "oo_ = model_comparison(ModelNames_,ModelPriors_,oo_,options_,M_.fname);" << endl;
 }
 
+void
+ModelComparisonStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"model_comparison\"";
+  if (!filename_list.empty())
+    output << ", \"filename_list\": {";
+
+  for (filename_list_t::const_iterator it = filename_list.begin();
+       it != filename_list.end(); it++)
+    {
+      if (it != filename_list.begin())
+        output << ", ";
+      output << "\"name\": \"" << it->first << "\""
+             << "\"prior\": \"" << it->second << "\"";
+    }
+
+  if (!filename_list.empty())
+    output << "}";
+
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+
+  output << "}";
+}
+
 PlannerObjectiveStatement::PlannerObjectiveStatement(StaticModel *model_tree_arg) :
   model_tree(model_tree_arg)
 {
@@ -1311,6 +1868,14 @@ PlannerObjectiveStatement::writeOutput(ostream &output, const string &basename,
   model_tree->writeStaticFile(basename + "_objective", false, false, false, false);
 }
 
+void
+PlannerObjectiveStatement::writeJsonOutput(ostream &output) const
+{
+  cerr << "ERROR: writeJsonOutput not yet implemented for Planner Objective Statement" << endl;
+  exit(EXIT_FAILURE);
+  //  model_tree->writeStaticJsonFile(basename + "_objective", false, false, false, false);
+}
+
 BVARDensityStatement::BVARDensityStatement(int maxnlags_arg, const OptionsList &options_list_arg) :
   maxnlags(maxnlags_arg),
   options_list(options_list_arg)
@@ -1330,6 +1895,18 @@ BVARDensityStatement::writeOutput(ostream &output, const string &basename, bool
   output << "bvar_density(" << maxnlags << ");" << endl;
 }
 
+void
+BVARDensityStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"bvar_density\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 BVARForecastStatement::BVARForecastStatement(int nlags_arg, const OptionsList &options_list_arg) :
   nlags(nlags_arg),
   options_list(options_list_arg)
@@ -1349,6 +1926,18 @@ BVARForecastStatement::writeOutput(ostream &output, const string &basename, bool
   output << "bvar_forecast(" << nlags << ");" << endl;
 }
 
+void
+BVARForecastStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"bvar_forecast\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 SBVARStatement::SBVARStatement(const OptionsList &options_list_arg) :
   options_list(options_list_arg)
 {
@@ -1367,6 +1956,18 @@ SBVARStatement::writeOutput(ostream &output, const string &basename, bool minima
   output << "sbvar(M_,options_);" << endl;
 }
 
+void
+SBVARStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"sbvar\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 MSSBVAREstimationStatement::MSSBVAREstimationStatement(const OptionsList &options_list_arg) :
   options_list(options_list_arg)
 {
@@ -1396,6 +1997,18 @@ MSSBVAREstimationStatement::writeOutput(ostream &output, const string &basename,
   output << "[options_, oo_] = ms_estimation(M_, options_, oo_);" << endl;
 }
 
+void
+MSSBVAREstimationStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"ms_sbvar_estimation\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 MSSBVARSimulationStatement::MSSBVARSimulationStatement(const OptionsList &options_list_arg) :
   options_list(options_list_arg)
 {
@@ -1424,6 +2037,18 @@ MSSBVARSimulationStatement::writeOutput(ostream &output, const string &basename,
   output << "[options_, oo_] = ms_simulation(M_, options_, oo_);" << endl;
 }
 
+void
+MSSBVARSimulationStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"ms_sbvar_simulation\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 MSSBVARComputeMDDStatement::MSSBVARComputeMDDStatement(const OptionsList &options_list_arg) :
   options_list(options_list_arg)
 {
@@ -1443,6 +2068,18 @@ MSSBVARComputeMDDStatement::writeOutput(ostream &output, const string &basename,
   output << "[options_, oo_] = ms_compute_mdd(M_, options_, oo_);" << endl;
 }
 
+void
+MSSBVARComputeMDDStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"ms_sbvar_compute_mdd\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 MSSBVARComputeProbabilitiesStatement::MSSBVARComputeProbabilitiesStatement(const OptionsList &options_list_arg) :
   options_list(options_list_arg)
 {
@@ -1470,6 +2107,18 @@ MSSBVARComputeProbabilitiesStatement::writeOutput(ostream &output, const string
   output << "[options_, oo_] = ms_compute_probabilities(M_, options_, oo_);" << endl;
 }
 
+void
+MSSBVARComputeProbabilitiesStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"ms_sbvar_compute_probabilities\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 MSSBVARIrfStatement::MSSBVARIrfStatement(const SymbolList &symbol_list_arg,
 					 const OptionsList &options_list_arg) :
   symbol_list(symbol_list_arg),
@@ -1517,6 +2166,23 @@ MSSBVARIrfStatement::writeOutput(ostream &output, const string &basename, bool m
   output << "[options_, oo_] = ms_irf(var_list_,M_, options_, oo_);" << endl;
 }
 
+void
+MSSBVARIrfStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"ms_sbvar_irf\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  if (!symbol_list.empty())
+    {
+      output << ", ";
+      symbol_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 MSSBVARForecastStatement::MSSBVARForecastStatement(const OptionsList &options_list_arg) :
   options_list(options_list_arg)
 {
@@ -1543,6 +2209,18 @@ MSSBVARForecastStatement::writeOutput(ostream &output, const string &basename, b
   output << "[options_, oo_] = ms_forecast(M_, options_, oo_);" << endl;
 }
 
+void
+MSSBVARForecastStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"ms_sbvar_forecast\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 MSSBVARVarianceDecompositionStatement::MSSBVARVarianceDecompositionStatement(const OptionsList &options_list_arg) :
   options_list(options_list_arg)
 {
@@ -1587,6 +2265,18 @@ MSSBVARVarianceDecompositionStatement::writeOutput(ostream &output, const string
   output << "[options_, oo_] = ms_variance_decomposition(M_, options_, oo_);" << endl;
 }
 
+void
+MSSBVARVarianceDecompositionStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"ms_sbvar_variance_decomposition\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 IdentificationStatement::IdentificationStatement(const OptionsList &options_list_arg)
 {
   options_list = options_list_arg;
@@ -1626,6 +2316,18 @@ IdentificationStatement::writeOutput(ostream &output, const string &basename, bo
   output << "dynare_identification(options_ident);" << endl;
 }
 
+void
+IdentificationStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"identification\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 WriteLatexDynamicModelStatement::WriteLatexDynamicModelStatement(const DynamicModel &dynamic_model_arg) :
   dynamic_model(dynamic_model_arg)
 {
@@ -1637,6 +2339,12 @@ WriteLatexDynamicModelStatement::writeOutput(ostream &output, const string &base
   dynamic_model.writeLatexFile(basename);
 }
 
+void
+WriteLatexDynamicModelStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"write_latex_dynamic_model\"}";
+}
+
 WriteLatexStaticModelStatement::WriteLatexStaticModelStatement(const StaticModel &static_model_arg) :
   static_model(static_model_arg)
 {
@@ -1648,6 +2356,12 @@ WriteLatexStaticModelStatement::writeOutput(ostream &output, const string &basen
   static_model.writeLatexFile(basename);
 }
 
+void
+WriteLatexStaticModelStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"write_latex_static_model\"}";
+}
+
 WriteLatexOriginalModelStatement::WriteLatexOriginalModelStatement(const DynamicModel &original_model_arg) :
   original_model(original_model_arg)
 {
@@ -1659,6 +2373,12 @@ WriteLatexOriginalModelStatement::writeOutput(ostream &output, const string &bas
   original_model.writeLatexOriginalFile(basename);
 }
 
+void
+WriteLatexOriginalModelStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"write_latex_original_model\"}";
+}
+
 ShockDecompositionStatement::ShockDecompositionStatement(const SymbolList &symbol_list_arg,
                                                          const OptionsList &options_list_arg) :
   symbol_list(symbol_list_arg),
@@ -1674,6 +2394,23 @@ ShockDecompositionStatement::writeOutput(ostream &output, const string &basename
   output << "oo_ = shock_decomposition(M_,oo_,options_,var_list_,bayestopt_,estim_params_);" << endl;
 }
 
+void
+ShockDecompositionStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"shock_decomposition\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  if (!symbol_list.empty())
+    {
+      output << ", ";
+      symbol_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 ConditionalForecastStatement::ConditionalForecastStatement(const OptionsList &options_list_arg) :
   options_list(options_list_arg)
 {
@@ -1686,6 +2423,18 @@ ConditionalForecastStatement::writeOutput(ostream &output, const string &basenam
   output << "imcforecast(constrained_paths_, constrained_vars_, options_cond_fcst_);" << endl;
 }
 
+void
+ConditionalForecastStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"conditional_forecast\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 PlotConditionalForecastStatement::PlotConditionalForecastStatement(int periods_arg, const SymbolList &symbol_list_arg) :
   periods(periods_arg),
   symbol_list(symbol_list_arg)
@@ -1702,6 +2451,19 @@ PlotConditionalForecastStatement::writeOutput(ostream &output, const string &bas
     output << "plot_icforecast(var_list_, " << periods << ",options_);" << endl;
 }
 
+void
+PlotConditionalForecastStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"plot_conditional_forecast\", "
+         << "\"periods\": " << periods;
+  if (!symbol_list.empty())
+    {
+      output << ", ";
+      symbol_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 SvarIdentificationStatement::SvarIdentificationStatement(const svar_identification_restrictions_t &restrictions_arg,
                                                          const bool &upper_cholesky_present_arg,
                                                          const bool &lower_cholesky_present_arg,
@@ -1812,6 +2574,42 @@ SvarIdentificationStatement::writeOutput(ostream &output, const string &basename
     }
 }
 
+void
+SvarIdentificationStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"svar_identification\"";
+
+  if (upper_cholesky_present)
+    output << ", \"upper_cholesky\": 1";
+
+  if (lower_cholesky_present)
+    output << ", \"lower_cholesky\": 1";
+
+  if (constants_exclusion_present)
+    output << ", \"constants_exclusion\": 1";
+
+  if (!upper_cholesky_present && !lower_cholesky_present)
+    {
+      output << ", \"nlags\": " << getMaxLag()
+             << ", \"restrictions\": [";
+
+      for (svar_identification_restrictions_t::const_iterator it = restrictions.begin(); it != restrictions.end(); it++)
+        {
+          if (it != restrictions.begin())
+            output << ", ";
+          output << "{"
+                 << "\"equation_number\": " << it->equation << ", "
+                 << "\"restriction_number\": " << it->restriction_nbr << ", "
+                 << "\"variable\": " << symbol_table.getName(it->variable) << ", "
+                 << "\"expression\": \"";
+          it->value->writeOutput(output);
+          output << "\"}";
+        }
+      output << "]";
+    }
+  output << "}";
+}
+
 MarkovSwitchingStatement::MarkovSwitchingStatement(const OptionsList &options_list_arg) :
   options_list(options_list_arg)
 {
@@ -2051,6 +2849,33 @@ MarkovSwitchingStatement::writeCOutput(ostream &output, const string &basename)
          << "     chain, number_of_regimes, number_of_lags, number_of_lags_was_passed, parameters, duration, restriction_map));" << endl;
 }
 
+void
+MarkovSwitchingStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"markov_switching\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+
+  if (!restriction_map.empty())
+    output << ", {";
+  for (map<pair<int, int>, double >::const_iterator it = restriction_map.begin();
+       it != restriction_map.end(); it++)
+    {
+      if (it != restriction_map.begin())
+        output << ", ";
+      output << "{\"current_period_regime\": " << it->first.first
+             << ", \"next_period_regime\": " << it->first.second
+             << ", \"transition_probability\": "<< it->second
+             << "}";
+    }
+  if (!restriction_map.empty())
+    output << "}";
+  output << "}";
+}
+
 SvarStatement::SvarStatement(const OptionsList &options_list_arg) :
   options_list(options_list_arg)
 {
@@ -2115,6 +2940,18 @@ SvarStatement::writeOutput(ostream &output, const string &basename, bool minimal
     output << "'ALL';" << endl;
 }
 
+void
+SvarStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"svar\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 SvarGlobalIdentificationCheckStatement::SvarGlobalIdentificationCheckStatement(void)
 {
 }
@@ -2125,6 +2962,12 @@ SvarGlobalIdentificationCheckStatement::writeOutput(ostream &output, const strin
   output << "svar_global_identification_check(options_);" << std::endl;
 }
 
+void
+SvarGlobalIdentificationCheckStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"svar_global_identification\"}";
+}
+
 SetTimeStatement::SetTimeStatement(const OptionsList &options_list_arg) :
   options_list(options_list_arg)
 {
@@ -2136,6 +2979,18 @@ SetTimeStatement::writeOutput(ostream &output, const string &basename, bool mini
   options_list.writeOutput(output);
 }
 
+void
+SetTimeStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"set_time\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 EstimationDataStatement::EstimationDataStatement(const OptionsList &options_list_arg) :
   options_list(options_list_arg)
 {
@@ -2175,6 +3030,18 @@ EstimationDataStatement::writeOutput(ostream &output, const string &basename, bo
   options_list.writeOutput(output, "options_.dataset");
 }
 
+void
+EstimationDataStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"estimation_data\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 SubsamplesStatement::SubsamplesStatement(const string &name1_arg,
                                          const string &name2_arg,
                                          const subsample_declaration_map_t subsample_declaration_map_arg,
@@ -2248,6 +3115,30 @@ SubsamplesStatement::writeOutput(ostream &output, const string &basename, bool m
          << endl;
 }
 
+void
+SubsamplesStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"subsamples\""
+         << ", \"name1\": \"" << name1 << "\"";
+  if (!name2.empty())
+    output << ", \"name2\": \"" << name2 << "\"";
+
+  output << ", \"declarations\": {";
+  for (subsample_declaration_map_t::const_iterator it = subsample_declaration_map.begin();
+       it != subsample_declaration_map.end(); it++)
+    {
+      if (it != subsample_declaration_map.begin())
+        output << ",";
+      output << "{"
+             << "\"range_index\": \"" << it->first << "\""
+             << ", \"date1\": \"" << it->second.first << "\""
+             << ", \"date2\": \"" << it->second.second << "\""
+             << "}";
+    }
+  output << "}"
+         << "}";
+}
+
 SubsamplesEqualStatement::SubsamplesEqualStatement(const string &to_name1_arg,
                                                    const string &to_name2_arg,
                                                    const string &from_name1_arg,
@@ -2310,6 +3201,19 @@ SubsamplesEqualStatement::writeOutput(ostream &output, const string &basename, b
          << endl;
 }
 
+void
+SubsamplesEqualStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"subsamples_equal\""
+         << ", \"to_name1\": \"" << to_name1 << "\"";
+  if (!to_name2.empty())
+    output << ", \"to_name2\": \"" << to_name2 << "\"";
+  output << ", \"from_name1\": \"" << from_name1 << "\"";
+  if (!from_name2.empty())
+    output << ", \"from_name2\": \"" << from_name2 << "\"";
+  output << "}";
+}
+
 JointPriorStatement::JointPriorStatement(const vector<string> joint_parameters_arg,
                                          const PriorDistributions &prior_shape_arg,
                                          const OptionsList &options_list_arg) :
@@ -2416,6 +3320,58 @@ JointPriorStatement::writeOutputHelper(ostream &output, const string &field, con
   output << "};" << endl;
 }
 
+void
+JointPriorStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"joint_prior\""
+         << ", \"key\": [";
+  for (vector<string>::const_iterator it = joint_parameters.begin() ; it != joint_parameters.end(); it++)
+    {
+      if (it != joint_parameters.begin())
+        output << ", ";
+      output << "\"" << *it << "\"";
+    }
+  output << "]";
+
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+
+  output << ", \"shape\": ";
+  switch(prior_shape)
+    {
+    case eBeta:
+      output  << "\"beta\"";
+      break;
+    case eGamma:
+      output  << "\"gamma\"";
+      break;
+    case eNormal:
+      output  << "\"normal\"";
+      break;
+    case eInvGamma:
+      output  << "\"inv_gamma\"";
+      break;
+    case eUniform:
+      output  << "\"uniform\"";
+      break;
+    case eInvGamma2:
+      output  << "\"inv_gamma2\"";
+      break;
+    case eDirichlet:
+      output  << "\"dirichlet\"";
+      break;
+    case eWeibull:
+      output  << "\"weibull\"";
+      break;
+    case eNoShape:
+      cerr << "Impossible case." << endl;
+      exit(EXIT_FAILURE);
+    }
+  output << "}";
+}
 
 BasicPriorStatement::~BasicPriorStatement()
 {
@@ -2537,6 +3493,27 @@ BasicPriorStatement::writePriorOutput(ostream &output, string &lhs_field, const
   writeCommonOutput(output, lhs_field);
 }
 
+void
+BasicPriorStatement::writeJsonPriorOutput(ostream &output) const
+{
+  output << ", \"name\": \"" << name << "\""
+         << ", \"subsample\": \"" << subsample_name << "\""
+         << ", ";
+  writeJsonShape(output);
+  if (variance != NULL)
+    {
+      deriv_node_temp_terms_t tef_terms;
+      output << ", \"variance\": \"";
+      variance->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+      output << "\"";
+    }
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+}
+
 void
 BasicPriorStatement::writeCVarianceOption(ostream &output) const
 {
@@ -2610,6 +3587,41 @@ BasicPriorStatement::writeCShape(ostream &output) const
     }
 }
 
+void
+BasicPriorStatement::writeJsonShape(ostream &output) const
+{
+  output << "\"shape\": ";
+  switch (prior_shape)
+    {
+    case eBeta:
+      output  << "\"beta\"";
+      break;
+    case eGamma:
+      output  << "\"gamma\"";
+      break;
+    case eNormal:
+      output  << "\"normal\"";
+      break;
+    case eInvGamma:
+      output  << "\"inv_gamma\"";
+      break;
+    case eUniform:
+      output  << "\"uniform\"";
+      break;
+    case eInvGamma2:
+      output  << "\"inv_gamma2\"";
+      break;
+    case eDirichlet:
+      output  << "\"dirichlet\"";
+      break;
+    case eWeibull:
+      output  << "\"weibull\"";
+      break;
+    case eNoShape:
+      assert(prior_shape != eNoShape);
+    }
+}
+
 PriorStatement::PriorStatement(const string &name_arg,
                                const string &subsample_name_arg,
                                const PriorDistributions &prior_shape_arg,
@@ -2629,6 +3641,14 @@ PriorStatement::writeOutput(ostream &output, const string &basename, bool minima
   writePriorOutput(output, lhs_field, "");
 }
 
+void
+PriorStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"prior\"";
+  writeJsonPriorOutput(output);
+  output << "}";
+}
+
 void
 PriorStatement::writeCOutput(ostream &output, const string &basename)
 {
@@ -2669,6 +3689,14 @@ StdPriorStatement::writeOutput(ostream &output, const string &basename, bool min
   writePriorOutput(output, lhs_field, "");
 }
 
+void
+StdPriorStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"std_prior\"";
+  writeJsonPriorOutput(output);
+  output << "}";
+}
+
 void
 StdPriorStatement::writeCOutput(ostream &output, const string &basename)
 {
@@ -2734,6 +3762,15 @@ CorrPriorStatement::writeOutput(ostream &output, const string &basename, bool mi
   writePriorOutput(output, lhs_field, name1);
 }
 
+void
+CorrPriorStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"corr_prior\""
+         << ", \"name2\": \"" << name1 << "\"";
+  writeJsonPriorOutput(output);
+  output << "}";
+}
+
 void
 CorrPriorStatement::writeCOutput(ostream &output, const string &basename)
 {
@@ -2869,6 +3906,21 @@ PriorEqualStatement::writeOutput(ostream &output, const string &basename, bool m
   output << lhs_field << " = " << rhs_field << ";" << endl;
 }
 
+void
+PriorEqualStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"prior_equal\""
+         << ", \"to_name1\": \"" << to_name1 << "\"";
+  if (to_declaration_type == "corr")
+    output << ", \"to_name2\": \"" << to_name2 << "\"";
+  output << ", \"to_subsample\": \"" << to_subsample_name << "\""
+         << ", \"from_name1\": \"" << from_name1 << "\"";
+  if (to_declaration_type == "corr")
+    output << ", \"from_name2\": \"" << from_name2 << "\"";
+  output << ", \"from_subsample\": \"" << from_subsample_name << "\""
+         << "}";
+}
+
 BasicOptionsStatement::~BasicOptionsStatement()
 {
 }
@@ -2946,6 +3998,19 @@ BasicOptionsStatement::writeOptionsOutput(ostream &output, string &lhs_field, co
   writeCommonOutput(output, lhs_field);
 }
 
+void
+BasicOptionsStatement::writeJsonOptionsOutput(ostream &output) const
+{
+  output << ", \"name\": \"" << name << "\"";
+  if (!subsample_name.empty())
+    output << ", \"subsample_name\": \"" << subsample_name << "\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+}
+
 OptionsStatement::OptionsStatement(const string &name_arg,
                                    const string &subsample_name_arg,
                                    const OptionsList &options_list_arg) :
@@ -2963,6 +4028,14 @@ OptionsStatement::writeOutput(ostream &output, const string &basename, bool mini
   writeOptionsOutput(output, lhs_field, "");
 }
 
+void
+OptionsStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"options\"";
+  writeJsonOptionsOutput(output);
+  output << "}";
+}
+
 void
 OptionsStatement::writeCOutput(ostream &output, const string &basename)
 {
@@ -2994,6 +4067,14 @@ StdOptionsStatement::writeOutput(ostream &output, const string &basename, bool m
   writeOptionsOutput(output, lhs_field, "");
 }
 
+void
+StdOptionsStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"std_options\"";
+  writeJsonOptionsOutput(output);
+  output << "}";
+}
+
 void
 StdOptionsStatement::writeCOutput(ostream &output, const string &basename)
 {
@@ -3051,6 +4132,15 @@ CorrOptionsStatement::writeOutput(ostream &output, const string &basename, bool
   writeOptionsOutput(output, lhs_field, name1);
 }
 
+void
+CorrOptionsStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"corr_options\""
+         << ", \"name2\": \"" << name1 << "\"";
+  writeJsonOptionsOutput(output);
+  output << "}";
+}
+
 void
 CorrOptionsStatement::writeCOutput(ostream &output, const string &basename)
 {
@@ -3110,6 +4200,21 @@ OptionsEqualStatement::checkPass(ModFileStructure &mod_file_struct, WarningConso
     }
 }
 
+void
+OptionsEqualStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"options_equal\""
+         << ", \"to_name1\": \"" << to_name1 << "\"";
+  if (to_declaration_type == "corr")
+    output << ", \"to_name2\": \"" << to_name2 << "\"";
+  output << ", \"to_subsample\": \"" << to_subsample_name << "\""
+         << ", \"from_name1\": \"" << from_name1 << "\"";
+  if (to_declaration_type == "corr")
+    output << ", \"from_name2\": \"" << from_name2 << "\"";
+  output << ", \"from_subsample\": \"" << from_subsample_name << "\""
+         << "}";
+}
+
 void
 OptionsEqualStatement::get_base_name(const SymbolType symb_type, string &lhs_field) const
 {
@@ -3203,6 +4308,23 @@ CalibSmootherStatement::writeOutput(ostream &output, const string &basename, boo
   output << "[oo_,options_,bayestopt_]=evaluate_smoother('calibration',var_list_,M_,oo_,options_,bayestopt_,estim_params_);" << endl;
 }
 
+void
+CalibSmootherStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"calib_smoother\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  if (!symbol_list.empty())
+    {
+      output << ", ";
+      symbol_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 ExtendedPathStatement::ExtendedPathStatement(const OptionsList &options_list_arg)
   : options_list(options_list_arg)
 {
@@ -3239,6 +4361,18 @@ ExtendedPathStatement::writeOutput(ostream &output, const string &basename, bool
          << ", [], options_, M_, oo_);" << endl;
 }
 
+void
+ExtendedPathStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"extended_path\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
+
 ModelDiagnosticsStatement::ModelDiagnosticsStatement()
 {
 }
@@ -3249,6 +4383,12 @@ ModelDiagnosticsStatement::writeOutput(ostream &output, const string &basename,
   output << "model_diagnostics(M_,options_,oo_);" << endl;
 }
 
+void
+ModelDiagnosticsStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"model_diagnostics\"}";
+}
+
 Smoother2histvalStatement::Smoother2histvalStatement(const OptionsList &options_list_arg) :
   options_list(options_list_arg)
 {
@@ -3260,3 +4400,15 @@ Smoother2histvalStatement::writeOutput(ostream &output, const string &basename,
   options_list.writeOutput(output, "options_smoother2histval");
   output << "smoother2histval(options_smoother2histval);" << endl;
 }
+
+void
+Smoother2histvalStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"smoother_2_histval\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+  output << "}";
+}
diff --git a/ComputingTasks.hh b/ComputingTasks.hh
index a62a02b3b671f63f29e0cc35fbd0c5422a609965..49dcdbe8ba7f759cf4392d220b571304a302342d 100644
--- a/ComputingTasks.hh
+++ b/ComputingTasks.hh
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003-2016 Dynare Team
+ * Copyright (C) 2003-2017 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -36,6 +36,7 @@ public:
   SteadyStatement(const OptionsList &options_list_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class CheckStatement : public Statement
@@ -46,6 +47,7 @@ public:
   CheckStatement(const OptionsList &options_list_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class SimulStatement : public Statement
@@ -56,6 +58,7 @@ public:
   SimulStatement(const OptionsList &options_list_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class PerfectForesightSetupStatement : public Statement
@@ -65,6 +68,7 @@ private:
 public:
   PerfectForesightSetupStatement(const OptionsList &options_list_arg);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class PerfectForesightSolverStatement : public Statement
@@ -75,6 +79,7 @@ public:
   PerfectForesightSolverStatement(const OptionsList &options_list_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class PriorPosteriorFunctionStatement : public Statement
@@ -86,6 +91,7 @@ public:
   PriorPosteriorFunctionStatement(const bool prior_func_arg, const OptionsList &options_list_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class ModelInfoStatement : public Statement
@@ -96,6 +102,7 @@ public:
   ModelInfoStatement(const OptionsList &options_list_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class StochSimulStatement : public Statement
@@ -108,6 +115,7 @@ public:
                       const OptionsList &options_list_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class ForecastStatement : public Statement
@@ -119,6 +127,7 @@ public:
   ForecastStatement(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 RamseyModelStatement : public Statement
@@ -131,6 +140,7 @@ public:
                         const OptionsList &options_list_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class RamseyConstraintsStatement : public Statement
@@ -143,11 +153,13 @@ public:
   }; 
   typedef vector<Constraint> constraints_t;
 private:
+  const SymbolTable &symbol_table;
   const constraints_t constraints;
 public:
-  RamseyConstraintsStatement(const constraints_t &constraints_arg);
+  RamseyConstraintsStatement(const SymbolTable &symbol_table_arg, const constraints_t &constraints_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
   //  virtual Statement *cloneAndReindexSymbIds(DataTree &dynamic_datatree, SymbolTable &orig_symbol_table);
 };
 
@@ -164,6 +176,7 @@ public:
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   void checkRamseyPolicyList();
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class DiscretionaryPolicyStatement : public Statement
@@ -176,6 +189,7 @@ public:
 			       const OptionsList &options_list_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class RplotStatement : public Statement
@@ -185,6 +199,7 @@ private:
 public:
   RplotStatement(const SymbolList &symbol_list_arg);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class UnitRootVarsStatement : public Statement
@@ -192,6 +207,7 @@ class UnitRootVarsStatement : public Statement
 public:
   UnitRootVarsStatement(void);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class PeriodsStatement : public Statement
@@ -201,6 +217,7 @@ private:
 public:
   PeriodsStatement(int periods_arg);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class DsampleStatement : public Statement
@@ -211,6 +228,7 @@ public:
   DsampleStatement(int val1_arg);
   DsampleStatement(int val1_arg, int val2_arg);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class EstimationStatement : public Statement
@@ -223,6 +241,7 @@ public:
                       const OptionsList &options_list_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class DynareSensitivityStatement : public Statement
@@ -233,6 +252,7 @@ public:
   DynareSensitivityStatement(const OptionsList &options_list_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class ObservationTrendsStatement : public Statement
@@ -246,6 +266,7 @@ public:
   ObservationTrendsStatement(const trend_elements_t &trend_elements_arg,
                              const SymbolTable &symbol_table_arg);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class OsrParamsStatement : public Statement
@@ -257,6 +278,7 @@ public:
   OsrParamsStatement(const SymbolList &symbol_list_arg, const SymbolTable &symbol_table_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class OsrStatement : public Statement
@@ -269,6 +291,7 @@ public:
                const OptionsList &options_list_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 //! Temporary structure used when parsing estimation_params* statements
@@ -295,6 +318,7 @@ public:
   OsrParamsBoundsStatement(const vector<OsrParams> &osr_params_list_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class DynaTypeStatement : public Statement
@@ -306,6 +330,7 @@ public:
   DynaTypeStatement(const SymbolList &symbol_list_arg,
                     const string &filename_arg);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class DynaSaveStatement : public Statement
@@ -317,6 +342,7 @@ public:
   DynaSaveStatement(const SymbolList &symbol_list_arg,
                     const string &filename_arg);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class ModelComparisonStatement : public Statement
@@ -330,6 +356,7 @@ public:
   ModelComparisonStatement(const filename_list_t &filename_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;
 };
 
 //! Temporary structure used when parsing estimation_params* statements
@@ -369,6 +396,7 @@ public:
                            const SymbolTable &symbol_table_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class EstimatedParamsInitStatement : public Statement
@@ -383,6 +411,7 @@ public:
                                const bool use_calibration_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class EstimatedParamsBoundsStatement : public Statement
@@ -394,6 +423,7 @@ public:
   EstimatedParamsBoundsStatement(const vector<EstimationParams> &estim_params_list_arg,
                                  const SymbolTable &symbol_table_arg);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class OptimWeightsStatement : public Statement
@@ -411,6 +441,7 @@ public:
                         const SymbolTable &symbol_table_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 /*! \todo Make model_tree a member instead of a pointer */
@@ -430,6 +461,7 @@ public:
   /*! \todo allow for the possibility of disabling temporary terms */
   virtual void computingPass();
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
   //! Return the Planner Objective
   StaticModel *getPlannerObjective() const;
 };
@@ -443,6 +475,7 @@ public:
   BVARDensityStatement(int maxnlags_arg, const OptionsList &options_list_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class BVARForecastStatement : public Statement
@@ -454,6 +487,7 @@ public:
   BVARForecastStatement(int nlags_arg, const OptionsList &options_list_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class SBVARStatement : public Statement
@@ -464,6 +498,7 @@ public:
   SBVARStatement(const OptionsList &options_list_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class MSSBVAREstimationStatement : public Statement
@@ -474,6 +509,7 @@ public:
   MSSBVAREstimationStatement(const OptionsList &options_list_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class MSSBVARSimulationStatement : public Statement
@@ -484,6 +520,7 @@ public:
   MSSBVARSimulationStatement(const OptionsList &options_list_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class MSSBVARComputeMDDStatement : public Statement
@@ -494,6 +531,7 @@ public:
   MSSBVARComputeMDDStatement(const OptionsList &options_list_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class MSSBVARComputeProbabilitiesStatement : public Statement
@@ -504,6 +542,7 @@ public:
   MSSBVARComputeProbabilitiesStatement(const OptionsList &options_list_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class MSSBVARIrfStatement : public Statement
@@ -516,6 +555,7 @@ public:
 		      const OptionsList &options_list_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class MSSBVARForecastStatement : public Statement
@@ -526,6 +566,7 @@ public:
   MSSBVARForecastStatement(const OptionsList &options_list_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class MSSBVARVarianceDecompositionStatement : public Statement
@@ -536,6 +577,7 @@ public:
   MSSBVARVarianceDecompositionStatement(const OptionsList &options_list_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class IdentificationStatement : public Statement
@@ -546,6 +588,7 @@ public:
   IdentificationStatement(const OptionsList &options_list_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class WriteLatexDynamicModelStatement : public Statement
@@ -555,6 +598,7 @@ private:
 public:
   WriteLatexDynamicModelStatement(const DynamicModel &dynamic_model_arg);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class WriteLatexStaticModelStatement : public Statement
@@ -564,6 +608,7 @@ private:
 public:
   WriteLatexStaticModelStatement(const StaticModel &static_model_arg);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class WriteLatexOriginalModelStatement : public Statement
@@ -573,6 +618,7 @@ private:
 public:
   WriteLatexOriginalModelStatement(const DynamicModel &original_model_arg);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class ShockDecompositionStatement : public Statement
@@ -584,6 +630,7 @@ public:
   ShockDecompositionStatement(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 ConditionalForecastStatement : public Statement
@@ -593,6 +640,7 @@ private:
 public:
   ConditionalForecastStatement(const OptionsList &options_list_arg);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class PlotConditionalForecastStatement : public Statement
@@ -604,6 +652,7 @@ private:
 public:
   PlotConditionalForecastStatement(int periods_arg, const SymbolList &symbol_list_arg);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class CalibSmootherStatement : public Statement
@@ -616,6 +665,7 @@ public:
                          const OptionsList &options_list_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class ExtendedPathStatement : public Statement
@@ -626,6 +676,7 @@ public:
   ExtendedPathStatement(const OptionsList &options_list_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class SvarIdentificationStatement : public Statement
@@ -657,6 +708,7 @@ public:
                               const SymbolTable &symbol_table_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class MarkovSwitchingStatement : public Statement
@@ -669,6 +721,7 @@ public:
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
   virtual void writeCOutput(ostream &output, const string &basename);
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class SvarStatement : public Statement
@@ -679,6 +732,7 @@ public:
   SvarStatement(const OptionsList &options_list_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class SvarGlobalIdentificationCheckStatement : public Statement
@@ -686,6 +740,7 @@ class SvarGlobalIdentificationCheckStatement : public Statement
 public:
   SvarGlobalIdentificationCheckStatement();
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class SetTimeStatement : public Statement
@@ -695,6 +750,7 @@ private:
 public:
   SetTimeStatement(const OptionsList &options_list_arg);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class EstimationDataStatement : public Statement
@@ -705,6 +761,7 @@ public:
   EstimationDataStatement(const OptionsList &options_list_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class SubsamplesStatement : public Statement
@@ -724,6 +781,7 @@ public:
                       const SymbolTable &symbol_table_arg);
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class SubsamplesEqualStatement : public Statement
@@ -741,6 +799,7 @@ public:
                            const string &from_name2_arg,
                            const SymbolTable &symbol_table_arg);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class JointPriorStatement : public Statement
@@ -756,6 +815,7 @@ public:
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
   void writeOutputHelper(ostream &output, const string &field, const string &lhs_field) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 
@@ -788,6 +848,8 @@ protected:
   void writeCShape(ostream &output) const;
   void writeCVarianceOption(ostream &output) const;
   void writeCDomain(ostream &output) const;
+  void writeJsonShape(ostream &output) const;
+  void writeJsonPriorOutput(ostream &output) const;
 };
 
 class PriorStatement : public BasicPriorStatement
@@ -800,6 +862,7 @@ public:
                  const OptionsList &options_list_arg);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
   virtual void writeCOutput(ostream &output, const string &basename);
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class StdPriorStatement : public BasicPriorStatement
@@ -815,6 +878,7 @@ public:
                     const SymbolTable &symbol_table_arg);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
   virtual void writeCOutput(ostream &output, const string &basename);
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class CorrPriorStatement : public BasicPriorStatement
@@ -833,6 +897,7 @@ public:
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
   virtual void writeCOutput(ostream &output, const string &basename);
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class PriorEqualStatement : public Statement
@@ -860,6 +925,7 @@ public:
   void get_base_name(const SymbolType symb_type, string &lhs_field) const;
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class BasicOptionsStatement : public Statement
@@ -882,6 +948,7 @@ protected:
   void writeOptionsIndex(ostream &output, const string &lhs_field) const;
   void writeOutputHelper(ostream &output, const string &field, const string &lhs_field) const;
   void writeCOutputHelper(ostream &output, const string &field) const;
+  void writeJsonOptionsOutput(ostream &output) const;
 };
 
 class OptionsStatement : public BasicOptionsStatement
@@ -890,6 +957,7 @@ public:
   OptionsStatement(const string &name_arg, const string &subsample_name_arg, const OptionsList &options_list_arg);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
   virtual void writeCOutput(ostream &output, const string &basename);
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class StdOptionsStatement : public BasicOptionsStatement
@@ -903,6 +971,7 @@ public:
                       const SymbolTable &symbol_table_arg);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
   virtual void writeCOutput(ostream &output, const string &basename);
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class CorrOptionsStatement : public BasicOptionsStatement
@@ -918,6 +987,7 @@ public:
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
   virtual void writeCOutput(ostream &output, const string &basename);
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class OptionsEqualStatement : public Statement
@@ -945,6 +1015,7 @@ public:
   void get_base_name(const SymbolType symb_type, string &lhs_field) const;
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class ModelDiagnosticsStatement : public Statement
@@ -952,6 +1023,7 @@ class ModelDiagnosticsStatement : public Statement
 public:
   ModelDiagnosticsStatement();
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class Smoother2histvalStatement : public Statement
@@ -961,6 +1033,7 @@ private:
 public:
   Smoother2histvalStatement(const OptionsList &options_list_arg);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 #endif
diff --git a/ModFile.cc b/ModFile.cc
index d269887380e3295ba95e4b281c2268ab13263a1a..78ae952ac7fe4034ab23d1d1e431a06ba18d3bbd 100644
--- a/ModFile.cc
+++ b/ModFile.cc
@@ -1259,29 +1259,12 @@ ModFile::writeJsonOutput(const string &basename, JsonFileOutputType json_output_
   if (!statements.empty())
     {
       output << ",\"statements\": [";
-      bool printed_statement = false;
       for (vector<Statement *>::const_iterator it = statements.begin();
-           it != statements.end();)
+           it != statements.end(); it++)
         {
+          if (it != statements.begin())
+            output << ", " << endl;
           (*it)->writeJsonOutput(output);
-
-          if (dynamic_cast<InitParamStatement *>(*it) != NULL ||
-              dynamic_cast<InitValStatement *>(*it) != NULL ||
-              dynamic_cast<EndValStatement *>(*it) != NULL ||
-              dynamic_cast<HistValStatement *>(*it) != NULL)
-            printed_statement = true;
-
-          if (++it == statements.end())
-            break;
-
-          // tests to see if the next statement will be one for which we support writing JSON files
-          // to be deleted once we support all statements
-          if (printed_statement &&
-              (dynamic_cast<InitParamStatement *>(*it) != NULL ||
-               dynamic_cast<InitValStatement *>(*it) != NULL ||
-               dynamic_cast<EndValStatement *>(*it) != NULL ||
-               dynamic_cast<HistValStatement *>(*it) != NULL))
-            output << "," << endl;
         }
       output << "]" << endl;
     }
diff --git a/NumericalInitialization.cc b/NumericalInitialization.cc
index 057b59d6a5d92444e3c230bce800781ae77adfcc..22c013b3d3a61e0efe7d605e22ee37ac7bd7dfcb 100644
--- a/NumericalInitialization.cc
+++ b/NumericalInitialization.cc
@@ -177,16 +177,15 @@ InitOrEndValStatement::writeInitValues(ostream &output) const
 void
 InitOrEndValStatement::writeJsonInitValues(ostream &output) const
 {
-  int i = 0;
   deriv_node_temp_terms_t tef_terms;
   for (init_values_t::const_iterator it = init_values.begin();
-       it != init_values.end(); it++, i++)
+       it != init_values.end(); it++)
     {
+      if (it != init_values.begin())
+        output << ", ";
       output << "{\"name\": \"" << symbol_table.getName(it->first) << "\", " << "\"value\": \"";
       it->second->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
       output << "\"}";
-      if (i < init_values.size() - 1)
-        output << ", ";
     }
 }
 
@@ -419,19 +418,18 @@ HistValStatement::writeOutput(ostream &output, const string &basename, bool mini
 void
 HistValStatement::writeJsonOutput(ostream &output) const
 {
-  int i = 0;
   deriv_node_temp_terms_t tef_terms;
   output << "{\"statementName\": \"hist_val\", \"vals\": [";
   for (hist_values_t::const_iterator it = hist_values.begin();
        it != hist_values.end(); it++)
     {
+      if (it != hist_values.begin())
+        output << ", ";
       output << "{ \"name\": \"" << symbol_table.getName(it->first.first) << "\""
              << ", \"lag\": " << it->first.second
              << ", \"value\": \"";
       it->second->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
       output << "\"}";
-      if (i < hist_values.size() - 1)
-        output << ", ";
     }
   output << "]}";
 }
@@ -451,6 +449,14 @@ InitvalFileStatement::writeOutput(ostream &output, const string &basename, bool
          << "initvalf('" << filename << "');" << endl;
 }
 
+void
+InitvalFileStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"init_val_file\""
+         << ", \"filename\": \"" << filename << "\""
+         << "}";
+}
+
 HistvalFileStatement::HistvalFileStatement(const string &filename_arg) :
   filename(filename_arg)
 {
@@ -462,6 +468,14 @@ HistvalFileStatement::writeOutput(ostream &output, const string &basename, bool
   output << "histvalf('" << filename << "');" << endl;
 }
 
+void
+HistvalFileStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"hist_val_file\""
+         << ", \"filename\": \"" << filename << "\""
+         << "}";
+}
+
 HomotopyStatement::HomotopyStatement(const homotopy_values_t &homotopy_values_arg,
                                      const SymbolTable &symbol_table_arg) :
   homotopy_values(homotopy_values_arg),
@@ -498,6 +512,31 @@ HomotopyStatement::writeOutput(ostream &output, const string &basename, bool min
     }
 }
 
+void
+HomotopyStatement::writeJsonOutput(ostream &output) const
+{
+  deriv_node_temp_terms_t tef_terms;
+  output << "{\"statementName\": \"homotopy\", "
+         << "\"values\": [";
+  for (homotopy_values_t::const_iterator it = homotopy_values.begin();
+       it != homotopy_values.end(); it++)
+    {
+      if (it != homotopy_values.begin())
+        output << ", ";
+      output << "{\"name\": \"" << symbol_table.getName(it->first) << "\""
+             << ", \"initial_value\": \"";
+      if (it->second.first != NULL)
+        it->second.first->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+      else
+        output << "NaN";
+      output << "\", \"final_value\": \"";
+      it->second.second->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+      output << "\"}";
+    }
+  output << "]"
+         << "}";
+}
+
 SaveParamsAndSteadyStateStatement::SaveParamsAndSteadyStateStatement(const string &filename_arg) :
   filename(filename_arg)
 {
@@ -509,6 +548,14 @@ SaveParamsAndSteadyStateStatement::writeOutput(ostream &output, const string &ba
   output << "save_params_and_steady_state('" << filename << "');" << endl;
 }
 
+void
+SaveParamsAndSteadyStateStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"save_params_and_steady_state\""
+         << ", \"filename\": \"" << filename << "\""
+         << "}";
+}
+
 LoadParamsAndSteadyStateStatement::LoadParamsAndSteadyStateStatement(const string &filename,
                                                                      const SymbolTable &symbol_table_arg,
                                                                      WarningConsolidation &warnings) :
@@ -574,6 +621,24 @@ LoadParamsAndSteadyStateStatement::writeOutput(ostream &output, const string &ba
     }
 }
 
+void
+LoadParamsAndSteadyStateStatement::writeJsonOutput(ostream &output) const
+{
+  deriv_node_temp_terms_t tef_terms;
+  output << "{\"statementName\": \"load_params_and_steady_state\""
+         << "\"values\": [";
+  for (map<int, string>::const_iterator it = content.begin();
+       it != content.end(); it++)
+    {
+      if (it != content.begin())
+        output << ", ";
+      output << "{\"name\": \"" << symbol_table.getName(it->first) << "\""
+             << ", \"value\": \"" << it->second << "\"}";
+    }
+  output << "]"
+         << "}";
+}
+
 void
 LoadParamsAndSteadyStateStatement::fillEvalContext(eval_context_t &eval_context) const
 {
diff --git a/NumericalInitialization.hh b/NumericalInitialization.hh
index e48cb9ee796384dea3b4ab58e5912a904259121c..58a7e6e0437298f37f1ddfc540ddacbccb318caf 100644
--- a/NumericalInitialization.hh
+++ b/NumericalInitialization.hh
@@ -128,6 +128,7 @@ private:
 public:
   InitvalFileStatement(const string &filename_arg);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class HistvalFileStatement : public Statement
@@ -137,6 +138,7 @@ private:
 public:
   HistvalFileStatement(const string &filename_arg);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class HomotopyStatement : public Statement
@@ -152,6 +154,7 @@ public:
   HomotopyStatement(const homotopy_values_t &homotopy_values_arg,
                     const SymbolTable &symbol_table_arg);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class SaveParamsAndSteadyStateStatement : public Statement
@@ -161,6 +164,7 @@ private:
 public:
   SaveParamsAndSteadyStateStatement(const string &filename_arg);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class LoadParamsAndSteadyStateStatement : public Statement
@@ -177,6 +181,7 @@ public:
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
   //! Fill eval context with parameters/variables values
   void fillEvalContext(eval_context_t &eval_context) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 #endif
diff --git a/ParsingDriver.cc b/ParsingDriver.cc
index 23e2018c6c3006447df3e1adc1d84406ae834bb0..3129df07eb09831c3380df884ab94f3fc38d6676 100644
--- a/ParsingDriver.cc
+++ b/ParsingDriver.cc
@@ -2934,7 +2934,7 @@ ParsingDriver::prior_posterior_function(bool prior_func)
 void
 ParsingDriver::add_ramsey_constraints_statement()
 {
-  mod_file->addStatement(new RamseyConstraintsStatement(ramsey_constraints));
+  mod_file->addStatement(new RamseyConstraintsStatement(mod_file->symbol_table, ramsey_constraints));
   ramsey_constraints.clear();
 }
 
diff --git a/Shocks.cc b/Shocks.cc
index af40262414e6dc343874707a73d11814580c7590..95391092b9a562962a8f3e547f5c769fbc43b466 100644
--- a/Shocks.cc
+++ b/Shocks.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003-2016 Dynare Team
+ * Copyright (C) 2003-2017 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -67,6 +67,34 @@ AbstractShocksStatement::writeDetShocks(ostream &output) const
   output << "M_.exo_det_length = " << exo_det_length << ";\n";
 }
 
+void
+AbstractShocksStatement::writeJsonDetShocks(ostream &output) const
+{
+  deriv_node_temp_terms_t tef_terms;
+  output << "\"deterministic_shocks\": [";
+  for (det_shocks_t::const_iterator it = det_shocks.begin();
+       it != det_shocks.end(); it++)
+    {
+      if (it != det_shocks.begin())
+        output << ", ";
+      output << "{\"var\": \"" << symbol_table.getName(it->first) << "\", "
+             << "\"values\": [";
+        for (vector<DetShockElement>::const_iterator it1 = it->second.begin();
+             it1 != it->second.end(); it1++)
+          {
+            if (it1 != it->second.begin())
+              output << ", ";
+            output << "{\"period1\": " << it1->period1 << ", "
+                   << "\"period2\": " << it1->period2 << ", "
+                   << "\"value\": \"";
+            it1->value->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+            output << "\"}";
+          }
+      output << "]}";
+    }
+  output << "]";
+}
+
 ShocksStatement::ShocksStatement(bool overwrite_arg,
                                  const det_shocks_t &det_shocks_arg,
                                  const var_and_std_shocks_t &var_shocks_arg,
@@ -123,6 +151,73 @@ ShocksStatement::writeOutput(ostream &output, const string &basename, bool minim
     output << "M_.sigma_e_is_diagonal = 1;" << endl;
 }
 
+
+void
+ShocksStatement::writeJsonOutput(ostream &output) const
+{
+  deriv_node_temp_terms_t tef_terms;
+  output << "{\"statementName\": \"shocks\""
+         << ", \"overwrite\": ";
+  if (overwrite)
+    output << "true";
+  else
+    output << "false";
+  if (!det_shocks.empty())
+    {
+      output << ", ";
+      writeJsonDetShocks(output);
+    }
+  output<< ", \"variance\": [";
+  for (var_and_std_shocks_t::const_iterator it = var_shocks.begin(); it != var_shocks.end(); it++)
+    {
+      if (it != var_shocks.begin())
+        output << ", ";
+      output << "{\"name\": \"" << symbol_table.getName(it->first) << "\", "
+             << "\"variance\": \"";
+      it->second->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+      output << "\"}";
+    }
+  output << "]"
+         << ", \"stderr\": [";
+  for (var_and_std_shocks_t::const_iterator it = std_shocks.begin(); it != std_shocks.end(); it++)
+    {
+      if (it != std_shocks.begin())
+        output << ", ";
+      output << "{\"name\": \"" << symbol_table.getName(it->first) << "\", "
+             << "\"stderr\": \"";
+      it->second->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+      output << "\"}";
+    }
+  output << "]"
+         << ", \"covariance\": [";
+  for (covar_and_corr_shocks_t::const_iterator it = covar_shocks.begin(); it != covar_shocks.end(); it++)
+    {
+      if (it != covar_shocks.begin())
+        output << ", ";
+      output << "{"
+             << "\"name\": \"" << symbol_table.getName(it->first.first) << "\", "
+             << "\"name2\": \"" << symbol_table.getName(it->first.second) << "\", "
+             << "\"covariance\": \"";
+      it->second->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+      output << "\"}";
+    }
+  output << "]"
+         << ", \"correlation\": [";
+  for (covar_and_corr_shocks_t::const_iterator it = corr_shocks.begin(); it != corr_shocks.end(); it++)
+    {
+      if (it != corr_shocks.begin())
+        output << ", ";
+      output << "{"
+             << "\"name\": \"" << symbol_table.getName(it->first.first) << "\", "
+             << "\"name2\": \"" << symbol_table.getName(it->first.second) << "\", "
+             << "\"correlation\": \"";
+      it->second->writeJsonOutput(output, oMatlabOutsideModel, temporary_terms_t(), tef_terms);
+      output << "\"}";
+    }
+  output << "]"
+         << "}";
+}
+
 void
 ShocksStatement::writeVarOrStdShock(ostream &output, var_and_std_shocks_t::const_iterator &it,
                                     bool stddev) const
@@ -430,6 +525,26 @@ MomentCalibration::writeOutput(ostream &output, const string &basename, bool min
   output << "};" << endl;
 }
 
+void
+MomentCalibration::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"moment_calibration\""
+         << ", \"moment_calibration_criteria\": [";
+  for (constraints_t::const_iterator it = constraints.begin(); it != constraints.end(); it++)
+    {
+      if (it != constraints.begin())
+        output << ", ";
+      output << "{\"endogenous1\": \"" << symbol_table.getName(it->endo1) << "\""
+             << ", \"endogenous2\": \"" << symbol_table.getName(it->endo2) << "\""
+             << ", \"lags\": \"" << it->lags << "\""
+             << ", \"lower_bound\": \"" << it->lower_bound << "\""
+             << ", \"upper_bound\": \"" << it->upper_bound << "\""
+             << "}";
+    }
+  output << "]"
+         << "}";
+}
+
 IrfCalibration::IrfCalibration(const constraints_t &constraints_arg,
                                const SymbolTable &symbol_table_arg,
                                const OptionsList &options_list_arg)
@@ -455,6 +570,32 @@ IrfCalibration::writeOutput(ostream &output, const string &basename, bool minima
   output << "};" << endl;
 }
 
+void
+IrfCalibration::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"irf_calibration\"";
+  if (options_list.getNumberOfOptions())
+    {
+      output << ", ";
+      options_list.writeJsonOutput(output);
+    }
+
+  output << ", \"irf_restrictions\": [";
+  for (constraints_t::const_iterator it = constraints.begin(); it != constraints.end(); it++)
+    {
+      if (it != constraints.begin())
+        output << ", ";
+      output << "{\"endogenous\": \"" << symbol_table.getName(it->endo) << "\""
+             << ", \"exogenous\": \"" << symbol_table.getName(it->exo) << "\""
+             << ", \"periods\": \"" << it->periods << "\""
+             << ", \"lower_bound\": \"" << it->lower_bound << "\""
+             << ", \"upper_bound\": \"" << it->upper_bound << "\""
+             << "}";
+    }
+  output << "]"
+         << "}";
+}
+
 ShockGroupsStatement::ShockGroupsStatement(const group_t &shock_groups_arg, const string &name_arg)
   : shock_groups(shock_groups_arg), name(name_arg)
 {
diff --git a/Shocks.hh b/Shocks.hh
index f89e1fba1ec51d035aa4707129c84c8e59720bb3..76f49ffe717980020c05952d910849f343b2419e 100644
--- a/Shocks.hh
+++ b/Shocks.hh
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003-2016 Dynare Team
+ * Copyright (C) 2003-2017 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -50,6 +50,7 @@ protected:
   const det_shocks_t det_shocks;
   const SymbolTable &symbol_table;
   void writeDetShocks(ostream &output) const;
+  void writeJsonDetShocks(ostream &output) const;
 
   AbstractShocksStatement(bool mshocks_arg, bool overwrite_arg,
                           const det_shocks_t &det_shocks_arg,
@@ -77,8 +78,9 @@ public:
                   const covar_and_corr_shocks_t &covar_shocks_arg,
                   const covar_and_corr_shocks_t &corr_shocks_arg,
                   const SymbolTable &symbol_table_arg);
-  virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
   virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings);
+  virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class MShocksStatement : public AbstractShocksStatement
@@ -120,6 +122,7 @@ public:
   MomentCalibration(const constraints_t &constraints_arg,
                     const SymbolTable &symbol_table_arg);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class IrfCalibration : public Statement
@@ -141,6 +144,7 @@ public:
                  const SymbolTable &symbol_table_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 ShockGroupsStatement : public Statement
diff --git a/Statement.cc b/Statement.cc
index ee18bbb835a88bbddd97c3422abb8076996bcef7..82ced98103a2c79022a7d75f7b710e91be531a62 100644
--- a/Statement.cc
+++ b/Statement.cc
@@ -109,6 +109,14 @@ NativeStatement::writeOutput(ostream &output, const string &basename, bool minim
   output << ns << endl;
 }
 
+void
+NativeStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"native\""
+         << ", \"string\": \"" << native_statement << "\""
+         << "}";
+}
+
 VerbatimStatement::VerbatimStatement(const string &verbatim_statement_arg) :
   verbatim_statement(verbatim_statement_arg)
 {
@@ -120,6 +128,14 @@ VerbatimStatement::writeOutput(ostream &output, const string &basename, bool min
   output << verbatim_statement << endl;
 }
 
+void
+VerbatimStatement::writeJsonOutput(ostream &output) const
+{
+  output << "{\"statementName\": \"verbatim\""
+         << ", \"string\": \"" << verbatim_statement << "\""
+         << "}";
+}
+
 void
 OptionsList::writeOutput(ostream &output) const
 {
@@ -213,6 +229,100 @@ OptionsList::writeOutput(ostream &output, const string &option_group) const
     }
 }
 
+void
+OptionsList::writeJsonOutput(ostream &output) const
+{
+  if (getNumberOfOptions() == 0)
+    return;
+
+  output << "\"options\": {";
+  for (num_options_t::const_iterator it = num_options.begin();
+       it != num_options.end();)
+    {
+      output << "\""<< it->first << "\": " << it->second;
+      it++;
+      if (it != num_options.end() ||
+          !(paired_num_options.empty() &&
+            string_options.empty() &&
+            date_options.empty() &&
+            symbol_list_options.empty() &&
+            vector_int_options.empty()))
+        output << ", ";
+    }
+
+  for (paired_num_options_t::const_iterator it = paired_num_options.begin();
+       it != paired_num_options.end();)
+    {
+      output << "\""<< it->first << "\": [" << it->second.first << " " << it->second.second << "]";
+      it++;
+      if (it != paired_num_options.end() ||
+          !(string_options.empty() &&
+            date_options.empty() &&
+            symbol_list_options.empty() &&
+            vector_int_options.empty()))
+        output << ", ";
+    }
+
+  for (string_options_t::const_iterator it = string_options.begin();
+       it != string_options.end();)
+    {
+      output << "\""<< it->first << "\": \"" << it->second << "\"";
+      it++;
+      if (it != string_options.end() ||
+          !(date_options.empty() &&
+            symbol_list_options.empty() &&
+            vector_int_options.empty()))
+        output << ", ";
+    }
+
+  for (date_options_t::const_iterator it = date_options.begin();
+       it != date_options.end();)
+    {
+      output << "\""<< it->first << "\": \"" << it->second << "\"";
+      it++;
+      if (it != date_options.end() ||
+          !(symbol_list_options.empty() &&
+            vector_int_options.empty()))
+        output << ", ";
+    }
+
+  for (symbol_list_options_t::const_iterator it = symbol_list_options.begin();
+       it != symbol_list_options.end(); it++)
+    {
+      output << "\""<< it->first << "\":";
+      it->second.writeJsonOutput(output);
+      it++;
+      if (it != symbol_list_options.end() ||
+          !vector_int_options.empty())
+        output << ", ";
+    }
+
+  for (vec_int_options_t::const_iterator it = vector_int_options.begin();
+       it != vector_int_options.end();)
+    {
+      output << "\""<< it->first << "\": [";
+      if (it->second.size() > 1)
+        {
+          for (vector<int>::const_iterator viit = it->second.begin();
+               viit != it->second.end();)
+            {
+              output << *viit;
+              viit++;
+              if (viit != it->second.end())
+                output << ", ";
+            }
+        }
+      else
+        output << it->second.front() << endl;
+      output << "]";
+      it++;
+      if (it != vector_int_options.end())
+        output << ", ";
+    }
+
+  output << "}";
+}
+
 void
 OptionsList::clear()
 {
@@ -223,3 +333,14 @@ OptionsList::clear()
   symbol_list_options.clear();
   vector_int_options.clear();
 }
+
+int
+OptionsList::getNumberOfOptions() const
+{
+  return num_options.size()
+    + paired_num_options.size()
+    + string_options.size()
+    + date_options.size()
+    + symbol_list_options.size()
+    + vector_int_options.size();
+}
diff --git a/Statement.hh b/Statement.hh
index 0db8a3c8c6dbb0761d310e548299bbd2df528fe4..54f13a76adaaff0960e6dfec4317478048d90e30 100644
--- a/Statement.hh
+++ b/Statement.hh
@@ -154,6 +154,7 @@ private:
 public:
   NativeStatement(const string &native_statement_arg);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class VerbatimStatement : public Statement
@@ -163,6 +164,7 @@ private:
 public:
   VerbatimStatement(const string &verbatim_statement_arg);
   virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const;
+  virtual void writeJsonOutput(ostream &output) const;
 };
 
 class OptionsList
@@ -180,8 +182,10 @@ public:
   date_options_t date_options;
   symbol_list_options_t symbol_list_options;
   vec_int_options_t vector_int_options;
+  int getNumberOfOptions() const;
   void writeOutput(ostream &output) const;
   void writeOutput(ostream &output, const string &option_group) const;
+  void writeJsonOutput(ostream &output) const;
   void clear();
 };
 
diff --git a/SymbolList.cc b/SymbolList.cc
index dca1410ece165ec8bd8a846d6e0763a6b2e837a1..d729f447d5609b89703197bfacedeafcd6d169f8 100644
--- a/SymbolList.cc
+++ b/SymbolList.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003-2014 Dynare Team
+ * Copyright (C) 2003-2017 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -39,6 +39,20 @@ SymbolList::writeOutput(const string &varname, ostream &output) const
   output << ");" << endl;
 }
 
+void
+SymbolList::writeJsonOutput(ostream &output) const
+{
+  output << "\"symbol_list\": [";
+  for (vector<string>::const_iterator it = symbols.begin();
+       it != symbols.end(); ++it)
+    {
+      if (it != symbols.begin())
+        output << ",";
+      output << "\"" << *it << "\"";
+    }
+  output << "]";
+}
+
 void
 SymbolList::clear()
 {
diff --git a/SymbolList.hh b/SymbolList.hh
index 82f0b79401ced40b14b26ea0fe2a240fc784567a..8ad5f9d26e5e7d2dd19210eb26d49b6c74287e9c 100644
--- a/SymbolList.hh
+++ b/SymbolList.hh
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003-2011 Dynare Team
+ * Copyright (C) 2003-2017 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -39,6 +39,8 @@ public:
   //! Output content in Matlab format
   /*! Creates a string array for Matlab, stored in variable "varname" */
   void writeOutput(const string &varname, ostream &output) const;
+  //! Write JSON output
+  void writeJsonOutput(ostream &output) const;
   //! Clears all content
   void clear();
   //! Get a copy of the string vector