diff --git a/meson.build b/meson.build
index 799499d84cb330bfcf94f90e2f8d156713d3c67d..89bd910a14d4251de306669a9b8c3ef1ecb0f1e3 100644
--- a/meson.build
+++ b/meson.build
@@ -46,6 +46,8 @@ src = [
     'src/users/user_replay.hpp',
     'src/users/user_windows.cpp',
     'src/users/user_windows.hpp',
+    'src/users/response_behaviors.cpp',
+    'src/users/response_behaviors.hpp',
     'src/users/user_feedback.cpp',
     'src/users/user_feedback.hpp',
     'src/users/dynscheduler.cpp',
diff --git a/src/json_workload.cpp b/src/json_workload.cpp
index 03c29fcb026ae3a85955c46361a617272d15dd38..d58926cf5cc2a114ab0339d80d67c0c5bfca6bff 100644
--- a/src/json_workload.cpp
+++ b/src/json_workload.cpp
@@ -208,7 +208,7 @@ bool JobComparator::operator()(Job j1, Job j2) const
 
 bool JobSubmissionOrder::operator()(const Job *j1, const Job *j2) const
 {
-    if (j1->submission_time == j2->submission_time) 
+    if (j1->submission_time == j2->submission_time)
         return jobcmp(j1, j2);
     else
         return j1->submission_time < j2->submission_time;
@@ -238,8 +238,7 @@ UserSubmitQueue::UserSubmitQueue(
     PPK_ASSERT_ERROR(jobs.IsArray(), "%s: the 'jobs' member is not an array",
         error_prefix.c_str());
 
-    for (SizeType i = 0; i < jobs.Size();
-         i++)
+    for (SizeType i = 0; i < jobs.Size(); i++)
     {
         const Value &job_json_description = jobs[i];
 
@@ -249,11 +248,12 @@ UserSubmitQueue::UserSubmitQueue(
 
     /* Sort the list by submission time */
     _jobs.sort(submission_order);
+}
 
-    }
-    
-UserSubmitQueue::~UserSubmitQueue(){
-    for (auto j : _jobs){
+UserSubmitQueue::~UserSubmitQueue()
+{
+    for (auto j : _jobs)
+    {
         delete j;
     }
 }
@@ -264,13 +264,13 @@ void UserSubmitQueue::insert_sorted(const Job *j)
     *job = *j;
     auto start = _jobs.begin();
     auto end = _jobs.end();
-    while(start!=end && submission_order((*start), job)) {
+    while (start != end && submission_order((*start), job))
+    {
         ++start;
     }
-    _jobs.insert(start,job);
+    _jobs.insert(start, job);
 }
 
-
 const Job *UserSubmitQueue::top() const
 {
     return _jobs.front();
@@ -282,7 +282,7 @@ const Job *UserSubmitQueue::pop()
     _jobs.pop_front();
     return j;
 }
-    
+
 bool UserSubmitQueue::is_empty() const
 {
     return _jobs.size() == 0;
@@ -633,9 +633,12 @@ Session *Parser::session_from_json_object(string user_name, const Value &object,
     return s;
 }
 
-void Parser::profile_from_duration(Profile *profile, const string duration,
-    const string user_name, const double platform_computing_speed)
+void Parser::profile_from_duration(
+    Profile *profile, const string duration, const string user_name)
 {
+    // TODO retrieve that info from the platform (wait batsim5.0)
+    double platform_computing_speed = PLATFORM_COMPUTING_SPEED;
+
     profile->workload_name = user_name;
     profile->name = duration;
     double duration_time = stod(duration);
diff --git a/src/json_workload.hpp b/src/json_workload.hpp
index f1a3339a66b1ca03c92382d8635d7f3b69a1655c..8cefe2a2c316d6d80aa554b6a3d9d33ce84f7770 100644
--- a/src/json_workload.hpp
+++ b/src/json_workload.hpp
@@ -12,6 +12,8 @@
 #include <string>
 #include <utility>
 
+#include "scheds/HARD_DEFINED_VAR.hpp"
+
 struct JobAlloc;
 class Session;
 
@@ -168,6 +170,5 @@ struct Parser
         const std::string user_name, const std::string input_json);
 
     static void profile_from_duration(Profile *profile,
-        const std::string duration, const std::string user_name,
-        const double platform_computing_speed);
+        const std::string duration, const std::string user_name);
 };
\ No newline at end of file
diff --git a/src/users/broker.cpp b/src/users/broker.cpp
index e9d62d6fed9d25bb47031444a3a59480bda2d8e2..4091a5d674b3f1fb8fb1c698050a50f9c28807fb 100644
--- a/src/users/broker.cpp
+++ b/src/users/broker.cpp
@@ -398,13 +398,11 @@ void Broker::update_status_if_dyn_job(
 void Broker::log_user_stats(string log_folder)
 {
     static int stat[14] = { 0 };
-    int *dm_stat;
     for (auto it : users)
     {
         User *user = it.second;
-        dm_stat = user->get_dm_stat();
         for (int i = 0; i < 14; i++)
-            stat[i] += dm_stat[i];
+            stat[i] += user->dm_stat[i];
     }
     if (logger_user_stat){
         logger_user_stat->log_stat();
diff --git a/src/users/response_behaviors.cpp b/src/users/response_behaviors.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fc292beb5a8e5e5f374d7b8ee41700228a195cf0
--- /dev/null
+++ b/src/users/response_behaviors.cpp
@@ -0,0 +1,158 @@
+#include "response_behaviors.hpp"
+#include "json_workload.hpp"
+#include "users/user.hpp"
+
+#include "../pempek_assert.hpp"
+
+void log_behavior(LoggerUserStat *logger, shared_ptr<Job> &job,
+    std::string behavior_name, long delay_time, double random_value)
+{
+    if (logger)
+    {
+        logger->add_stat(
+            job, std::move(behavior_name), delay_time, random_value);
+    }
+}
+
+bool rigid_job(shared_ptr<Job> job, Profile *profile, User *user,
+    LoggerUserStat *logger, double random_number)
+{
+    Parser::profile_from_duration(profile, job->profile, user->user_name);
+
+    /* Log... */
+    log_behavior(logger, job, "rigid", 0, random_number);
+    user->dm_stat[2 * RIGID]++;
+    user->dm_stat[2 * RIGID + 1]
+        += job->nb_requested_resources * std::stol(job->profile);
+
+    /* Signals that the job must be executed */
+    return true;
+}
+
+bool renounce_job(shared_ptr<Job> job, User *user, LoggerUserStat *logger,
+    double random_number)
+{
+    /* Log... */
+    log_behavior(logger, job, "renonce", 0, random_number);
+    user->dm_stat[2 * RENONCED]++;
+    user->dm_stat[2 * RENONCED + 1]
+        += job->nb_requested_resources * std::stol(job->profile);
+
+    /* Signals that the job must not be executed */
+    return false;
+}
+
+bool reconfig_job(shared_ptr<Job> job, Profile *profile, double alpha,
+    User *user, LoggerUserStat *logger, double random_number)
+{
+    int orig_nb_core = job->nb_requested_resources;
+
+    PPK_ASSERT_ERROR(orig_nb_core > 1,
+        "Behavior 'reconfig' undefined for job of size 1. Job_id: %s",
+        job->id.c_str());
+
+    /* Log... */
+    user->dm_stat[2 * RECONF]++;
+    user->dm_stat[2 * RECONF + 1] += orig_nb_core * std::stol(job->profile);
+    log_behavior(logger, job, "reconfig", 0.0, random_number);
+
+    /* Reconfig: divide by two rounded up the nb or cores requested */
+    int n = (orig_nb_core + 1) / 2;
+
+    /* Speedup model:
+     *   - T_orig: the original execution time (on orig_nb_core cores)
+     *   - T_1: the execution time on one core
+     *   - T_n: the execution time on n cores
+     * We have: T_1 = n^alpha * T_n = orig_nb_core^alpha * T_orig
+     *          => T_n = (orig_nb_core / n)^alpha * T_orig
+     */
+    long T_orig = std::stol(job->profile);
+    long T_n = pow((double)orig_nb_core / n, alpha) * T_orig;
+    Parser::profile_from_duration(
+        profile, std::to_string(T_n), user->user_name); // parallel_homogeneous
+    job->nb_requested_resources = n;
+    job->profile = profile->name = 'r' + std::to_string(T_orig);
+
+    return true;
+}
+
+bool degrad_space_job(shared_ptr<Job> &job, Profile *profile, User *user,
+    LoggerUserStat *logger, double random_number)
+{
+    int orig_nb_core = job->nb_requested_resources;
+
+    PPK_ASSERT_ERROR(orig_nb_core > 1,
+        "Behavior 'degrad' undefined for job of size 1. Job_id: %s",
+        job->id.c_str());
+
+    /* Log... */
+    user->dm_stat[2 * DEGRADED]++;
+    user->dm_stat[2 * DEGRADED + 1] += orig_nb_core * std::stol(job->profile);
+    log_behavior(logger, job, "degrad", 0, random_number);
+
+    /* Spatial degradiation: divide by two rounded up the nb or
+     * cores requested, and keep the original duration */
+    job->nb_requested_resources = (orig_nb_core + 1) / 2;
+    Parser::profile_from_duration(profile, job->profile, user->user_name);
+    job->profile = profile->name = 'd' + profile->name;
+
+    return true;
+}
+
+bool degrad_time_job(shared_ptr<Job> &job, Profile *profile, User *user,
+    LoggerUserStat *logger, double random_number)
+{
+    long original_time = std::stol(job->profile);
+
+    /* Log... */
+    log_behavior(logger, job, "degrad_time", 0, random_number);
+    user->dm_stat[2 * DEGRADED]++;
+    user->dm_stat[2 * DEGRADED + 1]
+        += (job->nb_requested_resources) * original_time;
+
+    /* time degrad: divide by two the execution time */
+    long new_time = original_time / 2;
+    Parser::profile_from_duration(
+        profile, std::to_string(new_time), user->user_name);
+    job->profile = profile->name = std::to_string(original_time);
+    return true;
+}
+
+bool delay_job(double new_time, shared_ptr<Job> job,
+    UserSubmitQueue *original_trace, User *user, LoggerUserStat *logger,
+    double random_number)
+{
+
+    /* Log... */
+    log_behavior(
+        logger, job, "delay", new_time - job->submission_time, random_number);
+    user->dm_stat[2 * DELAYED]++;
+    user->dm_stat[2 * DELAYED + 1]
+        += job->nb_requested_resources * std::stol(job->profile);
+
+    /* Update submission date and put job back in the trace */
+    job->submission_time = new_time;
+    original_trace->insert_sorted(job.get());
+
+    /* Return "Do not execute now" */
+    return false;
+}
+
+bool C_you_later_job(double next_time, shared_ptr<Job> job,
+    UserSubmitQueue *original_trace, User *user, LoggerUserStat *logger,
+    double random_number)
+{
+    /* Log... */
+    log_behavior(logger, job, "C_you_later", next_time - job->submission_time,
+        random_number);
+    user->dm_stat[2 * DELAYED]++;
+    user->dm_stat[2 * DELAYED + 1]
+        += job->nb_requested_resources * std::stol(job->profile);
+
+    /* Update the submission date and put job back in the queue */
+    job->submission_time = next_time;
+    original_trace->insert_sorted(job.get());
+
+    /* Return "Do not execute now" */
+    return false;
+}
\ No newline at end of file
diff --git a/src/users/response_behaviors.hpp b/src/users/response_behaviors.hpp
index ecbbb3cd64f67e86e41bbd4b35e3f600abaf77cc..8d62de3214a0d9912870b23ce9e9dd0174ff8f69 100644
--- a/src/users/response_behaviors.hpp
+++ b/src/users/response_behaviors.hpp
@@ -1,25 +1,43 @@
+#include "json_workload.hpp"
 #include "log_user_stat.hpp"
 #include "queue.hpp"
+#include "user.hpp"
 
 using namespace std;
 
-bool rigid_job(shared_ptr<Job> job, Profile *profile, LoggerUserStat *logger,
-    double random_number);
+enum Behavior
+{
+    RIGID,
+    RENONCED,
+    DELAYED,
+    DEGRADED,
+    RECONF,
+    CONSIDER_DEGRADED,
+    CONSIDER_RECONF
+};
+
+void log_behavior(LoggerUserStat *logger, shared_ptr<Job> &job,
+    std::string behavior_name, long delay_time, double random_value);
+
+bool rigid_job(shared_ptr<Job> job, Profile *profile, User *user,
+    LoggerUserStat *logger, double random_number);
 
-bool renounce_job(shared_ptr<Job> job, Profile *profile, LoggerUserStat *logger,
+bool renounce_job(shared_ptr<Job> job, User *user, LoggerUserStat *logger,
     double random_number);
 
-bool reconfig_job(shared_ptr<Job> job, Profile *profile, LoggerUserStat *logger,
-    double random_number);
+bool reconfig_job(shared_ptr<Job> job, Profile *profile, double alpha,
+    User *user, LoggerUserStat *logger, double random_number);
 
-bool degrad_space_job(shared_ptr<Job> &job, Profile *profile,
+bool degrad_space_job(shared_ptr<Job> &job, Profile *profile, User *user,
     LoggerUserStat *logger, double random_number);
 
-bool degrad_time_job(shared_ptr<Job> &job, Profile *profile,
+bool degrad_time_job(shared_ptr<Job> &job, Profile *profile, User *user,
     LoggerUserStat *logger, double random_number);
 
 bool delay_job(double new_time, shared_ptr<Job> job,
-    Queue *original_trace, LoggerUserStat *logger, double random_number);
+    UserSubmitQueue *original_trace, User *user, LoggerUserStat *logger,
+    double random_number);
 
 bool C_you_later_job(double next_time, shared_ptr<Job> job,
-    Queue *original_trace, LoggerUserStat *logger, double random_number);
\ No newline at end of file
+    UserSubmitQueue *original_trace, User *user, LoggerUserStat *logger,
+    double random_number);
\ No newline at end of file
diff --git a/src/users/user.cpp b/src/users/user.cpp
index 7e0ae590c2137d8c752b12f0500ceec86c6479b3..7f5e7bb42303dc54cf465ab7441b623006e980fb 100644
--- a/src/users/user.cpp
+++ b/src/users/user.cpp
@@ -15,12 +15,6 @@ long User::next_submission() const
     return date_of_next_submission;
 }
 
-int *User::get_dm_stat()
-{
-    static int stat[10] = { 0 };
-    return stat;
-}
-
 void User::wake_on_feedback(double date, std::list<shared_ptr<Job>> &ended_jobs)
 {
     return;
diff --git a/src/users/user.hpp b/src/users/user.hpp
index ceef9da1ef85de2530b28aa616c94634671a33fd..a912409ec1a8b67c8518d3f6e85e4b351b8cbce0 100644
--- a/src/users/user.hpp
+++ b/src/users/user.hpp
@@ -6,8 +6,6 @@
 #include <string>
 #include <memory>
 
-#include "scheds/HARD_DEFINED_VAR.hpp"
-
 using namespace std;
 
 class User
@@ -37,19 +35,17 @@ public:
         = 0;
 
     /* For demand response users only: */
-    virtual int *get_dm_stat();
 
     /* For users reacting to feedback: */
     virtual void wake_on_feedback(double date, list<shared_ptr<Job>> &ended_jobs);
 
 public:
     string user_name;
+    long dm_stat[14];
 
 protected:
     long date_of_next_submission;
     long end_submit;
-    // TODO retrieve that info from the platform (wait batsim5.0)
-    double platform_computing_speed = PLATFORM_COMPUTING_SPEED;
 };
 
 /**
diff --git a/src/users/user_feedback.cpp b/src/users/user_feedback.cpp
index 545b9b3d73339945b1ee8cf906e7c8426afcdc2d..698011c977389b52ee370f8ba7009613983da789 100644
--- a/src/users/user_feedback.cpp
+++ b/src/users/user_feedback.cpp
@@ -215,6 +215,6 @@ bool FBUserThinkTimeOnly::handle_job(
     double date, shared_ptr<Job> job, Profile *profile)
 {
     Parser::profile_from_duration(
-        profile, job->profile, user_name, platform_computing_speed);
+        profile, job->profile, user_name);
     return true;
 }
\ No newline at end of file
diff --git a/src/users/user_model.hpp b/src/users/user_model.hpp
index 6269381e061a57f04ffc2d319bc1ae9109643927..d11e689723e82130dc93d9c13adf8d0bc44a858f 100644
--- a/src/users/user_model.hpp
+++ b/src/users/user_model.hpp
@@ -14,8 +14,8 @@ public:
     DichoIntersubmitTimeUser(string name, const rapidjson::Value &param);
     ~DichoIntersubmitTimeUser();
     long next_submission();
-    void jobs_to_submit(
-        double date, list<shared_ptr<Job>> &jobs, list<const Profile *> &profiles);
+    void jobs_to_submit(double date, list<shared_ptr<Job>> &jobs,
+        list<const Profile *> &profiles);
 
 protected:
     list<const Profile *> job_profiles_used();
@@ -26,6 +26,9 @@ private:
     double delay_between_sumbit;
     int job_id = 0;
     shared_ptr<Job> last_job_submitted;
+
+    // TODO retrieve that info from the platform (wait batsim5.0)
+    double platform_computing_speed = PLATFORM_COMPUTING_SPEED;
 };
 
 /**
@@ -37,14 +40,13 @@ private:
 class RoutineGreedyUser : public User
 {
 public:
-    RoutineGreedyUser(string name, long date_first_submit,
-        long date_end_submit, long delay_between_sumbit,
-        int initial_nb_job);
+    RoutineGreedyUser(string name, long date_first_submit, long date_end_submit,
+        long delay_between_sumbit, int initial_nb_job);
     RoutineGreedyUser(string name, const rapidjson::Value &param);
     ~RoutineGreedyUser();
     long next_submission();
-    void jobs_to_submit(
-        double date, list<shared_ptr<Job>> &jobs, list<const Profile *> &profiles);
+    void jobs_to_submit(double date, list<shared_ptr<Job>> &jobs,
+        list<const Profile *> &profiles);
 
 protected:
     list<const Profile *> job_profiles_used();
@@ -59,6 +61,9 @@ private:
     /* Return true if all the jobs previously submitted by the user finished
      * successfully. Also delete the finished jobs. */
     bool previous_jobs_succedded();
+
+    // TODO retrieve that info from the platform (wait batsim5.0)
+    double platform_computing_speed = PLATFORM_COMPUTING_SPEED;
 };
 
 /**
@@ -76,8 +81,8 @@ public:
     ThinkTimeUser(string name, const rapidjson::Value &param);
     ~ThinkTimeUser();
     long next_submission();
-    void jobs_to_submit(
-        double date, list<shared_ptr<Job>> &jobs, list<const Profile *> &profiles);
+    void jobs_to_submit(double date, list<shared_ptr<Job>> &jobs,
+        list<const Profile *> &profiles);
     void wake_on_feedback(double date, list<shared_ptr<Job>> &ended_jobs);
 
 protected:
@@ -87,4 +92,7 @@ private:
     unsigned long think_time;
     int job_id = 0;
     shared_ptr<Job> last_job_submitted;
+
+    // TODO retrieve that info from the platform (wait batsim5.0)
+    double platform_computing_speed = PLATFORM_COMPUTING_SPEED;
 };
\ No newline at end of file
diff --git a/src/users/user_replay.cpp b/src/users/user_replay.cpp
index a90456a6543014dd1cb3bd7dd22ee97d2cc960e5..3377ee6c75ba06e791a72d679a898be08c7b360b 100644
--- a/src/users/user_replay.cpp
+++ b/src/users/user_replay.cpp
@@ -6,7 +6,8 @@
  ******************************* Replay users *********************************
  *****************************************************************************/
 /* Master class ReplayUser */
-void ReplayUser::init_ReplayUser(std::string name, const rapidjson::Value &param)
+void ReplayUser::init_ReplayUser(
+    std::string name, const rapidjson::Value &param)
 {
     /* Parse some info from the json */
     PPK_ASSERT_ERROR(param.HasMember("input_json"),
@@ -54,9 +55,8 @@ void ReplayUser::jobs_to_submit(double date, std::list<shared_ptr<Job>> &jobs,
     while (!original_trace->is_empty()
         && lround(original_trace->top()->submission_time) == lround(date))
     {
-        /* Delete job from the original queue */        
-        shared_ptr<Job> job
-            = shared_ptr<Job>(new Job(*original_trace->pop()));
+        /* Delete job from the original queue */
+        shared_ptr<Job> job = shared_ptr<Job>(new Job(*original_trace->pop()));
         Profile *job_profile = new Profile();
 
         /* Handle the job according to the user behavior. */
@@ -108,17 +108,15 @@ void ReplayUserRigid::jobs_to_submit(double date,
 bool ReplayUserRigid::handle_job(
     double date, shared_ptr<Job> job, Profile *profile)
 {
-    /* Just generate the corresponding profile */
-    Parser::profile_from_duration(
-        profile, job->profile, user_name, platform_computing_speed);
 
-    /* If demande response mode: log if in dm_window */
+    /* If demand response mode: use behavior function handling the log etc. */
     if (dm_window && dm_window->date_in_dm_window(date))
     {
-        dm_stat[2 * RIGID]++;
-        dm_stat[2 * RIGID + 1]
-            += job->nb_requested_resources * std::stol(job->profile);
+        return rigid_job(job, profile, this, logger, -1);
     }
+
+    /* Otherwise: just generate the corresponding profile by hand */
+    Parser::profile_from_duration(profile, job->profile, user_name);
     return true;
 }
 
@@ -162,7 +160,7 @@ Profile *ReplayUserReconfig::build_profile(
         profile->name = flavor + "_" + duration;
 
     double compute_load
-        = std::stod(duration) * nb_core * platform_computing_speed;
+        = std::stod(duration) * nb_core * PLATFORM_COMPUTING_SPEED;
     profile->description
         = "{\"com\": 0.0, \"cpu\": " + std::to_string(compute_load)
         + ", \"type\": \"parallel_homogeneous_total\"}";
@@ -231,8 +229,6 @@ bool DMWindow::date_in_dm_window(double date)
     return date >= inf && date < sup;
 }
 
-
-
 DMUserReconfig::DMUserReconfig(
     std::string name, const rapidjson::Value &param, DMWindow *window)
 {
@@ -253,7 +249,7 @@ DMUserReconfig::DMUserReconfig(
 
 DMUserReconfig::~DMUserReconfig()
 {
-    if(original_trace)
+    if (original_trace)
     {
         delete original_trace;
         original_trace = NULL;
@@ -275,7 +271,7 @@ DMUserDegrad::DMUserDegrad(
 
 DMUserDegrad::~DMUserDegrad()
 {
-    if(original_trace)
+    if (original_trace)
     {
         delete original_trace;
         original_trace = NULL;
@@ -297,7 +293,7 @@ DMUserRenonce::DMUserRenonce(
 
 DMUserRenonce::~DMUserRenonce()
 {
-    if(original_trace)
+    if (original_trace)
     {
         delete original_trace;
         original_trace = NULL;
@@ -319,7 +315,7 @@ DMUserDelay::DMUserDelay(
 
 DMUserDelay::~DMUserDelay()
 {
-    if(original_trace)
+    if (original_trace)
     {
         delete original_trace;
         original_trace = NULL;
@@ -332,152 +328,65 @@ void DMUserDelay::jobs_to_submit(double date, std::list<shared_ptr<Job>> &jobs,
     ReplayUser::jobs_to_submit(date, jobs, profiles);
 }
 
-bool DMUserReconfig::reconfig_job(shared_ptr<Job> job, Profile *profile)
+bool DMUserReconfig::handle_job(
+    double date, shared_ptr<Job> job, Profile *profile)
 {
-    int orig_nb_core = job->nb_requested_resources;
-    dm_stat[2*CONSIDER_RECONF]++;
-    if (orig_nb_core == 1)
+    if (!dm_window->date_in_dm_window(date))
     {
-        /* No reconfig */
-        Parser::profile_from_duration(
-            profile, job->profile, user_name, platform_computing_speed);
-
-        /* Log... */
-        dm_stat[2 * RIGID]++;
-        dm_stat[2 * RIGID + 1] += orig_nb_core * std::stol(job->profile);
-    }
-    else
-    {
-        /* Log... */
-        dm_stat[2 * RECONF]++;
-        dm_stat[2 * RECONF + 1] += orig_nb_core * std::stol(job->profile);
-
-        /* Reconfig: divide by two rounded up the nb or cores requested */
-        int n = (orig_nb_core + 1) / 2;
-
-        /* Speedup model:
-             *   - T_orig: the original execution time (on orig_nb_core cores)
-             *   - T_1: the execution time on one core
-             *   - T_n: the execution time on n cores
-             * We have: T_1 = n^alpha * T_n = orig_nb_core^alpha * T_orig
-             *          => T_n = (orig_nb_core / n)^alpha * T_orig
-         */
-        long T_orig = std::stol(job->profile);
-        long T_n = pow( (double) orig_nb_core / n, alpha) * T_orig;
-        Parser::profile_from_duration(
-            profile, std::to_string(T_n), user_name, platform_computing_speed); // parallel_homogeneous
-        job->nb_requested_resources = n;
-        job->profile = profile->name = 'r' + std::to_string(T_orig);
+        Parser::profile_from_duration(profile, job->profile, user_name);
+        return true;
     }
-    return true;
-}
 
-bool DMUserReconfig::handle_job(double date, shared_ptr<Job> job, Profile *profile)
-{
-    if (dm_window->date_in_dm_window(date))
+    this->dm_stat[2 * CONSIDER_RECONF]++;
+    if (job->nb_requested_resources > 1)
     {
-        return reconfig_job(job,profile);
+        return reconfig_job(job, profile, alpha, this, logger, -1.0);
     }
     else
     {
-        Parser::profile_from_duration(
-            profile, job->profile, user_name, platform_computing_speed);
+        return rigid_job(job, profile, this, logger, -1.0);
     }
-    return true;
 }
 
-bool DMUserDegrad::degrad_job(shared_ptr<Job> job, Profile *profile)
+bool DMUserDegrad::handle_job(
+    double date, shared_ptr<Job> job, Profile *profile)
 {
-    int orig_nb_core = job->nb_requested_resources;
-    dm_stat[2*CONSIDER_DEGRADED]++;
-    if (orig_nb_core == 1)
-    {
-        /* No degrad */
-        Parser::profile_from_duration(
-            profile, job->profile, user_name, platform_computing_speed);
-        /* Log... */
-        dm_stat[2 * RIGID]++;
-        dm_stat[2 * RIGID + 1] += orig_nb_core * std::stol(job->profile);
-    }
-    else
+    if (!dm_window->date_in_dm_window(date))
     {
-        /* Log... */
-        dm_stat[2 * DEGRADED]++;
-        dm_stat[2 * DEGRADED + 1] += orig_nb_core * std::stol(job->profile);
-        /* Spatial degradiation: divide by two rounded up the nb or
-             * cores requested, and keep the original duration */
-        job->nb_requested_resources = (orig_nb_core + 1) / 2;
-        Parser::profile_from_duration(
-            profile, job->profile, user_name, platform_computing_speed);
-        job->profile = profile->name = 'd' + profile->name;
+        Parser::profile_from_duration(profile, job->profile, user_name);
+        return true;
     }
-    return true;
-}
-bool DMUserDegrad::handle_job(double date, shared_ptr<Job> job, Profile *profile)
-{
-    if (dm_window->date_in_dm_window(date))
+
+    this->dm_stat[2 * CONSIDER_DEGRADED]++;
+    if (job->nb_requested_resources > 1)
     {
-        return degrad_job(job,profile);
+        return degrad_space_job(job, profile, this, logger, -1);
     }
     else
     {
-        Parser::profile_from_duration(
-            profile, job->profile, user_name, platform_computing_speed);
+        return rigid_job(job, profile, this, logger, -1);
     }
-    return true;
 }
 
-bool DMUserRenonce::renonce_job(shared_ptr<Job> job)
-{
-    /* Log... */
-    dm_stat[2 * RENONCED]++;
-    dm_stat[2 * RENONCED + 1]
-        += job->nb_requested_resources * std::stol(job->profile);
-
-    /* Signals that the job must not be executed */
-    return false;
-}
-bool DMUserRenonce::handle_job(double date, shared_ptr<Job> job, Profile *profile)
+bool DMUserRenonce::handle_job(
+    double date, shared_ptr<Job> job, Profile *profile)
 {
     if (dm_window->date_in_dm_window(date))
     {
-        return renonce_job(job);
-    }
-    else
-    {
-        Parser::profile_from_duration(
-            profile, job->profile, user_name, platform_computing_speed);
+        return renounce_job(job, this, logger, -1);
     }
-    return true;
-}
 
-bool DMUserDelay::delay_job(shared_ptr<Job> job)
-{
-    /* Log... */
-    dm_stat[2 * DELAYED]++;
-    dm_stat[2 * DELAYED + 1]
-        += job->nb_requested_resources * std::stol(job->profile);
-
-    /* Update submission date and put job back in the trace */
-    job->submission_time = dm_window->sup;
-    original_trace->insert_sorted(job.get());
-
-    /* Return "Do not execute now" */
-    return false;
+    Parser::profile_from_duration(profile, job->profile, user_name);
+    return true;
 }
 
 bool DMUserDelay::handle_job(double date, shared_ptr<Job> job, Profile *profile)
 {
     if (dm_window->date_in_dm_window(date))
     {
-        return delay_job(job);
-    }
-    else
-    {
-        Parser::profile_from_duration(
-            profile, job->profile, user_name, platform_computing_speed);
-        return true;
+        return delay_job(dm_window->sup, job, original_trace, this, logger, -1);
     }
-}
-
 
+    Parser::profile_from_duration(profile, job->profile, user_name);
+    return true;
+}
diff --git a/src/users/user_replay.hpp b/src/users/user_replay.hpp
index 0590df7cae10c9bd87d465dfbc0ae44ecb3939fb..aff97b5316f0867bc170104ea08a0851474f767e 100644
--- a/src/users/user_replay.hpp
+++ b/src/users/user_replay.hpp
@@ -4,6 +4,7 @@
 #pragma once
 #include "json_workload.hpp"
 #include "users/user.hpp"
+#include "users/response_behaviors.hpp"
 #include <random>
 #include "queue.hpp"
 #include "users/log_user_stat.hpp"
@@ -49,6 +50,7 @@ protected:
     DMWindow *dm_window = nullptr;
     int dm_stat[14] = { 0 };
 
+    LoggerUserStat *logger = nullptr;
     /* Keep track of profiles to not send them twice to Batsim */
     std::set<std::string> sent_profiles;
 };
@@ -108,17 +110,6 @@ private:
 /******************************************************************************
  *********************** Users "demand response" ******************************
  *****************************************************************************/
-enum Behavior
-{
-    RIGID,
-    RENONCED,
-    DELAYED,
-    DEGRADED,
-    RECONF,
-    CONSIDER_DEGRADED,
-    CONSIDER_RECONF
-};
-
 /**
  * @brief
  * @details
@@ -134,7 +125,6 @@ public:
         double date, std::list<shared_ptr<Job>> &jobs, std::list<const Profile *> &profiles);
 
 protected:
-    bool reconfig_job(shared_ptr<Job> job,Profile *profile);
     virtual bool handle_job(double date, shared_ptr<Job> job,
         Profile *profile);
     double alpha = 1.0; // for the speedup model 
@@ -155,7 +145,6 @@ public:
         double date, std::list<shared_ptr<Job>> &jobs, std::list<const Profile *> &profiles);
 
 protected:
-    bool degrad_job(shared_ptr<Job> job,Profile *profile);
     bool handle_job(double date, shared_ptr<Job> job, Profile *profile);
 };
 
@@ -174,7 +163,6 @@ public:
         double date, std::list<shared_ptr<Job>> &jobs, std::list<const Profile *> &profiles);
 
 protected:
-    bool renonce_job(shared_ptr<Job> job);
     bool handle_job(double date, shared_ptr<Job> job, Profile *profile);
 };
 
@@ -193,6 +181,5 @@ public:
         double date, std::list<shared_ptr<Job>> &jobs, std::list<const Profile *> &profiles);
 
 protected:
-    bool delay_job(shared_ptr<Job> job);
     bool handle_job(double date, shared_ptr<Job> job, Profile *profile);
 };
diff --git a/src/users/user_windows.cpp b/src/users/user_windows.cpp
index 8bc076eea1d6c6419cb588289e12fb19fdf12c3f..fdd8a2cb5bf6cbef118dff46e3e507a4f5faea1c 100644
--- a/src/users/user_windows.cpp
+++ b/src/users/user_windows.cpp
@@ -2,40 +2,43 @@
 #include "user_windows.hpp"
 #include "../pempek_assert.hpp"
 
-
-DMWindow_list::DMWindow_list(const IntervalSet & interval){
-    this->interval= interval;
+DMWindow_list::DMWindow_list(const IntervalSet &interval)
+{
+    this->interval = interval;
 }
 
+bool DMWindow_list::date_in_dm_window(double date) const
+{
+    /* Returns true if the date is in one of the dm_window of the DMWindow_list
+     */
 
-
-bool DMWindow_list::date_in_dm_window(double date) const{
-    /* Returns true if the date is in one of the dm_window of the DMWindow_list */
-
-    return interval.contains((int) date);
+    return interval.contains((int)date);
 }
 
-bool DMWindow_list::have_no_common_element( DMWindow_list* compare_list) const
+bool DMWindow_list::have_no_common_element(DMWindow_list *compare_list) const
 {
     IntervalSet intersect = interval;
-    intersect &=  compare_list->interval;
+    intersect &= compare_list->interval;
     return intersect.is_empty();
 }
 
-DMWindowAutomata::DMWindowAutomata(DMWindow* dm_window,DMWindow_list* red_windows,
-    DMWindow_list* yellow_windows)
+DMWindowAutomata::DMWindowAutomata(DMWindow *dm_window,
+    DMWindow_list *red_windows, DMWindow_list *yellow_windows)
 {
     this->dm_window = dm_window;
     this->red_windows = red_windows;
     this->yellow_windows = yellow_windows;
 }
-bool DMWindowAutomata::is_in_red_state(double date){
+bool DMWindowAutomata::is_in_red_state(double date)
+{
     // Check whether the date is in a red window
-    return (dm_window && dm_window->date_in_dm_window(date)) || (red_windows && red_windows->date_in_dm_window(date));
+    return (dm_window && dm_window->date_in_dm_window(date))
+        || (red_windows && red_windows->date_in_dm_window(date));
 }
-bool DMWindowAutomata::is_in_yellow_state(double date){
+bool DMWindowAutomata::is_in_yellow_state(double date)
+{
     // Check whether the date is in yellow window
-    return  yellow_windows && yellow_windows->date_in_dm_window(date);
+    return yellow_windows && yellow_windows->date_in_dm_window(date);
 }
 bool DMWindowAutomata::has_red_state()
 {
@@ -53,81 +56,88 @@ StateAutomata::~StateAutomata()
 {
 }
 
-DMUserMultiBehavior::DMUserMultiBehavior(
-        const std::string & name, const rapidjson::Value &param,
-        uint_fast32_t random_seed,StateAutomata* state_automata, LoggerUserStat* logger)
-        : DMUserRenonce(name,param,nullptr),DMUserReconfig(name,param,nullptr),
-        DMUserDegrad(name,param,nullptr)
+DMUserMultiBehavior::DMUserMultiBehavior(const std::string &name,
+    const rapidjson::Value &param, uint_fast32_t random_seed,
+    StateAutomata *state_automata, LoggerUserStat *logger)
+    : DMUserRenonce(name, param, nullptr)
+    , DMUserReconfig(name, param, nullptr)
+    , DMUserDegrad(name, param, nullptr)
 {
     this->state_automata = state_automata;
     this->logger = logger;
     random_gen = std::mt19937(random_seed);
-    red_prob_multi_core= vector<double> (R_TOTAL_MULTI,0.0);
-    red_prob_mono_core = vector<double> (R_TOTAL_MONO,0.0);
-    yellow_prob_mono_core = vector<double> (Y_TOTAL_MONO,0.0);
-    yellow_prob_multi_core = vector<double> (Y_TOTAL_MULTI,0.0);
+    red_prob_multi_core = vector<double>(R_TOTAL_MULTI, 0.0);
+    red_prob_mono_core = vector<double>(R_TOTAL_MONO, 0.0);
+    yellow_prob_mono_core = vector<double>(Y_TOTAL_MONO, 0.0);
+    yellow_prob_multi_core = vector<double>(Y_TOTAL_MULTI, 0.0);
     check_deprecated_param(param);
-    init_prob_mono_core(param,red_prob_mono_core,yellow_prob_mono_core);
-    init_prob_multi_core(param,red_prob_multi_core,yellow_prob_multi_core);
+    init_prob_mono_core(param, red_prob_mono_core, yellow_prob_mono_core);
+    init_prob_multi_core(param, red_prob_multi_core, yellow_prob_multi_core);
 }
 
-
 double DMUserMultiBehavior::parse_proba_param(const rapidjson::Value &param,
-    const std::vector<string> &config_param, std::vector<double> &probability_array,
-    const std::string & window_name, const std::string & type_prob_name)
+    const std::vector<string> &config_param,
+    std::vector<double> &probability_array, const std::string &window_name,
+    const std::string &type_prob_name)
 {
-    //fill the config_param fields to probability_array
+    // fill the config_param fields to probability_array
     double prob_total = 0.0;
-    for (std::vector<double>::size_type i =0 ; i < probability_array.size();i++)
+    for (std::vector<double>::size_type i = 0; i < probability_array.size();
+         i++)
     {
         std::string current_param = config_param[i];
         if (param.HasMember(current_param.c_str()))
         {
             PPK_ASSERT_ERROR(param[current_param.c_str()].IsDouble()
                     && param[current_param.c_str()].GetDouble() >= 0.0,
-                "Error every specified probability should be a non-negative Double");
+                "Error every specified probability should be a non-negative "
+                "Double");
             probability_array[i] = param[current_param.c_str()].GetDouble();
             prob_total += probability_array[i];
         }
     }
     std::string error_message = "Error in parameter defined for user ";
     error_message += user_name;
-    error_message += ". The sum of the probability given in parameter sum to 0.0 for ";
+    error_message
+        += ". The sum of the probability given in parameter sum to 0.0 for ";
     error_message += window_name;
     error_message += ". Check that you gave";
     error_message += type_prob_name;
-    error_message +=" parameter to user and at least one non-zero probability";
+    error_message += " parameter to user and at least one non-zero probability";
     PPK_ASSERT_ERROR(prob_total != 0.0, "%s", error_message.c_str());
     return prob_total;
 }
-void DMUserMultiBehavior::init_prob_mono_core(const rapidjson::Value &param,std::vector<double> & red_prob_array, std::vector<double> & yellow_prob_array){
-    //Red window probability initialization
-    if(state_automata->has_red_state())
+void DMUserMultiBehavior::init_prob_mono_core(const rapidjson::Value &param,
+    std::vector<double> &red_prob_array, std::vector<double> &yellow_prob_array)
+{
+    // Red window probability initialization
+    if (state_automata->has_red_state())
     {
         std::vector<string> red_config(R_TOTAL_MONO, "");
         red_config[R_DEGRAD_MONO] = "red_prob_degrad_mono_core";
         red_config[R_C_YOU_LATER_MONO] = "red_prob_see_you_later_mono_core";
         red_config[R_RENONCE_MONO] = "red_prob_renonce_mono_core";
         red_config[R_RIGID_MONO] = "red_prob_rigid_mono_core";
-        red_prob_total_mono_core
-            = parse_proba_param(param, red_config, red_prob_array,
-                "red_windows","red_windows_prob_mono_core");
+        red_prob_total_mono_core = parse_proba_param(param, red_config,
+            red_prob_array, "red_windows", "red_windows_prob_mono_core");
     }
 
     // Yellow probability Initialization
-    if(state_automata->has_yellow_state())
+    if (state_automata->has_yellow_state())
     {
         std::vector<string> yellow_config(Y_TOTAL_MONO, "");
         yellow_config[Y_DEGRAD_MONO] = "yellow_prob_degrad_mono_core";
         yellow_config[Y_RIGID_MONO] = "yellow_prob_rigid_mono_core";
         yellow_prob_total_mono_core
             = parse_proba_param(param, yellow_config, yellow_prob_array,
-                "yellow_windows","yellow_windows_prob_mono_core");
+                "yellow_windows", "yellow_windows_prob_mono_core");
     }
 }
 
-void DMUserMultiBehavior::init_prob_multi_core(const rapidjson::Value &param,std::vector<double> & red_prob_array, std::vector<double> & yellow_prob_array){
-    //Red window probability initialization
+void DMUserMultiBehavior::init_prob_multi_core(const rapidjson::Value &param,
+    std::vector<double> &red_prob_array, std::vector<double> &yellow_prob_array)
+{
+    // Red window probability initialization
     if (state_automata->has_red_state())
     {
         std::vector<string> red_config(R_TOTAL_MULTI, "");
@@ -136,10 +146,8 @@ void DMUserMultiBehavior::init_prob_multi_core(const rapidjson::Value &param,std
         red_config[R_RECONFIG_MULTI] = "red_prob_reconfig_multi_core";
         red_config[R_RENONCE_MULTI] = "red_prob_renonce_multi_core";
         red_config[R_RIGID_MULTI] = "red_prob_rigid_multi_core";
-        red_prob_total_multi_core
-            = parse_proba_param(param, red_config, red_prob_array,
-                "red_windows","red_windows_prob_multi_core");
-
+        red_prob_total_multi_core = parse_proba_param(param, red_config,
+            red_prob_array, "red_windows", "red_windows_prob_multi_core");
     }
 
     // Yellow probability Initialization
@@ -151,7 +159,7 @@ void DMUserMultiBehavior::init_prob_multi_core(const rapidjson::Value &param,std
         yellow_config[Y_RIGID_MULTI] = "yellow_prob_rigid_multi_core";
         yellow_prob_total_multi_core
             = parse_proba_param(param, yellow_config, yellow_prob_array,
-                "yellow_windows","yellow_windows_prob_multi_core");
+                "yellow_windows", "yellow_windows_prob_multi_core");
     }
 }
 void DMUserMultiBehavior::check_deprecated_param(const rapidjson::Value &param)
@@ -165,224 +173,225 @@ void DMUserMultiBehavior::check_deprecated_param(const rapidjson::Value &param)
     deprecated_option.emplace_back("yellow_prob_degrad");
     deprecated_option.emplace_back("yellow_prob_reconfig");
     deprecated_option.emplace_back("yellow_prob_rigid");
-    for (const std::string& option : deprecated_option){
-        PPK_ASSERT_ERROR(!(param.HasMember(option.c_str())),"%s %s,%s","Use of deprecated option for user,option :",user_name.c_str(),option.c_str());
+    for (const std::string &option : deprecated_option)
+    {
+        PPK_ASSERT_ERROR(!(param.HasMember(option.c_str())), "%s %s,%s",
+            "Use of deprecated option for user,option :", user_name.c_str(),
+            option.c_str());
     }
 }
 DMUserMultiBehavior::~DMUserMultiBehavior()
 {
-    if(original_trace)
+    if (original_trace)
     {
         delete original_trace;
         original_trace = nullptr;
     }
 }
 
-void DMUserMultiBehavior::jobs_to_submit(
-        double date, std::list<shared_ptr<Job>> &jobs, std::list< const Profile *> &profiles)
+void DMUserMultiBehavior::jobs_to_submit(double date,
+    std::list<shared_ptr<Job>> &jobs, std::list<const Profile *> &profiles)
 {
     ReplayUser::jobs_to_submit(date, jobs, profiles);
 }
 
-bool DMUserMultiBehavior::C_you_later_job(double date, double next_time,shared_ptr<Job> job,double random_number)
-{
-    /* Log... */
-    log_behavior(job,"C_you_later",(long) next_time,random_number);
-    dm_stat[2 * DELAYED]++;
-    dm_stat[2*DELAYED+1]+= job->nb_requested_resources * std::stol(job->profile);
-    
-    /* Update the submission date and put job back in the queue */
-    job->submission_time = date + next_time;
-    original_trace->insert_sorted(job.get());
-
-    /* Return "Do not execute now" */
-    return false;
-
-}
-
-bool DMUserMultiBehavior::rigid_job(shared_ptr<Job> job, Profile *profile,
-    double random_number)
+bool DMUserMultiBehavior::exec_red_behavior_mono(
+    std::vector<double>::size_type behavior_number, double date,
+    shared_ptr<Job> job, Profile *profile, double random_number)
 {
-    log_behavior(job,"rigid",0,random_number);
-    Parser::profile_from_duration(
-        profile, job->profile, user_name, platform_computing_speed);
-    dm_stat[2 * RIGID]++;
-    dm_stat[2 * RIGID + 1]
-        += job->nb_requested_resources * std::stol(job->profile);
-    return true;
-}
-bool DMUserMultiBehavior::degrad_space_job(
-    shared_ptr<Job> & job, Profile *profile)
-{
-    return degrad_job(job,profile);
-}
-bool DMUserMultiBehavior::degrad_time_job(shared_ptr<Job> & job, Profile *profile,
-    double random_number)
-{
-    /* Log... */
-    log_behavior(job,"consider_degrad",0,random_number);
-    log_behavior(job,"degrad_time",0,random_number);
-    dm_stat[2 * DEGRADED]++;
-    dm_stat[2 * DEGRADED + 1] += (job->nb_requested_resources) * std::stol(job->profile);
-
-    /* time degrad: divide by two the execution time */
-    long original_time = std::stol(job->profile);
-    long new_time = original_time/2;
-    Parser::profile_from_duration(
-        profile, std::to_string(new_time), user_name, platform_computing_speed);
-    job->profile = profile->name = std::to_string(original_time);
-    return true;
-}
-bool DMUserMultiBehavior::exec_red_behavior_mono(std::vector<double>::size_type behavior_number,double date,shared_ptr<Job> job,Profile *profile, double random_number){
-    if(behavior_number==R_RENONCE_MONO){
-        log_behavior(job,"renonce",0,random_number);
-        return renonce_job(job);
+    if (behavior_number == R_RENONCE_MONO)
+    {
+        return renounce_job(job, this, logger, random_number);
     }
-    if(behavior_number==R_C_YOU_LATER_MONO){
-        return C_you_later_job(date,3600,job,random_number);
+    if (behavior_number == R_C_YOU_LATER_MONO)
+    {
+        return C_you_later_job(
+            date + 3600, job, original_trace, this, logger, random_number);
     }
-    if(behavior_number == R_DEGRAD_MONO){
-        return degrad_time_job(job,profile,random_number);
+    if (behavior_number == R_DEGRAD_MONO)
+    {
+        log_behavior(logger, job, "consider_degrad", 0, random_number);
+        return degrad_time_job(job, profile, this, logger, random_number);
     }
-    if(behavior_number == R_RIGID_MONO){
-        return rigid_job(job,profile,random_number);
+    if (behavior_number == R_RIGID_MONO)
+    {
+        return rigid_job(job, profile, this, logger, random_number);
     }
+
+    PPK_ASSERT_ERROR(false, "Undefined behavior number...");
+    return false;
 }
-bool DMUserMultiBehavior::red_window_behavior_mono_core(double date, shared_ptr<Job> job, Profile *profile)
+
+bool DMUserMultiBehavior::red_window_behavior_mono_core(
+    double date, shared_ptr<Job> job, Profile *profile)
 {
-    double behavior = distribution(random_gen)*red_prob_total_mono_core;
+    double behavior = distribution(random_gen) * red_prob_total_mono_core;
     double total_probability = 0.0;
-    for (std::vector<double>::size_type i =0 ; i < red_prob_mono_core.size();i++){
-        total_probability+=red_prob_mono_core[i];
-        if (behavior < total_probability){
-            return exec_red_behavior_mono(i,date,job,profile,behavior/red_prob_total_mono_core);
+    for (std::vector<double>::size_type i = 0; i < red_prob_mono_core.size();
+         i++)
+    {
+        total_probability += red_prob_mono_core[i];
+        if (behavior < total_probability)
+        {
+            return exec_red_behavior_mono(
+                i, date, job, profile, behavior / red_prob_total_mono_core);
         }
     }
     /* if none of the above we launch the job without changing anything
     Rigid strategy*/
-    return rigid_job(job,profile,behavior/red_prob_total_mono_core);
+    return rigid_job(
+        job, profile, this, logger, behavior / red_prob_total_mono_core);
 }
-bool DMUserMultiBehavior::exec_red_behavior_multi(std::vector<double>::size_type behavior_number,
-    double date,shared_ptr<Job> job,Profile *profile, double random_number)
+
+bool DMUserMultiBehavior::exec_red_behavior_multi(
+    std::vector<double>::size_type behavior_number, double date,
+    shared_ptr<Job> job, Profile *profile, double random_number)
 {
-    if(behavior_number==R_RENONCE_MULTI){
-        log_behavior(job,"renonce",0,random_number);
-        return renonce_job(job);
+    if (behavior_number == R_RENONCE_MULTI)
+    {
+        return renounce_job(job, this, logger, random_number);
     }
-    if(behavior_number==R_C_YOU_LATER_MULTI){
-        return C_you_later_job(date,3600,job,random_number);
+    if (behavior_number == R_C_YOU_LATER_MULTI)
+    {
+        return C_you_later_job(
+            date + 3600, job, original_trace, this, logger, random_number);
     }
-    if(behavior_number == R_DEGRAD_MULTI){
-        log_behavior(job,"consider_degrad",0,random_number);
-        log_behavior(job,"degrad",0,random_number);
-        return degrad_space_job(job,profile);
+    if (behavior_number == R_DEGRAD_MULTI)
+    {
+        log_behavior(logger, job, "consider_degrad", 0, random_number);
+        return degrad_space_job(job, profile, this, logger, random_number);
     }
-    if(behavior_number == R_RECONFIG_MULTI){
-        log_behavior(job,"consider_reconfig",0,random_number);
-        log_behavior(job,"reconfig",0,random_number);
-        return reconfig_job(job,profile);
+    if (behavior_number == R_RECONFIG_MULTI)
+    {
+        log_behavior(logger, job, "consider_reconfig", 0, random_number);
+        return reconfig_job(job, profile, 1.0, this, logger, random_number);
     }
-    if(behavior_number == R_RIGID_MULTI){
-        return rigid_job(job,profile,random_number);
+    if (behavior_number == R_RIGID_MULTI)
+    {
+        return rigid_job(job, profile, this, logger, random_number);
+    }
+    else
+    {
+        PPK_ASSERT_ERROR(false, "Undefined behavior number...");
+        return false;
     }
 }
-bool DMUserMultiBehavior::red_window_behavior_multi_core(double date, shared_ptr<Job> job, Profile *profile)
+
+bool DMUserMultiBehavior::red_window_behavior_multi_core(
+    double date, shared_ptr<Job> job, Profile *profile)
 {
-    double behavior = distribution(random_gen)*red_prob_total_multi_core;
+    double behavior = distribution(random_gen) * red_prob_total_multi_core;
     double total_probability = 0.0;
-    for (std::vector<double>::size_type i =0 ; i < red_prob_multi_core.size();i++){
-        total_probability+=red_prob_multi_core[i];
-        if (behavior < total_probability){
-            return exec_red_behavior_multi(i,date,job,profile,behavior/red_prob_total_multi_core);
+    for (std::vector<double>::size_type i = 0; i < red_prob_multi_core.size();
+         i++)
+    {
+        total_probability += red_prob_multi_core[i];
+        if (behavior < total_probability)
+        {
+            return exec_red_behavior_multi(
+                i, date, job, profile, behavior / red_prob_total_multi_core);
         }
     }
-    return rigid_job(job,profile,behavior/red_prob_total_multi_core);
+    return rigid_job(
+        job, profile, this, logger, behavior / red_prob_total_multi_core);
 }
 
-bool DMUserMultiBehavior::red_window_behavior(double date,shared_ptr<Job> & job,Profile *profile)
+bool DMUserMultiBehavior::red_window_behavior(
+    double date, shared_ptr<Job> &job, Profile *profile)
 {
     /*
-         * We decide at random the behavior
-         * (renounce, C_you_later, degrad, reconfig,rigid)
-         * that will be done on this job
+     * We decide at random the behavior
+     * (renounce, C_you_later, degrad, reconfig,rigid)
+     * that will be done on this job
      */
-    if (job->nb_requested_resources== 1){
-        return red_window_behavior_mono_core(date,job,profile);
+    if (job->nb_requested_resources == 1)
+    {
+        return red_window_behavior_mono_core(date, job, profile);
     }
     else
     {
-        return red_window_behavior_multi_core(date,job,profile);
+        return red_window_behavior_multi_core(date, job, profile);
     }
-
 }
-bool DMUserMultiBehavior::yellow_window_behavior_mono_core(shared_ptr<Job> job, Profile *profile)
+bool DMUserMultiBehavior::yellow_window_behavior_mono_core(
+    shared_ptr<Job> job, Profile *profile)
 {
-    double behavior = distribution(random_gen)*yellow_prob_total_mono_core;
+    double behavior = distribution(random_gen) * yellow_prob_total_mono_core;
     double total_probability = 0.0;
     total_probability += yellow_prob_mono_core[Y_DEGRAD_MONO];
-    if (behavior < total_probability){
-        return degrad_time_job(job,profile,behavior/yellow_prob_total_mono_core);
+    if (behavior < total_probability)
+    {
+        log_behavior(logger, job, "consider_degrad", 0,
+            behavior / yellow_prob_total_mono_core);
+        return degrad_time_job(
+            job, profile, this, logger, behavior / yellow_prob_total_mono_core);
     }
     // if none of the above we launch the job without i.e. rigid strategy
-    return rigid_job(job,profile,behavior/yellow_prob_total_mono_core);
+    return rigid_job(
+        job, profile, this, logger, behavior / yellow_prob_total_mono_core);
 }
-bool DMUserMultiBehavior::yellow_window_behavior_multi_core(shared_ptr<Job> job, Profile *profile)
+bool DMUserMultiBehavior::yellow_window_behavior_multi_core(
+    shared_ptr<Job> job, Profile *profile)
 {
-    double behavior = distribution(random_gen)*yellow_prob_total_multi_core;
+    double behavior = distribution(random_gen) * yellow_prob_total_multi_core;
     double total_probability = 0.0;
-    total_probability+= yellow_prob_multi_core[Y_RECONFIG_MULTI];
-    if (behavior < total_probability){
-        log_behavior(job,"consider_reconfig",0,behavior/yellow_prob_total_multi_core);
-        log_behavior(job, "reconfig", 0,behavior/yellow_prob_total_multi_core);
-        return reconfig_job(job,profile);
+    total_probability += yellow_prob_multi_core[Y_RECONFIG_MULTI];
+    if (behavior < total_probability)
+    {
+        log_behavior(logger, job, "consider_reconfig", 0,
+            behavior / yellow_prob_total_multi_core);
+        return reconfig_job(job, profile, 1.0, this, logger,
+            behavior / yellow_prob_total_multi_core);
     }
     total_probability += yellow_prob_multi_core[Y_DEGRAD_MULTI];
-    if (behavior < total_probability){
-        log_behavior(job,"consider_degrad",0,behavior/yellow_prob_total_multi_core);
-        log_behavior(job, "degrad", 0,behavior/yellow_prob_total_multi_core);
-        return degrad_space_job(job,profile);
+    if (behavior < total_probability)
+    {
+        log_behavior(logger, job, "consider_degrad", 0,
+            behavior / yellow_prob_total_multi_core);
+        return degrad_space_job(job, profile, this, logger,
+            behavior / yellow_prob_total_multi_core);
     }
     // if none of the above we launch the job without i.e. rigid strategy
-    return rigid_job(job,profile,behavior/yellow_prob_total_multi_core);
+    return rigid_job(
+        job, profile, this, logger, behavior / yellow_prob_total_multi_core);
 }
-bool DMUserMultiBehavior::yellow_window_behavior(shared_ptr<Job> & job,Profile *profile){
+bool DMUserMultiBehavior::yellow_window_behavior(
+    shared_ptr<Job> &job, Profile *profile)
+{
     /*
-         * We decide at random the behavior (rigid, degrad, reconfig)
-         * that will be done on this job
+     * We decide at random the behavior (rigid, degrad, reconfig)
+     * that will be done on this job
      */
-    if(job->nb_requested_resources == 1 ){
-        return yellow_window_behavior_mono_core(job,profile);
-    }
-    else{
-        return yellow_window_behavior_multi_core(job,profile);
+    if (job->nb_requested_resources == 1)
+    {
+        return yellow_window_behavior_mono_core(job, profile);
     }
-
-}
-
-void DMUserMultiBehavior::log_behavior(shared_ptr<Job> & job,std::string behavior_name, long delay_time, double random_value)
-{
-    if(logger){
-        logger->add_stat(job,std::move(behavior_name),delay_time,random_value);
+    else
+    {
+        return yellow_window_behavior_multi_core(job, profile);
     }
 }
 
-bool DMUserMultiBehavior::handle_job(double date, shared_ptr<Job> job, Profile *profile)
+bool DMUserMultiBehavior::handle_job(
+    double date, shared_ptr<Job> job, Profile *profile)
 {
-    //red_windows and dm_windows check
-    if(state_automata->is_in_red_state(date)) {
-        return red_window_behavior(date, job,profile);
+    // red_windows and dm_windows check
+    if (state_automata->is_in_red_state(date))
+    {
+        return red_window_behavior(date, job, profile);
     }
 
     // yellow_windows check
-    if (state_automata->is_in_yellow_state(date)){
+    if (state_automata->is_in_yellow_state(date))
+    {
         /*
-          * We decide at random the behavior (rigid,degrad, reconfig)
-          * that will be done on this job
+         * We decide at random the behavior (rigid,degrad, reconfig)
+         * that will be done on this job
          */
-        return yellow_window_behavior(job,profile);
+        return yellow_window_behavior(job, profile);
     }
     else
     {
-        return rigid_job(job,profile,1.0);
+        return rigid_job(job, profile, this, logger, 1.0);
     }
 }
diff --git a/src/users/user_windows.hpp b/src/users/user_windows.hpp
index 50c4fb3217576b6bd80a2d34fac04234fd6328a5..d3268994ff8d0f95b1ee172a95fc1712b874d72e 100644
--- a/src/users/user_windows.hpp
+++ b/src/users/user_windows.hpp
@@ -92,13 +92,6 @@ protected:
     void init_prob_multi_core(const rapidjson::Value &param,
         vector<double> &red_prob_array, vector<double> & yellow_prob_array);
     void check_deprecated_param(const rapidjson::Value &param);
-    void log_behavior(shared_ptr<Job>  & job,  std::string behavior_name,
-        long delay_time,double random_value);
-    bool rigid_job(shared_ptr<Job> job,Profile* profile,double random_number);
-    bool degrad_space_job(shared_ptr<Job> & job,Profile* profile);
-    bool degrad_time_job(shared_ptr<Job> & job,Profile* profile, double random_number);
-    bool C_you_later_job(double date, double next_time,shared_ptr<Job> job,
-        double random_number);
 
     /**
      *  @brief function called each time the user want to submit a job