diff --git a/configure.ac b/configure.ac
index fa8ff3264492b36ccecf54db7c3306a706949305..9dd20dadedda806d72135e70fdb8d793bd03a0f5 100755
--- a/configure.ac
+++ b/configure.ac
@@ -67,6 +67,8 @@ fi
 
 # We need 1.36 because of unordered_{set,hash} used by Dynare++
 AX_BOOST_BASE([1.36], [], [AC_MSG_ERROR([Can't find Boost >= 1.36])])
+AX_BOOST_SYSTEM
+AX_BOOST_FILESYSTEM
 
 CPPFLAGS_SAVED="$CPPFLAGS"
 CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
diff --git a/license.txt b/license.txt
index 6f4def8451b134156189b45944bb9c031768ce49..5b3687397b1009c22bac6378c116c92ded19b68d 100644
--- a/license.txt
+++ b/license.txt
@@ -17,8 +17,13 @@ Copyright: 1996-2018 Dynare Team
 License: GPL-3+
 
 Files: m4/ax_boost_base.m4
-Copyright: 2008 Thomas Porschberg <thomas@randspringer.de>
+       m4/ax_boost_system.m4
+       m4/ax_boost_filesystem.m4
+Copyright: 2008-2009 Thomas Porschberg <thomas@randspringer.de>
            2009 Peter Adolphs
+           2008-2009 Michael Tindal
+           2008 Daniel Casimiro <dan.casimiro@gmail.com>
+           2009 Roman Rybalko <libtorrent@romanr.info>
 License: permissive-autoconf
 
 Files: m4/ax_cxx_compile_stdcxx.m4
diff --git a/m4/ax_boost_filesystem.m4 b/m4/ax_boost_filesystem.m4
new file mode 100644
index 0000000000000000000000000000000000000000..f162163cdc600a69f77ea9d41443fc78ee194b00
--- /dev/null
+++ b/m4/ax_boost_filesystem.m4
@@ -0,0 +1,118 @@
+# ===========================================================================
+#    http://www.gnu.org/software/autoconf-archive/ax_boost_filesystem.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_BOOST_FILESYSTEM
+#
+# DESCRIPTION
+#
+#   Test for Filesystem library from the Boost C++ libraries. The macro
+#   requires a preceding call to AX_BOOST_BASE. Further documentation is
+#   available at <http://randspringer.de/boost/index.html>.
+#
+#   This macro calls:
+#
+#     AC_SUBST(BOOST_FILESYSTEM_LIB)
+#
+#   And sets:
+#
+#     HAVE_BOOST_FILESYSTEM
+#
+# LICENSE
+#
+#   Copyright (c) 2009 Thomas Porschberg <thomas@randspringer.de>
+#   Copyright (c) 2009 Michael Tindal
+#   Copyright (c) 2009 Roman Rybalko <libtorrent@romanr.info>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 26
+
+AC_DEFUN([AX_BOOST_FILESYSTEM],
+[
+	AC_ARG_WITH([boost-filesystem],
+	AS_HELP_STRING([--with-boost-filesystem@<:@=special-lib@:>@],
+                   [use the Filesystem library from boost - it is possible to specify a certain library for the linker
+                        e.g. --with-boost-filesystem=boost_filesystem-gcc-mt ]),
+        [
+        if test "$withval" = "no"; then
+			want_boost="no"
+        elif test "$withval" = "yes"; then
+            want_boost="yes"
+            ax_boost_user_filesystem_lib=""
+        else
+		    want_boost="yes"
+		ax_boost_user_filesystem_lib="$withval"
+		fi
+        ],
+        [want_boost="yes"]
+	)
+
+	if test "x$want_boost" = "xyes"; then
+        AC_REQUIRE([AC_PROG_CC])
+		CPPFLAGS_SAVED="$CPPFLAGS"
+		CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+		export CPPFLAGS
+
+		LDFLAGS_SAVED="$LDFLAGS"
+		LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
+		export LDFLAGS
+
+		LIBS_SAVED=$LIBS
+		LIBS="$LIBS $BOOST_SYSTEM_LIB"
+		export LIBS
+
+        AC_CACHE_CHECK(whether the Boost::Filesystem library is available,
+					   ax_cv_boost_filesystem,
+        [AC_LANG_PUSH([C++])
+         AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <boost/filesystem/path.hpp>]],
+                                   [[using namespace boost::filesystem;
+                                   path my_path( "foo/bar/data.txt" );
+                                   return 0;]])],
+					       ax_cv_boost_filesystem=yes, ax_cv_boost_filesystem=no)
+         AC_LANG_POP([C++])
+		])
+		if test "x$ax_cv_boost_filesystem" = "xyes"; then
+			AC_DEFINE(HAVE_BOOST_FILESYSTEM,,[define if the Boost::Filesystem library is available])
+            BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'`
+            if test "x$ax_boost_user_filesystem_lib" = "x"; then
+                for libextension in `ls -r $BOOSTLIBDIR/libboost_filesystem* 2>/dev/null | sed 's,.*/lib,,' | sed 's,\..*,,'` ; do
+                     ax_lib=${libextension}
+				    AC_CHECK_LIB($ax_lib, exit,
+                                 [BOOST_FILESYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_FILESYSTEM_LIB) link_filesystem="yes"; break],
+                                 [link_filesystem="no"])
+				done
+                if test "x$link_filesystem" != "xyes"; then
+                for libextension in `ls -r $BOOSTLIBDIR/boost_filesystem* 2>/dev/null | sed 's,.*/,,' | sed -e 's,\..*,,'` ; do
+                     ax_lib=${libextension}
+				    AC_CHECK_LIB($ax_lib, exit,
+                                 [BOOST_FILESYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_FILESYSTEM_LIB) link_filesystem="yes"; break],
+                                 [link_filesystem="no"])
+				done
+		    fi
+            else
+               for ax_lib in $ax_boost_user_filesystem_lib boost_filesystem-$ax_boost_user_filesystem_lib; do
+				      AC_CHECK_LIB($ax_lib, exit,
+                                   [BOOST_FILESYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_FILESYSTEM_LIB) link_filesystem="yes"; break],
+                                   [link_filesystem="no"])
+                  done
+
+            fi
+            if test "x$ax_lib" = "x"; then
+                AC_MSG_ERROR(Could not find a version of the library!)
+            fi
+			if test "x$link_filesystem" != "xyes"; then
+				AC_MSG_ERROR(Could not link against $ax_lib !)
+			fi
+		fi
+
+		CPPFLAGS="$CPPFLAGS_SAVED"
+		LDFLAGS="$LDFLAGS_SAVED"
+		LIBS="$LIBS_SAVED"
+	fi
+])
diff --git a/m4/ax_boost_system.m4 b/m4/ax_boost_system.m4
new file mode 100644
index 0000000000000000000000000000000000000000..43570a51384d9d709e0ef8ce27d964cf43b8b93f
--- /dev/null
+++ b/m4/ax_boost_system.m4
@@ -0,0 +1,121 @@
+# ===========================================================================
+#      http://www.gnu.org/software/autoconf-archive/ax_boost_system.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_BOOST_SYSTEM
+#
+# DESCRIPTION
+#
+#   Test for System library from the Boost C++ libraries. The macro requires
+#   a preceding call to AX_BOOST_BASE. Further documentation is available at
+#   <http://randspringer.de/boost/index.html>.
+#
+#   This macro calls:
+#
+#     AC_SUBST(BOOST_SYSTEM_LIB)
+#
+#   And sets:
+#
+#     HAVE_BOOST_SYSTEM
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de>
+#   Copyright (c) 2008 Michael Tindal
+#   Copyright (c) 2008 Daniel Casimiro <dan.casimiro@gmail.com>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 18
+
+AC_DEFUN([AX_BOOST_SYSTEM],
+[
+	AC_ARG_WITH([boost-system],
+	AS_HELP_STRING([--with-boost-system@<:@=special-lib@:>@],
+                   [use the System library from boost - it is possible to specify a certain library for the linker
+                        e.g. --with-boost-system=boost_system-gcc-mt ]),
+        [
+        if test "$withval" = "no"; then
+			want_boost="no"
+        elif test "$withval" = "yes"; then
+            want_boost="yes"
+            ax_boost_user_system_lib=""
+        else
+		    want_boost="yes"
+		ax_boost_user_system_lib="$withval"
+		fi
+        ],
+        [want_boost="yes"]
+	)
+
+	if test "x$want_boost" = "xyes"; then
+        AC_REQUIRE([AC_PROG_CC])
+        AC_REQUIRE([AC_CANONICAL_BUILD])
+		CPPFLAGS_SAVED="$CPPFLAGS"
+		CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
+		export CPPFLAGS
+
+		LDFLAGS_SAVED="$LDFLAGS"
+		LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
+		export LDFLAGS
+
+        AC_CACHE_CHECK(whether the Boost::System library is available,
+					   ax_cv_boost_system,
+        [AC_LANG_PUSH([C++])
+			 CXXFLAGS_SAVE=$CXXFLAGS
+			 CXXFLAGS=
+
+			 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <boost/system/error_code.hpp>]],
+				    [[boost::system::error_category *a = 0;]])],
+                   ax_cv_boost_system=yes, ax_cv_boost_system=no)
+			 CXXFLAGS=$CXXFLAGS_SAVE
+             AC_LANG_POP([C++])
+		])
+		if test "x$ax_cv_boost_system" = "xyes"; then
+			AC_SUBST(BOOST_CPPFLAGS)
+
+			AC_DEFINE(HAVE_BOOST_SYSTEM,,[define if the Boost::System library is available])
+            BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'`
+
+			LDFLAGS_SAVE=$LDFLAGS
+            if test "x$ax_boost_user_system_lib" = "x"; then
+                for libextension in `ls -r $BOOSTLIBDIR/libboost_system* 2>/dev/null | sed 's,.*/lib,,' | sed 's,\..*,,'` ; do
+                     ax_lib=${libextension}
+				    AC_CHECK_LIB($ax_lib, exit,
+                                 [BOOST_SYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_SYSTEM_LIB) link_system="yes"; break],
+                                 [link_system="no"])
+				done
+                if test "x$link_system" != "xyes"; then
+                for libextension in `ls -r $BOOSTLIBDIR/boost_system* 2>/dev/null | sed 's,.*/,,' | sed -e 's,\..*,,'` ; do
+                     ax_lib=${libextension}
+				    AC_CHECK_LIB($ax_lib, exit,
+                                 [BOOST_SYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_SYSTEM_LIB) link_system="yes"; break],
+                                 [link_system="no"])
+				done
+                fi
+
+            else
+               for ax_lib in $ax_boost_user_system_lib boost_system-$ax_boost_user_system_lib; do
+				      AC_CHECK_LIB($ax_lib, exit,
+                                   [BOOST_SYSTEM_LIB="-l$ax_lib"; AC_SUBST(BOOST_SYSTEM_LIB) link_system="yes"; break],
+                                   [link_system="no"])
+                  done
+
+            fi
+            if test "x$ax_lib" = "x"; then
+                AC_MSG_ERROR(Could not find a version of the library!)
+            fi
+			if test "x$link_system" = "xno"; then
+				AC_MSG_ERROR(Could not link against $ax_lib !)
+			fi
+		fi
+
+		CPPFLAGS="$CPPFLAGS_SAVED"
+	LDFLAGS="$LDFLAGS_SAVED"
+	fi
+])
diff --git a/src/ComputingTasks.cc b/src/ComputingTasks.cc
index 7e7d38f7c844e470f26fe1b8d105513f7a75d52e..1a4e335a710fcc2099cb3531599759bf429235d4 100644
--- a/src/ComputingTasks.cc
+++ b/src/ComputingTasks.cc
@@ -2274,7 +2274,7 @@ PlannerObjectiveStatement::computingPass()
 void
 PlannerObjectiveStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const
 {
-  model_tree->writeStaticFile(basename + "_objective", false, false, false, false);
+  model_tree->writeStaticFile(basename + ".objective", false, false, false, false);
 }
 
 void
diff --git a/src/DataTree.cc b/src/DataTree.cc
index 9dd438eec9bb847990dcc68efe1cd8ec73dafc82..ca7273c4a467607afb0b71811fa42a72135ec6c7 100644
--- a/src/DataTree.cc
+++ b/src/DataTree.cc
@@ -20,6 +20,9 @@
 #include <cstdlib>
 #include <cassert>
 #include <iostream>
+#include <regex>
+
+#include <boost/filesystem.hpp>
 
 #include "DataTree.hh"
 
@@ -776,3 +779,12 @@ DataTree::writeNormcdf(ostream &output) const
            << "#endif" << endl;
 #endif
 }
+
+string
+DataTree::packageDir(const string &package)
+{
+  regex pat{"\\."};
+  string dirname = "+" + regex_replace(package, pat, "/+");
+  boost::filesystem::create_directories(dirname);
+  return dirname;
+}
diff --git a/src/DataTree.hh b/src/DataTree.hh
index 612579af64f0bb2b41d57891e4d0e84efc52adc0..39c629ac6c44821e0e7e587435a2c53ba32392fc 100644
--- a/src/DataTree.hh
+++ b/src/DataTree.hh
@@ -109,6 +109,14 @@ protected:
 
   //! Internal implementation of ParamUsedWithLeadLag()
   bool ParamUsedWithLeadLagInternal() const;
+
+  /*! Takes a MATLAB/Octave package name (possibly with several levels nested using dots),
+    and returns the name of the corresponding filesystem directory (which
+    is created by the function if it does not exist).
+    In practice the package nesting is used for the planner_objective (stored
+    inside +objective subdir). */
+  static string packageDir(const string &package);
+
 private:
   using node_list_t = list<expr_t>;
   //! The list of nodes
diff --git a/src/DynamicModel.cc b/src/DynamicModel.cc
index 2785b7812ffe75fc586b2403c3ea0e3723ac22f6..3b3c450f7bb1230cd042fc49b7942ca87e95a1f6 100644
--- a/src/DynamicModel.cc
+++ b/src/DynamicModel.cc
@@ -26,16 +26,10 @@
 #include <algorithm>
 #include <iterator>
 #include <numeric>
-#include "DynamicModel.hh"
 
-// For mkdir() and chdir()
-#ifdef _WIN32
-# include <direct.h>
-#else
-# include <unistd.h>
-# include <sys/stat.h>
-# include <sys/types.h>
-#endif
+#include <boost/filesystem.hpp>
+
+#include "DynamicModel.hh"
 
 DynamicModel::DynamicModel(SymbolTable &symbol_table_arg,
                            NumericalConstants &num_constants_arg,
@@ -212,7 +206,7 @@ DynamicModel::computeTemporaryTermsMapping()
 }
 
 void
-DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const
+DynamicModel::writeModelEquationsOrdered_M(const string &basename) const
 {
   string tmp_s, sps;
   ostringstream tmp_output, tmp1_output, global_output;
@@ -325,7 +319,7 @@ DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const
         }
 
       tmp1_output.str("");
-      tmp1_output << dynamic_basename << "_" << block+1 << ".m";
+      tmp1_output << packageDir(basename + ".block") << "/dynamic_" << block+1 << ".m";
       output.open(tmp1_output.str().c_str(), ios::out | ios::binary);
       output << "%\n";
       output << "% " << tmp1_output.str() << " : Computes dynamic model for Dynare\n";
@@ -335,14 +329,14 @@ DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const
       output << "%/\n";
       if (simulation_type == EVALUATE_BACKWARD || simulation_type == EVALUATE_FORWARD)
         {
-          output << "function [y, g1, g2, g3, varargout] = " << dynamic_basename << "_" << block+1 << "(y, x, params, steady_state, jacobian_eval, y_kmin, periods)\n";
+          output << "function [y, g1, g2, g3, varargout] = dynamic_" << block+1 << "(y, x, params, steady_state, jacobian_eval, y_kmin, periods)\n";
         }
       else if (simulation_type == SOLVE_FORWARD_COMPLETE || simulation_type == SOLVE_BACKWARD_COMPLETE)
-        output << "function [residual, y, g1, g2, g3, varargout] = " << dynamic_basename << "_" << block+1 << "(y, x, params, steady_state, it_, jacobian_eval)\n";
+        output << "function [residual, y, g1, g2, g3, varargout] = dynamic_" << block+1 << "(y, x, params, steady_state, it_, jacobian_eval)\n";
       else if (simulation_type == SOLVE_BACKWARD_SIMPLE || simulation_type == SOLVE_FORWARD_SIMPLE)
-        output << "function [residual, y, g1, g2, g3, varargout] = " << dynamic_basename << "_" << block+1 << "(y, x, params, steady_state, it_, jacobian_eval)\n";
+        output << "function [residual, y, g1, g2, g3, varargout] = dynamic_" << block+1 << "(y, x, params, steady_state, it_, jacobian_eval)\n";
       else
-        output << "function [residual, y, g1, g2, g3, b, varargout] = " << dynamic_basename << "_" << block+1 << "(y, x, params, steady_state, periods, jacobian_eval, y_kmin, y_size, Periods)\n";
+        output << "function [residual, y, g1, g2, g3, b, varargout] = dynamic_" << block+1 << "(y, x, params, steady_state, periods, jacobian_eval, y_kmin, y_size, Periods)\n";
       BlockType block_type;
       if (simulation_type == SOLVE_TWO_BOUNDARIES_COMPLETE || simulation_type == SOLVE_TWO_BOUNDARIES_SIMPLE)
         block_type = SIMULTAN;
@@ -790,16 +784,17 @@ DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const
 }
 
 void
-DynamicModel::writeModelEquationsCode(string &file_name, const string &bin_basename, const map_idx_t &map_idx) const
+DynamicModel::writeModelEquationsCode(const string &basename, const map_idx_t &map_idx) const
 {
 
   ostringstream tmp_output;
   ofstream code_file;
   unsigned int instruction_number = 0;
   bool file_open = false;
-  string main_name = file_name;
 
-  main_name += ".cod";
+  boost::filesystem::create_directories(basename + "/model/bytecode");
+
+  string main_name = basename + "/model/bytecode/dynamic.cod";
   code_file.open(main_name.c_str(), ios::out | ios::binary | ios::ate);
   if (!code_file.is_open())
     {
@@ -817,7 +812,7 @@ DynamicModel::writeModelEquationsCode(string &file_name, const string &bin_basen
   else
     simulation_type = SOLVE_BACKWARD_COMPLETE;
 
-  Write_Inf_To_Bin_File(file_name, u_count_int, file_open, simulation_type == SOLVE_TWO_BOUNDARIES_COMPLETE, symbol_table.endo_nbr());
+  Write_Inf_To_Bin_File(basename + "/model/bytecode/dynamic.bin", u_count_int, file_open, simulation_type == SOLVE_TWO_BOUNDARIES_COMPLETE, symbol_table.endo_nbr());
   file_open = true;
 
   //Temporary variables declaration
@@ -1046,7 +1041,7 @@ DynamicModel::writeModelEquationsCode(string &file_name, const string &bin_basen
 }
 
 void
-DynamicModel::writeModelEquationsCode_Block(string &file_name, const string &bin_basename, const map_idx_t &map_idx) const
+DynamicModel::writeModelEquationsCode_Block(const string &basename, const map_idx_t &map_idx) const
 {
   struct Uff_l
   {
@@ -1072,8 +1067,9 @@ DynamicModel::writeModelEquationsCode_Block(string &file_name, const string &bin
   vector<int> feedback_variables;
   bool file_open = false;
 
-  string main_name = file_name;
-  main_name += ".cod";
+  boost::filesystem::create_directories(basename + "/model/bytecode");
+
+  string main_name = basename + "/model/bytecode/dynamic.cod";
   code_file.open(main_name.c_str(), ios::out | ios::binary | ios::ate);
   if (!code_file.is_open())
     {
@@ -1105,7 +1101,7 @@ DynamicModel::writeModelEquationsCode_Block(string &file_name, const string &bin
       if (simulation_type == SOLVE_TWO_BOUNDARIES_SIMPLE || simulation_type == SOLVE_TWO_BOUNDARIES_COMPLETE
           || simulation_type == SOLVE_BACKWARD_COMPLETE || simulation_type == SOLVE_FORWARD_COMPLETE)
         {
-          Write_Inf_To_Bin_File_Block(file_name, bin_basename, block, u_count_int, file_open,
+          Write_Inf_To_Bin_File_Block(basename, block, u_count_int, file_open,
                                       simulation_type == SOLVE_TWO_BOUNDARIES_COMPLETE || simulation_type == SOLVE_TWO_BOUNDARIES_SIMPLE);
           file_open = true;
         }
@@ -1516,9 +1512,9 @@ DynamicModel::writeModelEquationsCode_Block(string &file_name, const string &bin
 }
 
 void
-DynamicModel::writeDynamicMFile(const string &dynamic_basename) const
+DynamicModel::writeDynamicMFile(const string &basename) const
 {
-  writeDynamicModel(dynamic_basename, false, false);
+  writeDynamicModel(basename, false, false);
 }
 
 void
@@ -1556,10 +1552,11 @@ DynamicModel::writeDynamicJuliaFile(const string &basename) const
 }
 
 void
-DynamicModel::writeDynamicCFile(const string &dynamic_basename, const int order) const
+DynamicModel::writeDynamicCFile(const string &basename, const int order) const
 {
-  string filename = dynamic_basename + ".c";
-  string filename_mex = dynamic_basename + "_mex.c";
+  boost::filesystem::create_directories(basename + "/model/src");
+  string filename = basename + "/model/src/dynamic.c";
+  string filename_mex = basename + "/model/src/dynamic_mex.c";
   ofstream mDynamicModelFile, mDynamicMexFile;
 
   mDynamicModelFile.open(filename.c_str(), ios::out | ios::binary);
@@ -1743,18 +1740,19 @@ DynamicModel::setNonZeroHessianEquations(map<int, string> &eqs)
 }
 
 void
-DynamicModel::Write_Inf_To_Bin_File_Block(const string &dynamic_basename, const string &bin_basename, const int &num,
+DynamicModel::Write_Inf_To_Bin_File_Block(const string &basename, const int &num,
                                           int &u_count_int, bool &file_open, bool is_two_boundaries) const
 {
   int j;
   std::ofstream SaveCode;
+  string filename = basename + "/model/bytecode/dynamic.bin";
   if (file_open)
-    SaveCode.open((bin_basename + "_dynamic.bin").c_str(), ios::out | ios::in | ios::binary | ios::ate);
+    SaveCode.open(filename, ios::out | ios::in | ios::binary | ios::ate);
   else
-    SaveCode.open((bin_basename + "_dynamic.bin").c_str(), ios::out | ios::binary);
+    SaveCode.open(filename, ios::out | ios::binary);
   if (!SaveCode.is_open())
     {
-      cerr << "Error : Can't open file \"" << bin_basename << "_dynamic.bin\" for writing" << endl;
+      cerr << "Error : Can't open file \"" << filename << "\" for writing" << endl;
       exit(EXIT_FAILURE);
     }
   u_count_int = 0;
@@ -1797,14 +1795,13 @@ DynamicModel::Write_Inf_To_Bin_File_Block(const string &dynamic_basename, const
 }
 
 void
-DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const string &basename) const
+DynamicModel::writeSparseDynamicMFile(const string &basename) const
 {
   string sp;
   ofstream mDynamicModelFile;
   ostringstream tmp, tmp1, tmp_eq;
   bool OK;
-  chdir(basename.c_str());
-  string filename = dynamic_basename + ".m";
+  string filename = packageDir(basename) + "/dynamic.m";
   mDynamicModelFile.open(filename.c_str(), ios::out | ios::binary);
   if (!mDynamicModelFile.is_open())
     {
@@ -1821,7 +1818,7 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
   int Nb_SGE = 0;
   bool open_par = false;
 
-  mDynamicModelFile << "function [varargout] = " << dynamic_basename << "(options_, M_, oo_, varargin)\n";
+  mDynamicModelFile << "function [varargout] = dynamic(options_, M_, oo_, varargin)\n";
   mDynamicModelFile << "  g2=[];g3=[];\n";
   //Temporary variables declaration
   OK = true;
@@ -1898,22 +1895,22 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
         {
         case EVALUATE_FORWARD:
         case EVALUATE_BACKWARD:
-          mDynamicModelFile << "    [y, dr(" << count_call << ").g1, dr(" << count_call << ").g2, dr(" << count_call << ").g3, dr(" << count_call << ").g1_x, dr(" << count_call << ").g1_xd, dr(" << count_call << ").g1_o]=" << dynamic_basename << "_" << block + 1 << "(y, x, params, steady_state, 1, it_-1, 1);\n";
+          mDynamicModelFile << "    [y, dr(" << count_call << ").g1, dr(" << count_call << ").g2, dr(" << count_call << ").g3, dr(" << count_call << ").g1_x, dr(" << count_call << ").g1_xd, dr(" << count_call << ").g1_o]=" << basename << ".block.dynamic_" << block + 1 << "(y, x, params, steady_state, 1, it_-1, 1);\n";
           mDynamicModelFile << "    residual(y_index_eq)=ys(y_index)-y(it_, y_index);\n";
           break;
         case SOLVE_FORWARD_SIMPLE:
         case SOLVE_BACKWARD_SIMPLE:
-          mDynamicModelFile << "    [r, y, dr(" << count_call << ").g1, dr(" << count_call << ").g2, dr(" << count_call << ").g3, dr(" << count_call << ").g1_x, dr(" << count_call << ").g1_xd, dr(" << count_call << ").g1_o]=" << dynamic_basename << "_" << block + 1 << "(y, x, params, steady_state, it_, 1);\n";
+          mDynamicModelFile << "    [r, y, dr(" << count_call << ").g1, dr(" << count_call << ").g2, dr(" << count_call << ").g3, dr(" << count_call << ").g1_x, dr(" << count_call << ").g1_xd, dr(" << count_call << ").g1_o]=" << basename << ".block.dynamic_" << block + 1 << "(y, x, params, steady_state, it_, 1);\n";
           mDynamicModelFile << "    residual(y_index_eq)=r;\n";
           break;
         case SOLVE_FORWARD_COMPLETE:
         case SOLVE_BACKWARD_COMPLETE:
-          mDynamicModelFile << "    [r, y, dr(" << count_call << ").g1, dr(" << count_call << ").g2, dr(" << count_call << ").g3, dr(" << count_call << ").g1_x, dr(" << count_call << ").g1_xd, dr(" << count_call << ").g1_o]=" << dynamic_basename << "_" << block + 1 << "(y, x, params, steady_state, it_, 1);\n";
+          mDynamicModelFile << "    [r, y, dr(" << count_call << ").g1, dr(" << count_call << ").g2, dr(" << count_call << ").g3, dr(" << count_call << ").g1_x, dr(" << count_call << ").g1_xd, dr(" << count_call << ").g1_o]=" << basename << ".block.dynamic_" << block + 1 << "(y, x, params, steady_state, it_, 1);\n";
           mDynamicModelFile << "    residual(y_index_eq)=r;\n";
           break;
         case SOLVE_TWO_BOUNDARIES_COMPLETE:
         case SOLVE_TWO_BOUNDARIES_SIMPLE:
-          mDynamicModelFile << "    [r, y, dr(" << count_call << ").g1, dr(" << count_call << ").g2, dr(" << count_call << ").g3, b, dr(" << count_call << ").g1_x, dr(" << count_call << ").g1_xd, dr(" << count_call << ").g1_o]=" << dynamic_basename << "_" <<  block + 1 << "(y, x, params, steady_state, it_-" << max_lag << ", 1, " << max_lag << ", " << block_recursive << "," << "options_.periods" << ");\n";
+          mDynamicModelFile << "    [r, y, dr(" << count_call << ").g1, dr(" << count_call << ").g2, dr(" << count_call << ").g3, b, dr(" << count_call << ").g1_x, dr(" << count_call << ").g1_xd, dr(" << count_call << ").g1_o]=" << basename << ".block.dynamic_" <<  block + 1 << "(y, x, params, steady_state, it_-" << max_lag << ", 1, " << max_lag << ", " << block_recursive << "," << "options_.periods" << ");\n";
           mDynamicModelFile << "    residual(y_index_eq)=r(:,M_.maximum_lag+1);\n";
           break;
         default:
@@ -1984,7 +1981,7 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
           mDynamicModelFile << "  oo_.deterministic_simulation.block(blck_num).error = 0;\n";
           mDynamicModelFile << "  oo_.deterministic_simulation.block(blck_num).iterations = 0;\n";
           mDynamicModelFile << "  g1=[];g2=[];g3=[];\n";
-          mDynamicModelFile << "  y=" << dynamic_basename << "_" << block + 1 << "(y, x, params, steady_state, 0, y_kmin, periods);\n";
+          mDynamicModelFile << "  y=" << basename << ".block.dynamic_" << block + 1 << "(y, x, params, steady_state, 0, y_kmin, periods);\n";
           mDynamicModelFile << "  tmp = y(:,M_.block_structure.block(" << block + 1 << ").variable);\n";
           mDynamicModelFile << "  if any(isnan(tmp) | isinf(tmp))\n";
           mDynamicModelFile << "    disp(['Inf or Nan value during the evaluation of block " << block <<"']);\n";
@@ -2012,7 +2009,7 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
           mDynamicModelFile << "  oo_.deterministic_simulation.block(blck_num).error = 0;\n";
           mDynamicModelFile << "  oo_.deterministic_simulation.block(blck_num).iterations = 0;\n";
           mDynamicModelFile << "  g1=[];g2=[];g3=[];\n";
-          mDynamicModelFile << "  " << dynamic_basename << "_" << block + 1 << "(y, x, params, steady_state, 0, y_kmin, periods);\n";
+          mDynamicModelFile << "  " << basename << ".block.dynamic_" << block + 1 << "(y, x, params, steady_state, 0, y_kmin, periods);\n";
           mDynamicModelFile << "  tmp = y(:,M_.block_structure.block(" << block + 1 << ").variable);\n";
           mDynamicModelFile << "  if any(isnan(tmp) | isinf(tmp))\n";
           mDynamicModelFile << "    disp(['Inf or Nan value during the evaluation of block " << block <<"']);\n";
@@ -2041,7 +2038,7 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
           mDynamicModelFile << "  else\n";
           mDynamicModelFile << "    blck_num = 1;\n";
           mDynamicModelFile << "  end;\n";
-          mDynamicModelFile << "  y = solve_one_boundary('"  << dynamic_basename << "_" <<  block + 1 << "'"
+          mDynamicModelFile << "  y = solve_one_boundary('" << basename << ".block.dynamic_" <<  block + 1 << "'"
                             <<", y, x, params, steady_state, y_index, " << nze
                             <<", options_.periods, " << blocks_linear[block]
                             <<", blck_num, y_kmin, options_.simul.maxit, options_.solve_tolf, options_.slowc, " << cutoff << ", options_.stack_solve_algo, 1, 1, 0);\n";
@@ -2074,7 +2071,7 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
           mDynamicModelFile << "  else\n";
           mDynamicModelFile << "    blck_num = 1;\n";
           mDynamicModelFile << "  end;\n";
-          mDynamicModelFile << "  y = solve_one_boundary('"  << dynamic_basename << "_" <<  block + 1 << "'"
+          mDynamicModelFile << "  y = solve_one_boundary('" << basename << ".block.dynamic_" <<  block + 1 << "'"
                             <<", y, x, params, steady_state, y_index, " << nze
                             <<", options_.periods, " << blocks_linear[block]
                             <<", blck_num, y_kmin, options_.simul.maxit, options_.solve_tolf, options_.slowc, " << cutoff << ", options_.stack_solve_algo, 1, 1, 0);\n";
@@ -2105,7 +2102,7 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
           mDynamicModelFile << "  else\n";
           mDynamicModelFile << "    blck_num = 1;\n";
           mDynamicModelFile << "  end;\n";
-          mDynamicModelFile << "  [y oo_] = solve_two_boundaries('" << dynamic_basename << "_" <<  block + 1 << "'"
+          mDynamicModelFile << "  [y oo_] = solve_two_boundaries('" << basename << ".block.dynamic_" <<  block + 1 << "'"
                             <<", y, x, params, steady_state, y_index, " << nze
                             <<", options_.periods, " << max_leadlag_block[block].first
                             <<", " << max_leadlag_block[block].second
@@ -2131,9 +2128,7 @@ DynamicModel::writeSparseDynamicMFile(const string &dynamic_basename, const stri
 
   mDynamicModelFile.close();
 
-  writeModelEquationsOrdered_M(dynamic_basename);
-
-  chdir("..");
+  writeModelEquationsOrdered_M(basename);
 }
 
 void
@@ -2141,13 +2136,13 @@ DynamicModel::writeWrapperFunctions(const string &basename, const string &ending
 {
   string name;
   if (ending == "g1")
-    name = basename + "_resid_g1";
+    name = "dynamic_resid_g1";
   else if (ending == "g2")
-    name= basename + "_resid_g1_g2";
+    name= "dynamic_resid_g1_g2";
   else if (ending == "g3")
-    name = basename + "_resid_g1_g2_g3";
+    name = "dynamic_resid_g1_g2_g3";
 
-  string filename = name + ".m";
+  string filename = packageDir(basename) + "/" + name + ".m";
   ofstream output;
   output.open(filename.c_str(), ios::out | ios::binary);
   if (!output.is_open())
@@ -2171,32 +2166,33 @@ DynamicModel::writeWrapperFunctions(const string &basename, const string &ending
          << "%" << endl
          << endl
          << "    if T_flag" << endl
-         << "        T = " << basename + "_" + ending + "_tt(T, y, x, params, steady_state, it_);" << endl
+         << "        T = " << basename << ".dynamic_" << ending << "_tt(T, y, x, params, steady_state, it_);" << endl
          << "    end" << endl;
 
   if (ending == "g1")
-    output << "    residual = " << basename + "_resid(T, y, x, params, steady_state, it_, false);" << endl
-           << "    g1       = " << basename + "_g1(T, y, x, params, steady_state, it_, false);" << endl;
+    output << "    residual = " << basename << ".dynamic_resid(T, y, x, params, steady_state, it_, false);" << endl
+           << "    g1       = " << basename << ".dynamic_g1(T, y, x, params, steady_state, it_, false);" << endl;
   else if (ending == "g2")
-    output << "    [residual, g1] = " << basename + "_resid_g1(T, y, x, params, steady_state, it_, false);" << endl
-           << "    g2       = " << basename + "_g2(T, y, x, params, steady_state, it_, false);" << endl;
+    output << "    [residual, g1] = " << basename << ".dynamic_resid_g1(T, y, x, params, steady_state, it_, false);" << endl
+           << "    g2       = " << basename << ".dynamic_g2(T, y, x, params, steady_state, it_, false);" << endl;
   else if (ending == "g3")
-    output << "    [residual, g1, g2] = " << basename + "_resid_g1_g2(T, y, x, params, steady_state, it_, false);" << endl
-           << "    g3       = " << basename + "_g3(T, y, x, params, steady_state, it_, false);" << endl;
+    output << "    [residual, g1, g2] = " << basename << ".dynamic_resid_g1_g2(T, y, x, params, steady_state, it_, false);" << endl
+           << "    g3       = " << basename << ".dynamic_g3(T, y, x, params, steady_state, it_, false);" << endl;
 
   output << endl << "end" << endl;
   output.close();
 }
 
 void
-DynamicModel::writeDynamicModelHelper(const string &name, const string &retvalname,
+DynamicModel::writeDynamicModelHelper(const string &basename,
+                                      const string &name, const string &retvalname,
                                       const string &name_tt, size_t ttlen,
                                       const string &previous_tt_name,
                                       const ostringstream &init_s,
                                       const ostringstream &end_s,
                                       const ostringstream &s, const ostringstream &s_tt) const
 {
-  string filename =  name_tt + ".m";
+  string filename = packageDir(basename) + "/" + name_tt + ".m";
   ofstream output;
   output.open(filename.c_str(), ios::out | ios::binary);
   if (!output.is_open())
@@ -2228,13 +2224,13 @@ DynamicModel::writeDynamicModelHelper(const string &name, const string &retvalna
          << endl;
 
   if (!previous_tt_name.empty())
-    output << "T = " << previous_tt_name << "(T, y, x, params, steady_state, it_);" << endl << endl;
+    output << "T = " << basename << "." << previous_tt_name << "(T, y, x, params, steady_state, it_);" << endl << endl;
 
   output << s_tt.str() << endl
          << "end" << endl;
   output.close();
 
-  filename = name + ".m";
+  filename = packageDir(basename) + "/" + name + ".m";
   output.open(filename.c_str(), ios::out | ios::binary);
   if (!output.is_open())
     {
@@ -2265,7 +2261,7 @@ DynamicModel::writeDynamicModelHelper(const string &name, const string &retvalna
 
   if (!name_tt.empty())
     output << "if T_flag" << endl
-           << "    T = " << name_tt << "(T, y, x, params, steady_state, it_);" << endl
+           << "    T = " << basename << "." << name_tt << "(T, y, x, params, steady_state, it_);" << endl
            << "end" << endl;
 
   output << init_s.str() << endl
@@ -2276,9 +2272,9 @@ DynamicModel::writeDynamicModelHelper(const string &name, const string &retvalna
 }
 
 void
-DynamicModel::writeDynamicMatlabCompatLayer(const string &name) const
+DynamicModel::writeDynamicMatlabCompatLayer(const string &basename) const
 {
-  string filename = name + ".m";
+  string filename = packageDir(basename) + "/dynamic.m";
   ofstream output;
   output.open(filename.c_str(), ios::out | ios::binary);
   if (!output.is_open())
@@ -2288,16 +2284,16 @@ DynamicModel::writeDynamicMatlabCompatLayer(const string &name) const
     }
   int ntt = temporary_terms_mlv.size() + temporary_terms_res.size() + temporary_terms_g1.size() + temporary_terms_g2.size() + temporary_terms_g3.size();
 
-  output << "function [residual, g1, g2, g3] = " << name << "(y, x, params, steady_state, it_)" << endl
+  output << "function [residual, g1, g2, g3] = dynamic(y, x, params, steady_state, it_)" << endl
          << "    T = NaN(" << ntt << ", 1);" << endl
          << "    if nargout <= 1" << endl
-         << "        residual = " << name << "_resid(T, y, x, params, steady_state, it_, true);" << endl
+         << "        residual = " << basename << ".dynamic_resid(T, y, x, params, steady_state, it_, true);" << endl
          << "    elseif nargout == 2" << endl
-         << "        [residual, g1] = " << name << "_resid_g1(T, y, x, params, steady_state, it_, true);" << endl
+         << "        [residual, g1] = " << basename << ".dynamic_resid_g1(T, y, x, params, steady_state, it_, true);" << endl
          << "    elseif nargout == 3" << endl
-         << "        [residual, g1, g2] = " << name << "_resid_g1_g2(T, y, x, params, steady_state, it_, true);" << endl
+         << "        [residual, g1, g2] = " << basename << ".dynamic_resid_g1_g2(T, y, x, params, steady_state, it_, true);" << endl
          << "    else" << endl
-         << "        [residual, g1, g2, g3] = " << name << "_resid_g1_g2_g3(T, y, x, params, steady_state, it_, true);" << endl
+         << "        [residual, g1, g2, g3] = " << basename << ".dynamic_resid_g1_g2_g3(T, y, x, params, steady_state, it_, true);" << endl
          << "    end" << endl
          << "end" << endl;
 
@@ -2311,14 +2307,14 @@ DynamicModel::writeDynamicModel(ostream &DynamicOutput, bool use_dll, bool julia
 }
 
 void
-DynamicModel::writeDynamicModel(const string &dynamic_basename, bool use_dll, bool julia) const
+DynamicModel::writeDynamicModel(const string &basename, bool use_dll, bool julia) const
 {
   ofstream DynamicOutput;
-  writeDynamicModel(dynamic_basename, DynamicOutput, use_dll, julia);
+  writeDynamicModel(basename, DynamicOutput, use_dll, julia);
 }
 
 void
-DynamicModel::writeDynamicModel(const string &dynamic_basename, ostream &DynamicOutput, bool use_dll, bool julia) const
+DynamicModel::writeDynamicModel(const string &basename, ostream &DynamicOutput, bool use_dll, bool julia) const
 {
   ostringstream model_tt_output;             // Used for storing model temp vars
   ostringstream model_output;                // Used for storing model equations
@@ -2538,8 +2534,8 @@ DynamicModel::writeDynamicModel(const string &dynamic_basename, ostream &Dynamic
 
       ostringstream init_output, end_output;
       init_output << "residual = zeros(" << nrows << ", 1);";
-      writeDynamicModelHelper(dynamic_basename + "_resid", "residual",
-                              dynamic_basename + "_resid_tt",
+      writeDynamicModelHelper(basename, "dynamic_resid", "residual",
+                              "dynamic_resid_tt",
                               temporary_terms_mlv.size() + temporary_terms_res.size(),
                               "", init_output, end_output,
                               model_output, model_tt_output);
@@ -2547,13 +2543,13 @@ DynamicModel::writeDynamicModel(const string &dynamic_basename, ostream &Dynamic
       init_output.str(string());
       init_output.clear();
       init_output << "g1 = zeros(" << nrows << ", " << dynJacobianColsNbr << ");";
-      writeDynamicModelHelper(dynamic_basename + "_g1", "g1",
-                              dynamic_basename + "_g1_tt",
+      writeDynamicModelHelper(basename, "dynamic_g1", "g1",
+                              "dynamic_g1_tt",
                               temporary_terms_mlv.size() + temporary_terms_res.size() + temporary_terms_g1.size(),
-                              dynamic_basename + "_resid_tt",
+                              "dynamic_resid_tt",
                               init_output, end_output,
                               jacobian_output, jacobian_tt_output);
-      writeWrapperFunctions(dynamic_basename, "g1");
+      writeWrapperFunctions(basename, "g1");
 
       init_output.str(string());
       init_output.clear();
@@ -2564,14 +2560,14 @@ DynamicModel::writeDynamicModel(const string &dynamic_basename, ostream &Dynamic
         }
       else
         init_output << "g2 = sparse([],[],[]," << nrows << "," << hessianColsNbr << ");";
-      writeDynamicModelHelper(dynamic_basename + "_g2", "g2",
-                              dynamic_basename + "_g2_tt",
+      writeDynamicModelHelper(basename, "dynamic_g2", "g2",
+                              "dynamic_g2_tt",
                               temporary_terms_mlv.size() + temporary_terms_res.size() + temporary_terms_g1.size()
                               + temporary_terms_g2.size(),
-                              dynamic_basename + "_g1_tt",
+                              "dynamic_g1_tt",
                               init_output, end_output,
                               hessian_output, hessian_tt_output);
-      writeWrapperFunctions(dynamic_basename, "g2");
+      writeWrapperFunctions(basename, "g2");
 
       init_output.str(string());
       init_output.clear();
@@ -2585,16 +2581,16 @@ DynamicModel::writeDynamicModel(const string &dynamic_basename, ostream &Dynamic
         }
       else
         init_output << "g3 = sparse([],[],[]," << nrows << "," << ncols << ");";
-      writeDynamicModelHelper(dynamic_basename + "_g3", "g3",
-                              dynamic_basename + "_g3_tt",
+      writeDynamicModelHelper(basename, "dynamic_g3", "g3",
+                              "dynamic_g3_tt",
                               temporary_terms_mlv.size() + temporary_terms_res.size() + temporary_terms_g1.size()
                               + temporary_terms_g2.size() + temporary_terms_g3.size(),
-                              dynamic_basename + "_g2_tt",
+                              "dynamic_g2_tt",
                               init_output, end_output,
                               third_derivatives_output, third_derivatives_tt_output);
-      writeWrapperFunctions(dynamic_basename, "g3");
+      writeWrapperFunctions(basename, "g3");
 
-      writeDynamicMatlabCompatLayer(dynamic_basename);
+      writeDynamicMatlabCompatLayer(basename);
     }
   else if (output_type == oCDynamicModel)
     {
@@ -2635,7 +2631,7 @@ DynamicModel::writeDynamicModel(const string &dynamic_basename, ostream &Dynamic
     }
   else
     {
-      string filename =  dynamic_basename + "Dynamic.jl";
+      string filename = basename + "Dynamic.jl";
       ofstream output;
       output.open(filename.c_str(), ios::out | ios::binary);
       if (!output.is_open())
@@ -2644,10 +2640,10 @@ DynamicModel::writeDynamicModel(const string &dynamic_basename, ostream &Dynamic
           exit(EXIT_FAILURE);
         }
 
-      output << "module " << dynamic_basename << "Dynamic" << endl
+      output << "module " << basename << "Dynamic" << endl
              << "#" << endl
              << "# NB: this file was automatically generated by Dynare" << endl
-             << "#     from " << dynamic_basename << ".mod" << endl
+             << "#     from " << basename << ".mod" << endl
              << "#" << endl
              << "using Utils" << endl << endl
              << "export tmp_nbr, dynamic!, dynamicResid!, dynamicG1!, dynamicG2!, dynamicG3!" << endl << endl
@@ -3262,8 +3258,8 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block_de
       if (estimation_present)
         {
           ofstream KF_index_file;
-          string main_name = basename;
-          main_name += ".kfi";
+          boost::filesystem::create_directories(basename + "/model/bytecode");
+          string main_name = basename + "/model/bytecode/kfi";
           KF_index_file.open(main_name.c_str(), ios::out | ios::binary | ios::ate);
           int n_obs = symbol_table.observedVariablesNbr();
           int n_state = state_var.size();
@@ -4342,34 +4338,20 @@ DynamicModel::collectBlockVariables()
 void
 DynamicModel::writeDynamicFile(const string &basename, bool block, bool bytecode, bool use_dll, int order, bool julia) const
 {
-  int r;
-  string t_basename = basename + "_dynamic";
   if (block && bytecode)
-    writeModelEquationsCode_Block(t_basename, basename, map_idx);
+    writeModelEquationsCode_Block(basename, map_idx);
   else if (!block && bytecode)
-    writeModelEquationsCode(t_basename, basename, map_idx);
+    writeModelEquationsCode(basename, map_idx);
   else if (block && !bytecode)
-    {
-#ifdef _WIN32
-      r = mkdir(basename.c_str());
-#else
-      r = mkdir(basename.c_str(), 0777);
-#endif
-      if (r < 0 && errno != EEXIST)
-        {
-          perror("ERROR");
-          exit(EXIT_FAILURE);
-        }
-      writeSparseDynamicMFile(t_basename, basename);
-    }
+    writeSparseDynamicMFile(basename);
   else if (use_dll)
-    writeDynamicCFile(t_basename, order);
+    writeDynamicCFile(basename, order);
   else if (julia)
     writeDynamicJuliaFile(basename);
   else
     {
-      writeDynamicMFile(t_basename);
-      writeSetAuxiliaryVariables(t_basename, julia);
+      writeDynamicMFile(basename);
+      writeSetAuxiliaryVariables(basename, julia);
     }
 }
 
@@ -4382,8 +4364,8 @@ DynamicModel::writeSetAuxiliaryVariables(const string &basename, const bool juli
   if (output_func_body.str().empty())
     return;
 
-  string func_name = basename + "_set_auxiliary_series";
-  string filename = julia ? func_name + ".jl" : func_name + ".m";
+  string func_name = julia ? basename + "_dynamic_set_auxiliary_series" : "dynamic_set_auxiliary_series";
+  string filename = julia ? func_name + ".jl" : packageDir(basename) + "/" + func_name + ".m";
   string comment = julia ? "#" : "%";
 
   ofstream output;
@@ -5030,7 +5012,7 @@ DynamicModel::writeParamsDerivativesFile(const string &basename, bool julia) con
       i++;
     }
 
-  string filename = julia ? basename + "DynamicParamsDerivs.jl" : basename + "_params_derivs.m";
+  string filename = julia ? basename + "DynamicParamsDerivs.jl" : packageDir(basename) + "/dynamic_params_derivs.m";
   ofstream paramsDerivsFile;
   paramsDerivsFile.open(filename.c_str(), ios::out | ios::binary);
   if (!paramsDerivsFile.is_open())
@@ -5051,7 +5033,7 @@ DynamicModel::writeParamsDerivativesFile(const string &basename, bool julia) con
       fixNestedParenthesis(hessian1_output, tmp_paren_vars, message_printed);
       fixNestedParenthesis(third_derivs_output, tmp_paren_vars, message_printed);
       fixNestedParenthesis(third_derivs1_output, tmp_paren_vars, message_printed);
-      paramsDerivsFile << "function [rp, gp, rpp, gpp, hp] = " << basename << "_params_derivs(y, x, params, steady_state, it_, ss_param_deriv, ss_param_2nd_deriv)" << endl
+      paramsDerivsFile << "function [rp, gp, rpp, gpp, hp] = dynamic_params_derivs(y, x, params, steady_state, it_, ss_param_deriv, ss_param_2nd_deriv)" << endl
                        << "%" << endl
                        << "% Compute the derivatives of the dynamic model with respect to the parameters" << endl
                        << "% Inputs :" << endl
@@ -5737,20 +5719,7 @@ DynamicModel::isChecksumMatching(const string &basename) const
       result.process_bytes(private_buffer, strlen(private_buffer));
     }
 
-  bool basename_dir_exists = false;
-#ifdef _WIN32
-  int r = mkdir(basename.c_str());
-#else
-  int r = mkdir(basename.c_str(), 0777);
-#endif
-  if (r < 0)
-    if (errno != EEXIST)
-      {
-        perror("ERROR");
-        exit(EXIT_FAILURE);
-      }
-    else
-      basename_dir_exists = true;
+  bool basename_dir_exists = !boost::filesystem::create_directory(basename);
 
   // check whether basename directory exist. If not, create it.
   // If it does, read old checksum if it exist
diff --git a/src/DynamicModel.hh b/src/DynamicModel.hh
index 2d64b422d0ae7dd2173b375834eaa724f8df341d..79c726ce2d3cf3816c6acbdd79e35c54ce2a4dbd 100644
--- a/src/DynamicModel.hh
+++ b/src/DynamicModel.hh
@@ -96,27 +96,27 @@ private:
   first_chain_rule_derivatives_t first_chain_rule_derivatives;
 
   //! Writes dynamic model file (Matlab version)
-  void writeDynamicMFile(const string &dynamic_basename) const;
+  void writeDynamicMFile(const string &basename) const;
   //! Writes dynamic model file (Julia version)
   void writeDynamicJuliaFile(const string &dynamic_basename) const;
   //! Write Var Expectation calls
   void writeVarExpectationCalls(ostream &output) const;
   //! Writes dynamic model file (C version)
   /*! \todo add third derivatives handling */
-  void writeDynamicCFile(const string &dynamic_basename, const int order) const;
+  void writeDynamicCFile(const string &basename, const int order) const;
   //! Writes dynamic model file when SparseDLL option is on
-  void writeSparseDynamicMFile(const string &dynamic_basename, const string &basename) const;
+  void writeSparseDynamicMFile(const string &basename) const;
   //! Writes the dynamic model equations and its derivatives
   /*! \todo add third derivatives handling in C output */
   void writeDynamicModel(ostream &DynamicOutput, bool use_dll, bool julia) const;
-  void writeDynamicModel(const string &dynamic_basename, bool use_dll, bool julia) const;
-  void writeDynamicModel(const string &dynamic_basename, ostream &DynamicOutput, bool use_dll, bool julia) const;
+  void writeDynamicModel(const string &basename, bool use_dll, bool julia) const;
+  void writeDynamicModel(const string &basename, ostream &DynamicOutput, bool use_dll, bool julia) const;
   //! Writes the Block reordred structure of the model in M output
-  void writeModelEquationsOrdered_M(const string &dynamic_basename) const;
+  void writeModelEquationsOrdered_M(const string &basename) const;
   //! Writes the code of the Block reordred structure of the model in virtual machine bytecode
-  void writeModelEquationsCode_Block(string &file_name, const string &bin_basename, const map_idx_t &map_idx) const;
+  void writeModelEquationsCode_Block(const string &basename, const map_idx_t &map_idx) const;
   //! Writes the code of the model in virtual machine bytecode
-  void writeModelEquationsCode(string &file_name, const string &bin_basename, const map_idx_t &map_idx) const;
+  void writeModelEquationsCode(const string &basename, const map_idx_t &map_idx) const;
 
   void writeSetAuxiliaryVariables(const string &basename, const bool julia) const;
   void writeAuxVarRecursiveDefinitions(ostream &output, ExprNodeOutputType output_type) const;
@@ -235,7 +235,8 @@ private:
   vector<pair<int, int>> endo_max_leadlag_block, other_endo_max_leadlag_block, exo_max_leadlag_block, exo_det_max_leadlag_block, max_leadlag_block;
 
   void writeWrapperFunctions(const string &name, const string &ending) const;
-  void writeDynamicModelHelper(const string &name, const string &retvalname,
+  void writeDynamicModelHelper(const string &basename,
+                               const string &name, const string &retvalname,
                                const string &name_tt, size_t ttlen,
                                const string &previous_tt_name,
                                const ostringstream &init_s,
@@ -243,7 +244,7 @@ private:
                                const ostringstream &s, const ostringstream &s_tt) const;
 
   //! Create a legacy *_dynamic.m file for Matlab/Octave not yet using the temporary terms array interface
-  void writeDynamicMatlabCompatLayer(const string &name) const;
+  void writeDynamicMatlabCompatLayer(const string &basename) const;
 
   void getEquationNumbersFromTags(vector<int> &eqnumber, set<string> &eqtags) const;
 
@@ -335,7 +336,7 @@ public:
   void substitutePacExpectation();
 
   //! Adds informations for simulation in a binary file
-  void Write_Inf_To_Bin_File_Block(const string &dynamic_basename, const string &bin_basename,
+  void Write_Inf_To_Bin_File_Block(const string &basename,
                                    const int &num, int &u_count_int, bool &file_open, bool is_two_boundaries) const;
   //! Writes dynamic model file
   void writeDynamicFile(const string &basename, bool block, bool bytecode, bool use_dll, int order, bool julia) const;
diff --git a/src/Makefile.am b/src/Makefile.am
index 080c598420d15f1fe456762c75cb4ac37a7d2378..a9efbb0ef4a04b47720238e47ff2ea3ad46e57ad 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -64,7 +64,7 @@ EXTRA_DIST = \
 # The -I. is for <FlexLexer.h>
 dynare_m_CPPFLAGS = $(BOOST_CPPFLAGS) -I.
 dynare_m_LDFLAGS = $(BOOST_LDFLAGS)
-dynare_m_LDADD = macro/libmacro.a
+dynare_m_LDADD = macro/libmacro.a $(BOOST_FILESYSTEM_LIB) $(BOOST_SYSTEM_LIB)
 
 DynareFlex.cc FlexLexer.h: DynareFlex.ll
 	$(LEX) -o DynareFlex.cc DynareFlex.ll
diff --git a/src/ModFile.cc b/src/ModFile.cc
index 5bcaa0a10aef334d4649551c5f94b3eba10c1952..1c5e3a31902a4799703d014dbc4863a3edc91733 100644
--- a/src/ModFile.cc
+++ b/src/ModFile.cc
@@ -22,9 +22,8 @@
 #include <fstream>
 #include <typeinfo>
 #include <cassert>
-#ifndef _WIN32
-# include <unistd.h>
-#endif
+
+#include <boost/filesystem.hpp>
 
 #include "ModFile.hh"
 #include "ConfigFile.hh"
@@ -746,12 +745,23 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo
                           , const bool nopreprocessoroutput
                           ) const
 {
+  bool hasModelChanged = !dynamic_model.isChecksumMatching(basename);
+  if (!check_model_changes)
+    hasModelChanged = true;
+
+  if (hasModelChanged)
+    {
+      // Erase possible remnants of previous runs
+      boost::filesystem::remove_all("+" + basename);
+      boost::filesystem::remove_all(basename + "/model");
+    }
+
   ofstream mOutputFile;
 
   if (basename.size())
     {
-      string fname(basename);
-      fname += ".m";
+      boost::filesystem::create_directory("+" + basename);
+      string fname = "+" + basename + "/driver.m";
       mOutputFile.open(fname.c_str(), ios::out | ios::binary);
       if (!mOutputFile.is_open())
         {
@@ -879,42 +889,6 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo
                 << "  error('DYNARE: Can''t find bytecode DLL. Please compile it or remove the ''bytecode'' option.')" << endl
                 << "end" << endl;
 
-  bool hasModelChanged = !dynamic_model.isChecksumMatching(basename);
-  if (!check_model_changes)
-    hasModelChanged = true;
-
-  if (hasModelChanged)
-    {
-      // Erase possible remnants of previous runs
-      unlink((basename + "_dynamic.m").c_str());
-      unlink((basename + "_dynamic.cod").c_str());
-      unlink((basename + "_dynamic.bin").c_str());
-
-      unlink((basename + "_static.m").c_str());
-      unlink((basename + "_static.cod").c_str());
-      unlink((basename + "_static.bin").c_str());
-
-      unlink((basename + "_steadystate2.m").c_str());
-      unlink((basename + "_set_auxiliary_variables.m").c_str());
-
-      // Clean generated files for temporary terms array interface
-      for (auto s1 : { "dynamic", "static" })
-        {
-          for (auto s2 : { "resid", "g1", "g2", "g3" })
-            for (auto s3 : { "", "_tt" })
-              unlink((basename + "_" + s1 + "_" + s2 + s3 + ".m").c_str());
-
-          for (auto s2 : { "resid_g1", "resid_g1_g2", "resid_g1_g2_g3" })
-            unlink((basename + "_" + s1 + "_" + s2 + ".m").c_str());
-        }
-    }
-
-  if (!use_dll)
-    {
-      mOutputFile << "erase_compiled_function('" + basename + "_static');" << endl;
-      mOutputFile << "erase_compiled_function('" + basename + "_dynamic');" << endl;
-    }
-
 #if defined(_WIN32) || defined(__CYGWIN32__)
 # if (defined(_MSC_VER) && _MSC_VER < 1700)
   // If using USE_DLL with MSVC 10.0 or earlier, check that the user didn't use a function not supported by the compiler (because MSVC <= 10.0 doesn't comply with C99 standard)
@@ -965,14 +939,10 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo
 #endif
     }
 
-  // Add path for block option with M-files
-  if (block && !byte_code)
-    mOutputFile << "addpath " << basename << ";" << endl;
-
   mOutputFile << "M_.orig_eq_nbr = " << mod_file_struct.orig_eq_nbr << ";" << endl
               << "M_.eq_nbr = " << dynamic_model.equation_number() << ";" << endl
               << "M_.ramsey_eq_nbr = " << mod_file_struct.ramsey_eq_nbr << ";" << endl
-              << "M_.set_auxiliary_variables = exist(['./' M_.fname '_set_auxiliary_variables.m'], 'file') == 2;" << endl;
+              << "M_.set_auxiliary_variables = exist(['./+' M_.fname '/set_auxiliary_variables.m'], 'file') == 2;" << endl;
 
   if (dynamic_model.equation_number() > 0)
     {
@@ -1018,10 +988,6 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo
         vms->createVarModelMFunction(mOutputFile, dynamic_model.getVarExpectationFunctionsToWrite());
     }
 
-  // Remove path for block option with M-files
-  if (block && !byte_code)
-    mOutputFile << "rmpath " << basename << ";" << endl;
-
   mOutputFile << "save('" << basename << "_results.mat', 'oo_', 'M_', 'options_');" << endl
               << "if exist('estim_params_', 'var') == 1" << endl
               << "  save('" << basename << "_results.mat', 'estim_params_', '-append');" << endl << "end" << endl
diff --git a/src/ModelTree.cc b/src/ModelTree.cc
index 6afb4c5834a743c421dfc41bf66f9dd0c108ba0e..c6a1be2ac8d5e5ef5dc5493a3fae8e3f790bf694 100644
--- a/src/ModelTree.cc
+++ b/src/ModelTree.cc
@@ -1603,19 +1603,18 @@ ModelTree::compileModelEquations(ostream &code_file, unsigned int &instruction_n
 }
 
 void
-ModelTree::Write_Inf_To_Bin_File(const string &basename,
+ModelTree::Write_Inf_To_Bin_File(const string &filename,
                                  int &u_count_int, bool &file_open, bool is_two_boundaries, int block_mfs) const
 {
   int j;
   std::ofstream SaveCode;
-  const string bin_basename = basename + ".bin";
   if (file_open)
-    SaveCode.open(bin_basename.c_str(), ios::out | ios::in | ios::binary | ios::ate);
+    SaveCode.open(filename, ios::out | ios::in | ios::binary | ios::ate);
   else
-    SaveCode.open(bin_basename.c_str(), ios::out | ios::binary);
+    SaveCode.open(filename, ios::out | ios::binary);
   if (!SaveCode.is_open())
     {
-      cerr << "Error : Can't open file \"" << bin_basename << "\" for writing" << endl;
+      cerr << "Error : Can't open file \"" << filename << "\" for writing" << endl;
       exit(EXIT_FAILURE);
     }
   u_count_int = 0;
diff --git a/src/ModelTree.hh b/src/ModelTree.hh
index 8f0fc48725900d4301151019e711320280296461..46cad5f2118f0e35a58a6338ba6728d4b21f50dd 100644
--- a/src/ModelTree.hh
+++ b/src/ModelTree.hh
@@ -192,7 +192,7 @@ protected:
   //! Compiles temporary terms
   void compileTemporaryTerms(ostream &code_file, unsigned int &instruction_number, const temporary_terms_t &tt, map_idx_t map_idx, bool dynamic, bool steady_dynamic) const;
   //! Adds informations for simulation in a binary file
-  void Write_Inf_To_Bin_File(const string &basename, int &u_count_int, bool &file_open, bool is_two_boundaries, int block_mfs) const;
+  void Write_Inf_To_Bin_File(const string &filename, int &u_count_int, bool &file_open, bool is_two_boundaries, int block_mfs) const;
   //! Fixes output when there are more than 32 nested parens, Issue #1201
   void fixNestedParenthesis(ostringstream &output, map<string, string> &tmp_paren_vars, bool &message_printed) const;
   //! Tests if string contains more than 32 nested parens, Issue #1201
diff --git a/src/StaticModel.cc b/src/StaticModel.cc
index 68836677c7950991a4e39dcdf6645feb49f4197e..59ae0821ca7c1249b565f38e255779a3d05de4df 100644
--- a/src/StaticModel.cc
+++ b/src/StaticModel.cc
@@ -24,16 +24,10 @@
 #include <cstdio>
 #include <cerrno>
 #include <algorithm>
-#include "StaticModel.hh"
 
-// For mkdir() and chdir()
-#ifdef _WIN32
-# include <direct.h>
-#else
-# include <unistd.h>
-# include <sys/stat.h>
-# include <sys/types.h>
-#endif
+#include <boost/filesystem.hpp>
+
+#include "StaticModel.hh"
 
 StaticModel::StaticModel(SymbolTable &symbol_table_arg,
                          NumericalConstants &num_constants_arg,
@@ -193,7 +187,7 @@ StaticModel::computeTemporaryTermsMapping(temporary_terms_t &temporary_terms, ma
 }
 
 void
-StaticModel::writeModelEquationsOrdered_M(const string &static_basename) const
+StaticModel::writeModelEquationsOrdered_M(const string &basename) const
 {
   string tmp_s, sps;
   ostringstream tmp_output, tmp1_output, global_output;
@@ -223,7 +217,7 @@ StaticModel::writeModelEquationsOrdered_M(const string &static_basename) const
       unsigned int block_recursive = block_size - block_mfs;
 
       tmp1_output.str("");
-      tmp1_output << static_basename << "_" << block+1 << ".m";
+      tmp1_output << packageDir(basename + ".block") << "/static_" << block+1 << ".m";
       output.open(tmp1_output.str().c_str(), ios::out | ios::binary);
       output << "%\n";
       output << "% " << tmp1_output.str() << " : Computes static model for Dynare\n";
@@ -232,9 +226,9 @@ StaticModel::writeModelEquationsOrdered_M(const string &static_basename) const
       output << "%           from model file (.mod)\n\n";
       output << "%/\n";
       if (simulation_type == EVALUATE_BACKWARD || simulation_type == EVALUATE_FORWARD)
-        output << "function y = " << static_basename << "_" << block+1 << "(y, x, params)\n";
+        output << "function y = static_" << block+1 << "(y, x, params)\n";
       else
-        output << "function [residual, y, g1] = " << static_basename << "_" << block+1 << "(y, x, params)\n";
+        output << "function [residual, y, g1] = static_" << block+1 << "(y, x, params)\n";
 
       BlockType block_type;
       if (simulation_type == SOLVE_FORWARD_COMPLETE || simulation_type == SOLVE_BACKWARD_COMPLETE)
@@ -397,7 +391,7 @@ StaticModel::writeModelEquationsOrdered_M(const string &static_basename) const
 }
 
 void
-StaticModel::writeModelEquationsCode(const string file_name, const string bin_basename, map_idx_t map_idx) const
+StaticModel::writeModelEquationsCode(const string &basename, map_idx_t map_idx) const
 {
 
   ostringstream tmp_output;
@@ -405,8 +399,9 @@ StaticModel::writeModelEquationsCode(const string file_name, const string bin_ba
   unsigned int instruction_number = 0;
   bool file_open = false;
 
-  string main_name = file_name;
-  main_name += ".cod";
+  boost::filesystem::create_directories(basename + "/model/bytecode");
+
+  string main_name = basename + "/model/bytecode/static.cod";
   code_file.open(main_name.c_str(), ios::out | ios::binary | ios::ate);
   if (!code_file.is_open())
     {
@@ -416,7 +411,7 @@ StaticModel::writeModelEquationsCode(const string file_name, const string bin_ba
   int count_u;
   int u_count_int = 0;
 
-  Write_Inf_To_Bin_File(file_name, u_count_int, file_open, false, symbol_table.endo_nbr());
+  Write_Inf_To_Bin_File(basename + "/model/bytecode/static.bin", u_count_int, file_open, false, symbol_table.endo_nbr());
   file_open = true;
 
   //Temporary variables declaration
@@ -560,7 +555,7 @@ StaticModel::writeModelEquationsCode(const string file_name, const string bin_ba
 }
 
 void
-StaticModel::writeModelEquationsCode_Block(const string file_name, const string bin_basename, map_idx_t map_idx, vector<map_idx_t> map_idx2) const
+StaticModel::writeModelEquationsCode_Block(const string &basename, map_idx_t map_idx, vector<map_idx_t> map_idx2) const
 {
   struct Uff_l
   {
@@ -586,8 +581,9 @@ StaticModel::writeModelEquationsCode_Block(const string file_name, const string
   deriv_node_temp_terms_t tef_terms;
   bool file_open = false;
 
-  string main_name = file_name;
-  main_name += ".cod";
+  boost::filesystem::create_directories(basename + "/model/bytecode");
+
+  string main_name = basename + "/model/bytecode/static.cod";
   code_file.open(main_name.c_str(), ios::out | ios::binary | ios::ate);
   if (!code_file.is_open())
     {
@@ -617,7 +613,7 @@ StaticModel::writeModelEquationsCode_Block(const string file_name, const string
       if (simulation_type == SOLVE_TWO_BOUNDARIES_SIMPLE || simulation_type == SOLVE_TWO_BOUNDARIES_COMPLETE
           || simulation_type == SOLVE_BACKWARD_COMPLETE || simulation_type == SOLVE_FORWARD_COMPLETE)
         {
-          Write_Inf_To_Bin_File_Block(file_name, bin_basename, block, u_count_int, file_open);
+          Write_Inf_To_Bin_File_Block(basename, block, u_count_int, file_open);
           file_open = true;
         }
 
@@ -973,18 +969,19 @@ StaticModel::writeModelEquationsCode_Block(const string file_name, const string
 }
 
 void
-StaticModel::Write_Inf_To_Bin_File_Block(const string &static_basename, const string &bin_basename, const int &num,
+StaticModel::Write_Inf_To_Bin_File_Block(const string &basename, const int &num,
                                          int &u_count_int, bool &file_open) const
 {
   int j;
   std::ofstream SaveCode;
+  string filename = basename + "/model/bytecode/static.bin";
   if (file_open)
-    SaveCode.open((bin_basename + "_static.bin").c_str(), ios::out | ios::in | ios::binary | ios::ate);
+    SaveCode.open(filename, ios::out | ios::in | ios::binary | ios::ate);
   else
-    SaveCode.open((bin_basename + "_static.bin").c_str(), ios::out | ios::binary);
+    SaveCode.open(filename, ios::out | ios::binary);
   if (!SaveCode.is_open())
     {
-      cerr << "Error : Can't open file \"" << bin_basename << "_static.bin\" for writing" << endl;
+      cerr << "Error : Can't open file " << filename << " for writing" << endl;
       exit(EXIT_FAILURE);
     }
   u_count_int = 0;
@@ -1152,9 +1149,9 @@ StaticModel::computingPass(const eval_context_t &eval_context, bool no_tmp_terms
 }
 
 void
-StaticModel::writeStaticMFile(const string &func_name) const
+StaticModel::writeStaticMFile(const string &basename) const
 {
-  writeStaticModel(func_name, false, false);
+  writeStaticModel(basename, false, false);
 }
 
 void
@@ -1162,13 +1159,13 @@ StaticModel::writeWrapperFunctions(const string &basename, const string &ending)
 {
   string name;
   if (ending == "g1")
-    name = basename + "_resid_g1";
+    name = "static_resid_g1";
   else if (ending == "g2")
-    name= basename + "_resid_g1_g2";
+    name = "static_resid_g1_g2";
   else if (ending == "g3")
-    name = basename + "_resid_g1_g2_g3";
+    name = "static_resid_g1_g2_g3";
 
-  string filename = name + ".m";
+  string filename = packageDir(basename) + "/" + name + ".m";
   ofstream output;
   output.open(filename.c_str(), ios::out | ios::binary);
   if (!output.is_open())
@@ -1192,31 +1189,32 @@ StaticModel::writeWrapperFunctions(const string &basename, const string &ending)
          << "%" << endl
          << endl
          << "    if T_flag" << endl
-         << "        T = " << basename + "_" + ending + "_tt(T, y, x, params);" << endl
+         << "        T = " << basename << ".static_" << ending << "_tt(T, y, x, params);" << endl
          << "    end" << endl;
 
   if (ending == "g1")
-    output << "    residual = " << basename + "_resid(T, y, x, params, false);" << endl
-           << "    g1       = " << basename + "_g1(T, y, x, params, false);" << endl;
+    output << "    residual = " << basename << ".static_resid(T, y, x, params, false);" << endl
+           << "    g1       = " << basename << ".static_g1(T, y, x, params, false);" << endl;
   else if (ending == "g2")
-    output << "    [residual, g1] = " << basename + "_resid_g1(T, y, x, params, false);" << endl
-           << "    g2       = " << basename + "_g2(T, y, x, params, false);" << endl;
+    output << "    [residual, g1] = " << basename << ".static_resid_g1(T, y, x, params, false);" << endl
+           << "    g2       = " << basename << ".static_g2(T, y, x, params, false);" << endl;
   else if (ending == "g3")
-    output << "    [residual, g1, g2] = " << basename + "_resid_g1_g2(T, y, x, params, false);" << endl
-           << "    g3       = " << basename + "_g3(T, y, x, params, false);" << endl;
+    output << "    [residual, g1, g2] = " << basename << ".static_resid_g1_g2(T, y, x, params, false);" << endl
+           << "    g3       = " << basename << ".static_g3(T, y, x, params, false);" << endl;
 
   output << endl << "end" << endl;
   output.close();
 }
 
 void
-StaticModel::writeStaticModelHelper(const string &name, const string &retvalname,
+StaticModel::writeStaticModelHelper(const string &basename,
+                                    const string &name, const string &retvalname,
                                     const string &name_tt, size_t ttlen,
                                     const string &previous_tt_name,
                                     const ostringstream &init_s, const ostringstream &end_s,
                                     const ostringstream &s, const ostringstream &s_tt) const
 {
-  string filename =  name_tt + ".m";
+  string filename = packageDir(basename) + "/" + name_tt + ".m";
   ofstream output;
   output.open(filename.c_str(), ios::out | ios::binary);
   if (!output.is_open())
@@ -1243,13 +1241,13 @@ StaticModel::writeStaticModelHelper(const string &name, const string &retvalname
          << endl;
 
   if (!previous_tt_name.empty())
-    output << "T = " << previous_tt_name << "(T, y, x, params);" << endl << endl;
+    output << "T = " << basename << "." << previous_tt_name << "(T, y, x, params);" << endl << endl;
 
   output << s_tt.str() << endl
          << "end" << endl;
   output.close();
 
-  filename = name + ".m";
+  filename = packageDir(basename) + "/" + name + ".m";
   output.open(filename.c_str(), ios::out | ios::binary);
   if (!output.is_open())
     {
@@ -1276,7 +1274,7 @@ StaticModel::writeStaticModelHelper(const string &name, const string &retvalname
 
   if (!name_tt.empty())
     output << "if T_flag" << endl
-           << "    T = " << name_tt << "(T, y, x, params);" << endl
+           << "    T = " << basename << "."  << name_tt << "(T, y, x, params);" << endl
            << "end" << endl;
 
   output << init_s.str() << endl
@@ -1287,9 +1285,9 @@ StaticModel::writeStaticModelHelper(const string &name, const string &retvalname
 }
 
 void
-StaticModel::writeStaticMatlabCompatLayer(const string &name) const
+StaticModel::writeStaticMatlabCompatLayer(const string &basename) const
 {
-  string filename = name + ".m";
+  string filename = packageDir(basename) + "/static.m";
   ofstream output;
   output.open(filename.c_str(), ios::out | ios::binary);
   if (!output.is_open())
@@ -1299,16 +1297,16 @@ StaticModel::writeStaticMatlabCompatLayer(const string &name) const
     }
   int ntt = temporary_terms_mlv.size() + temporary_terms_res.size() + temporary_terms_g1.size() + temporary_terms_g2.size() + temporary_terms_g3.size();
 
-  output << "function [residual, g1, g2, g3] = " << name << "(y, x, params)" << endl
+  output << "function [residual, g1, g2, g3] = static(y, x, params)" << endl
          << "    T = NaN(" << ntt << ", 1);" << endl
          << "    if nargout <= 1" << endl
-         << "        residual = " << name << "_resid(T, y, x, params, true);" << endl
+         << "        residual = " << basename << ".static_resid(T, y, x, params, true);" << endl
          << "    elseif nargout == 2" << endl
-         << "        [residual, g1] = " << name << "_resid_g1(T, y, x, params, true);" << endl
+         << "        [residual, g1] = " << basename << ".static_resid_g1(T, y, x, params, true);" << endl
          << "    elseif nargout == 3" << endl
-         << "        [residual, g1, g2] = " << name << "_resid_g1_g2(T, y, x, params, true);" << endl
+         << "        [residual, g1, g2] = " << basename << ".static_resid_g1_g2(T, y, x, params, true);" << endl
          << "    else" << endl
-         << "        [residual, g1, g2, g3] = " << name << "_resid_g1_g2_g3(T, y, x, params, true);" << endl
+         << "        [residual, g1, g2, g3] = " << basename << ".static_resid_g1_g2_g3(T, y, x, params, true);" << endl
          << "    end" << endl
          << "end" << endl;
 
@@ -1552,14 +1550,12 @@ StaticModel::writeStaticModel(const string &basename,
       fixNestedParenthesis(third_derivatives_output, tmp_paren_vars, message_printed);
       fixNestedParenthesis(third_derivatives_tt_output, tmp_paren_vars, message_printed);
 
-      string static_name = basename + "_static";
       ostringstream init_output, end_output;
       init_output << "residual = zeros(" << equations.size() << ", 1);";
       end_output << "if ~isreal(residual)" << endl
                  << "  residual = real(residual)+imag(residual).^2;" << endl
                  << "end";
-      writeStaticModelHelper(static_name + "_resid", "residual",
-                             static_name + "_resid_tt",
+      writeStaticModelHelper(basename, "static_resid", "residual", "static_resid_tt",
                              temporary_terms_mlv.size() + temporary_terms_res.size(),
                              "", init_output, end_output,
                              model_output, model_tt_output);
@@ -1572,13 +1568,12 @@ StaticModel::writeStaticModel(const string &basename,
       end_output << "if ~isreal(g1)" << endl
                  << "    g1 = real(g1)+2*imag(g1);" << endl
                  << "end";
-      writeStaticModelHelper(static_name + "_g1", "g1",
-                             static_name + "_g1_tt",
+      writeStaticModelHelper(basename, "static_g1", "g1", "static_g1_tt",
                              temporary_terms_mlv.size() + temporary_terms_res.size() + temporary_terms_g1.size(),
-                             static_name + "_resid_tt",
+                             "static_resid_tt",
                              init_output, end_output,
                              jacobian_output, jacobian_tt_output);
-      writeWrapperFunctions(static_name, "g1");
+      writeWrapperFunctions(basename, "g1");
 
       init_output.str(string());
       init_output.clear();
@@ -1591,14 +1586,13 @@ StaticModel::writeStaticModel(const string &basename,
         }
       else
         init_output << "g2 = sparse([],[],[]," << equations.size() << "," << g2ncols << ");";
-      writeStaticModelHelper(static_name + "_g2", "g2",
-                             static_name + "_g2_tt",
+      writeStaticModelHelper(basename, "static_g2", "g2", "static_g2_tt",
                              temporary_terms_mlv.size() + temporary_terms_res.size() + temporary_terms_g1.size()
                              + temporary_terms_g2.size(),
-                             static_name + "_g1_tt",
+                             "static_g1_tt",
                              init_output, end_output,
                              hessian_output, hessian_tt_output);
-      writeWrapperFunctions(static_name, "g2");
+      writeWrapperFunctions(basename, "g2");
 
       init_output.str(string());
       init_output.clear();
@@ -1612,16 +1606,15 @@ StaticModel::writeStaticModel(const string &basename,
         }
       else
         init_output << "g3 = sparse([],[],[]," << nrows << "," << ncols << ");";
-      writeStaticModelHelper(static_name + "_g3", "g3",
-                             static_name + "_g3_tt",
+      writeStaticModelHelper(basename, "static_g3", "g3", "static_g3_tt",
                              temporary_terms_mlv.size() + temporary_terms_res.size() + temporary_terms_g1.size()
                              + temporary_terms_g2.size() + temporary_terms_g3.size(),
-                             static_name + "_g2_tt",
+                             "static_g2_tt",
                              init_output, end_output,
                              third_derivatives_output, third_derivatives_tt_output);
-      writeWrapperFunctions(static_name, "g3");
+      writeWrapperFunctions(basename, "g3");
 
-      writeStaticMatlabCompatLayer(static_name);
+      writeStaticMatlabCompatLayer(basename);
     }
   else if (output_type == oCStaticModel)
     {
@@ -1869,11 +1862,12 @@ StaticModel::writeStaticModel(const string &basename,
 }
 
 void
-StaticModel::writeStaticCFile(const string &func_name) const
+StaticModel::writeStaticCFile(const string &basename) const
 {
   // Writing comments and function definition command
-  string filename = func_name + "_static.c";
-  string filename_mex = func_name + "_static_mex.c";
+  boost::filesystem::create_directories(basename + "/model/src");
+  string filename = basename + "/model/src/static.c";
+  string filename_mex = basename + "/model/src/static_mex.c";
 
   ofstream output;
   output.open(filename.c_str(), ios::out | ios::binary);
@@ -1994,29 +1988,13 @@ StaticModel::writeStaticJuliaFile(const string &basename) const
 void
 StaticModel::writeStaticFile(const string &basename, bool block, bool bytecode, bool use_dll, bool julia) const
 {
-  int r;
-
-  //assert(block);
-
-#ifdef _WIN32
-  r = mkdir(basename.c_str());
-#else
-  r = mkdir(basename.c_str(), 0777);
-#endif
-  if (r < 0 && errno != EEXIST)
-    {
-      perror("ERROR");
-      exit(EXIT_FAILURE);
-    }
   if (block && bytecode)
-    writeModelEquationsCode_Block(basename + "_static", basename, map_idx, map_idx2);
+    writeModelEquationsCode_Block(basename, map_idx, map_idx2);
   else if (!block && bytecode)
-    writeModelEquationsCode(basename + "_static", basename, map_idx);
+    writeModelEquationsCode(basename, map_idx);
   else if (block && !bytecode)
     {
-      chdir(basename.c_str());
-      writeModelEquationsOrdered_M(basename + "_static");
-      chdir("..");
+      writeModelEquationsOrdered_M(basename);
       writeStaticBlockMFSFile(basename);
     }
   else if (use_dll)
@@ -2040,7 +2018,7 @@ StaticModel::exoPresentInEqs() const
 void
 StaticModel::writeStaticBlockMFSFile(const string &basename) const
 {
-  string filename = basename + "_static.m";
+  string filename = packageDir(basename) + "/static.m";
 
   ofstream output;
   output.open(filename.c_str(), ios::out | ios::binary);
@@ -2050,9 +2028,7 @@ StaticModel::writeStaticBlockMFSFile(const string &basename) const
       exit(EXIT_FAILURE);
     }
 
-  string func_name = basename + "_static";
-
-  output << "function [residual, g1, y, var_index] = " << func_name << "(nblock, y, x, params)" << endl
+  output << "function [residual, g1, y, var_index] = static(nblock, y, x, params)" << endl
          << "  residual = [];" << endl
          << "  g1 = [];" << endl
          << "  var_index = [];\n" << endl
@@ -2071,7 +2047,7 @@ StaticModel::writeStaticBlockMFSFile(const string &basename) const
 
       if (simulation_type == EVALUATE_BACKWARD || simulation_type == EVALUATE_FORWARD)
         {
-          output << "      y_tmp = " << func_name << "_" << b+1 << "(y, x, params);\n";
+          output << "      y_tmp = " << basename << ".block.static_" << b+1 << "(y, x, params);\n";
           ostringstream tmp;
           for (int i = 0; i < (int) getBlockSize(b); i++)
             tmp << " " << getBlockVariableID(b, i)+1;
@@ -2080,7 +2056,7 @@ StaticModel::writeStaticBlockMFSFile(const string &basename) const
           output << "      y = y_tmp;\n";
         }
       else
-        output << "      [residual, y, g1] = " << func_name << "_" << b+1 << "(y, x, params);\n";
+        output << "      [residual, y, g1] = " << basename << ".block.static_" << b+1 << "(y, x, params);\n";
 
     }
   output << "  end" << endl
@@ -2394,8 +2370,8 @@ StaticModel::writeSetAuxiliaryVariables(const string &basename, const bool julia
   if (output_func_body.str().empty())
     return;
 
-  string func_name = basename + "_set_auxiliary_variables";
-  string filename = julia ? func_name + ".jl" : func_name + ".m";
+  string func_name = julia ? basename + "_set_auxiliary_variables" : "set_auxiliary_variables";
+  string filename = julia ? func_name + ".jl" : packageDir(basename) + "/" + func_name + ".m";
   string comment = julia ? "#" : "%";
 
   ofstream output;
@@ -2615,7 +2591,7 @@ StaticModel::writeParamsDerivativesFile(const string &basename, bool julia) cons
     }
 
   ofstream paramsDerivsFile;
-  string filename = julia ? basename + "StaticParamsDerivs.jl" : basename + "_static_params_derivs.m";
+  string filename = julia ? basename + "StaticParamsDerivs.jl" : packageDir(basename) + "/static_params_derivs.m";
   paramsDerivsFile.open(filename.c_str(), ios::out | ios::binary);
   if (!paramsDerivsFile.is_open())
     {
@@ -2636,7 +2612,7 @@ StaticModel::writeParamsDerivativesFile(const string &basename, bool julia) cons
       fixNestedParenthesis(third_derivs_output, tmp_paren_vars, message_printed);
       fixNestedParenthesis(third_derivs1_output, tmp_paren_vars, message_printed);
 
-      paramsDerivsFile << "function [rp, gp, rpp, gpp, hp] = " << basename << "_static_params_derivs(y, x, params)" << endl
+      paramsDerivsFile << "function [rp, gp, rpp, gpp, hp] = static_params_derivs(y, x, params)" << endl
                        << "%" << endl
                        << "% Status : Computes derivatives of the static model with respect to the parameters" << endl
                        << "%" << endl
diff --git a/src/StaticModel.hh b/src/StaticModel.hh
index b58e9134810eefda5b428f15d7b50a6ff4da78b4..4fad5171e7943e07e84f7c9c407d2a62325a9d3c 100644
--- a/src/StaticModel.hh
+++ b/src/StaticModel.hh
@@ -42,10 +42,10 @@ private:
   first_chain_rule_derivatives_t first_chain_rule_derivatives;
 
   //! Writes static model file (standard Matlab version)
-  void writeStaticMFile(const string &static_basename) const;
+  void writeStaticMFile(const string &basename) const;
 
   //! Writes static model file (C version)
-  void writeStaticCFile(const string &func_name) const;
+  void writeStaticCFile(const string &basename) const;
 
   //! Writes static model file (Julia version)
   void writeStaticJuliaFile(const string &basename) const;
@@ -57,13 +57,13 @@ private:
   void writeStaticBlockMFSFile(const string &basename) const;
 
   //! Writes the Block reordred structure of the model in M output
-  void writeModelEquationsOrdered_M(const string &dynamic_basename) const;
+  void writeModelEquationsOrdered_M(const string &basename) const;
 
   //! Writes the code of the Block reordred structure of the model in virtual machine bytecode
-  void writeModelEquationsCode_Block(const string file_name, const string bin_basename, map_idx_t map_idx, vector<map_idx_t> map_idx2) const;
+  void writeModelEquationsCode_Block(const string &basename, map_idx_t map_idx, vector<map_idx_t> map_idx2) const;
 
   //! Writes the code of the model in virtual machine bytecode
-  void writeModelEquationsCode(const string file_name, const string bin_basename, map_idx_t map_idx) const;
+  void writeModelEquationsCode(const string &basename, map_idx_t map_idx) const;
 
   //! Computes jacobian and prepares for equation normalization
   /*! Using values from initval/endval blocks and parameter initializations:
@@ -146,7 +146,8 @@ protected:
   vector<pair<int, int>> endo_max_leadlag_block, other_endo_max_leadlag_block, exo_max_leadlag_block, exo_det_max_leadlag_block, max_leadlag_block;
 
   //! Helper functions for writeStaticModel
-  void writeStaticModelHelper(const string &name, const string &retvalname,
+  void writeStaticModelHelper(const string &basename,
+                              const string &name, const string &retvalname,
                               const string &name_tt, size_t ttlen,
                               const string &previous_tt_name,
                               const ostringstream &init_s, const ostringstream &end_s,
@@ -174,7 +175,7 @@ public:
   void computingPass(const eval_context_t &eval_context, bool no_tmp_terms, bool hessian, bool thirdDerivatices, int paramsDerivsOrder, bool block, bool bytecode, const bool nopreprocessoroutput);
 
   //! Adds informations for simulation in a binary file for a block decomposed model
-  void Write_Inf_To_Bin_File_Block(const string &static_basename, const string &bin_basename, const int &num,
+  void Write_Inf_To_Bin_File_Block(const string &basename, const int &num,
                                    int &u_count_int, bool &file_open) const;
 
   //! Writes static model file
diff --git a/src/SteadyStateModel.cc b/src/SteadyStateModel.cc
index 74ff2394a7ad813bf3bf5694038888b6721681ce..185fae14c845ae50f74a6d8eafbf138957f1938a 100644
--- a/src/SteadyStateModel.cc
+++ b/src/SteadyStateModel.cc
@@ -159,7 +159,7 @@ SteadyStateModel::writeSteadyStateFile(const string &basename, bool ramsey_model
   if (def_table.size() == 0)
     return;
 
-  string filename = julia ? basename + "SteadyState2.jl" : basename + "_steadystate2.m";
+  string filename = julia ? basename + "SteadyState2.jl" : packageDir(basename) + "/steadystate.m";
   ofstream output;
   output.open(filename.c_str(), ios::out | ios::binary);
   if (!output.is_open())
@@ -171,7 +171,7 @@ SteadyStateModel::writeSteadyStateFile(const string &basename, bool ramsey_model
   ExprNodeOutputType output_type = (julia ? oJuliaSteadyStateFile : oSteadyStateFile);
 
   if (!julia)
-    output << "function [ys_, params, info] = " << basename << "_steadystate2("
+    output << "function [ys_, params, info] = steadystate("
            << "ys_, exo_, params)" << endl
            << "% Steady state generated by Dynare preprocessor" << endl
            << "    info = 0;" << endl;