diff --git a/meson.build b/meson.build
index fbdfd5612bca7c73114362510192bbd2fdb9ee9e..b1d3247c851c56e17362d77848ac171f434f9f9e 100644
--- a/meson.build
+++ b/meson.build
@@ -26,54 +26,14 @@ batsched_deps = [
 
 # Source files
 src = [
-    'src/algo/conservative_bf.cpp',
-    'src/algo/conservative_bf.hpp',
-    'src/algo/crasher.cpp',
-    'src/algo/crasher.hpp',
     'src/algo/easy_bf.cpp',
-    'src/algo/easy_bf_fast.cpp',
-    'src/algo/easy_bf_fast.hpp',
     'src/algo/easy_bf.hpp',
-    'src/algo/easy_bf_plot_liquid_load_horizon.cpp',
-    'src/algo/easy_bf_plot_liquid_load_horizon.hpp',
-    'src/algo/energy_bf.cpp',
-    'src/algo/energy_bf_dicho.cpp',
-    'src/algo/energy_bf_dicho.hpp',
-    'src/algo/energy_bf.hpp',
-    'src/algo/energy_bf_idle_sleeper.cpp',
-    'src/algo/energy_bf_idle_sleeper.hpp',
-    'src/algo/energy_bf_machine_subpart_sleeper.cpp',
-    'src/algo/energy_bf_machine_subpart_sleeper.hpp',
-    'src/algo/energy_bf_monitoring_inertial_shutdown.cpp',
-    'src/algo/energy_bf_monitoring_inertial_shutdown.hpp',
-    'src/algo/energy_bf_monitoring_period.cpp',
-    'src/algo/energy_bf_monitoring_period.hpp',
-    'src/algo/energy_watcher.cpp',
-    'src/algo/energy_watcher.hpp',
-    'src/algo/fcfs_fast.cpp',
-    'src/algo/fcfs_fast.hpp',
     'src/algo/fcfs.cpp',
     'src/algo/fcfs.hpp',
-    'src/algo/filler.cpp',
-    'src/algo/filler.hpp',
-    'src/algo/killer2.cpp',
-    'src/algo/killer2.hpp',
-    'src/algo/killer.cpp',
-    'src/algo/killer.hpp',
-    'src/algo/random.cpp',
-    'src/algo/random.hpp',
     'src/algo/rejecter.cpp',
     'src/algo/rejecter.hpp',
     'src/algo/sequencer.cpp',
     'src/algo/sequencer.hpp',
-    'src/algo/sequencer_dvfs.cpp',
-    'src/algo/sequencer_dvfs.hpp',
-    'src/algo/sleeper.cpp',
-    'src/algo/sleeper.hpp',
-    'src/algo/submitter.cpp',
-    'src/algo/submitter.hpp',
-    'src/algo/wt_estimator.cpp',
-    'src/algo/wt_estimator.hpp',
     'src/decision.cpp',
     'src/decision.hpp',
     'src/exact_numbers.hpp',
diff --git a/src/algo/conservative_bf.cpp b/src/algo/conservative_bf.cpp
deleted file mode 100644
index fd165e7b8444c3f178d0ec9c0580502732c76738..0000000000000000000000000000000000000000
--- a/src/algo/conservative_bf.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-#include "conservative_bf.hpp"
-
-#include <loguru.hpp>
-
-#include "../pempek_assert.hpp"
-
-using namespace std;
-
-ConservativeBackfilling::ConservativeBackfilling(Workload *workload, SchedulingDecision *decision,
-                                                 Queue *queue, ResourceSelector * selector, double rjms_delay, rapidjson::Document *variant_options) :
-    ISchedulingAlgorithm(workload, decision, queue, selector, rjms_delay, variant_options)
-{
-    if (variant_options->HasMember("dump_previsional_schedules"))
-    {
-        PPK_ASSERT_ERROR((*variant_options)["dump_previsional_schedules"].IsBool(),
-                "Invalid options: 'dump_previsional_schedules' should be a boolean");
-        _dump_provisional_schedules = (*variant_options)["dump_previsional_schedules"].GetBool();
-    }
-
-    if (variant_options->HasMember("dump_prefix"))
-    {
-        PPK_ASSERT_ERROR((*variant_options)["dump_prefix"].IsString(),
-                "Invalid options: 'dump_prefix' should be a string");
-        _dump_prefix = (*variant_options)["dump_prefix"].GetString();
-    }
-}
-
-ConservativeBackfilling::~ConservativeBackfilling()
-{
-}
-
-void ConservativeBackfilling::on_simulation_start(double date, const rapidjson::Value & batsim_config)
-{
-    _schedule = Schedule(_nb_machines, date);
-    (void) batsim_config;
-}
-
-void ConservativeBackfilling::on_simulation_end(double date)
-{
-    (void) date;
-}
-
-void ConservativeBackfilling::make_decisions(double date,
-                                             SortableJobOrder::UpdateInformation *update_info,
-                                             SortableJobOrder::CompareInformation *compare_info)
-{
-    // Let's remove finished jobs from the schedule
-    for (const string & ended_job_id : _jobs_ended_recently)
-        _schedule.remove_job((*_workload)[ended_job_id]);
-
-    // Let's handle recently released jobs
-    std::vector<std::string> recently_queued_jobs;
-    for (const string & new_job_id : _jobs_released_recently)
-    {
-        const Job * new_job = (*_workload)[new_job_id];
-
-        if (new_job->nb_requested_resources > _nb_machines)
-        {
-            _decision->add_reject_job(new_job_id, date);
-        }
-        else if (!new_job->has_walltime)
-        {
-            LOG_SCOPE_FUNCTION(INFO);
-            LOG_F(INFO, "Date=%g. Rejecting job '%s' as it has no walltime", date, new_job_id.c_str());
-            _decision->add_reject_job(new_job_id, date);
-        }
-        else
-        {
-            _queue->append_job(new_job, update_info);
-            recently_queued_jobs.push_back(new_job_id);
-        }
-    }
-
-    // Let's update the schedule's present
-    _schedule.update_first_slice(date);
-
-    // Queue sorting
-    _queue->sort_queue(update_info, compare_info);
-
-    // If no resources have been released, we can just insert the new jobs into the schedule
-    if (_jobs_ended_recently.empty())
-    {
-        for (const string & new_job_id : recently_queued_jobs)
-        {
-            const Job * new_job = (*_workload)[new_job_id];
-            Schedule::JobAlloc alloc = _schedule.add_job_first_fit(new_job, _selector);
-
-            // If the job should start now, let's say it to the resource manager
-            if (alloc.started_in_first_slice)
-            {
-                _decision->add_execute_job(new_job->id, alloc.used_machines, date);
-                _queue->remove_job(new_job);
-            }
-        }
-    }
-    else
-    {
-        // Since some resources have been freed,
-        // Let's compress the schedule following conservative backfilling rules:
-        // For each non running job j
-        //   Remove j from the schedule
-        //   Add j into the schedule
-        //   If j should be executed now
-        //     Take the decision to run j now
-        for (auto job_it = _queue->begin(); job_it != _queue->end(); )
-        {
-            const Job * job = (*job_it)->job;
-
-            _schedule.remove_job_if_exists(job);
-//            if (_dump_provisional_schedules)
-//                _schedule.incremental_dump_as_batsim_jobs_file(_dump_prefix);
-            Schedule::JobAlloc alloc = _schedule.add_job_first_fit(job, _selector);
-//            if (_dump_provisional_schedules)
-//                _schedule.incremental_dump_as_batsim_jobs_file(_dump_prefix);
-
-            if (alloc.started_in_first_slice)
-            {
-                _decision->add_execute_job(job->id, alloc.used_machines, date);
-                job_it = _queue->remove_job(job_it);
-            }
-            else
-                ++job_it;
-        }
-    }
-
-    // And now let's see if we can estimate some waiting times
-    
-    for (const std::string & job_id : _jobs_whose_waiting_time_estimation_has_been_requested_recently)
-    {
-        const Job * new_job = (*_workload)[job_id];
-        double answer = _schedule.query_wait(new_job->nb_requested_resources, new_job->walltime, _selector);
-            _decision->add_answer_estimate_waiting_time(job_id, answer, date);
-    }
-
-    if (_dump_provisional_schedules)
-        _schedule.incremental_dump_as_batsim_jobs_file(_dump_prefix);
-}
diff --git a/src/algo/conservative_bf.hpp b/src/algo/conservative_bf.hpp
deleted file mode 100644
index 717a991479edb20b21ef1e992093d4e609820beb..0000000000000000000000000000000000000000
--- a/src/algo/conservative_bf.hpp
+++ /dev/null
@@ -1,29 +0,0 @@
-#pragma once
-
-#include <list>
-
-#include "../isalgorithm.hpp"
-#include "../json_workload.hpp"
-#include "../locality.hpp"
-#include "../schedule.hpp"
-
-class ConservativeBackfilling : public ISchedulingAlgorithm
-{
-public:
-    ConservativeBackfilling(Workload * workload, SchedulingDecision * decision, Queue * queue, ResourceSelector * selector,
-                            double rjms_delay, rapidjson::Document * variant_options);
-    virtual ~ConservativeBackfilling();
-
-    virtual void on_simulation_start(double date, const rapidjson::Value & batsim_config);
-
-    virtual void on_simulation_end(double date);
-
-    virtual void make_decisions(double date,
-                                SortableJobOrder::UpdateInformation * update_info,
-                                SortableJobOrder::CompareInformation * compare_info);
-
-private:
-    Schedule _schedule;
-    bool _dump_provisional_schedules = false;
-    std::string _dump_prefix = "/tmp/dump";
-};
diff --git a/src/algo/crasher.cpp b/src/algo/crasher.cpp
deleted file mode 100644
index 1339973e0d11e878e0cc0bfdad87d825998845b4..0000000000000000000000000000000000000000
--- a/src/algo/crasher.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-#include "crasher.hpp"
-
-#include "../pempek_assert.hpp"
-
-// Mouhahahaha
-#include <stdlib.h>
-#include <signal.h>
-
-#include <stdexcept>
-
-#include <loguru.hpp>
-
-Crasher::CrashType Crasher::crash_type_from_string(const std::string &str)
-{
-    if (str == "segmentation_fault") return CrashType::SEGMENTATION_FAULT;
-    else if (str == "infinite_loop") return CrashType::INFINITE_LOOP;
-    else if (str == "terminate_processus_success") return CrashType::TERMINATE_PROCESSUS_SUCCESS;
-    else if (str == "terminate_processus_failure") return CrashType::TERMINATE_PROCESSUS_FAILURE;
-    else if (str == "abort") return CrashType::ABORT;
-    else if (str == "suspend_process") return CrashType::SUSPEND_PROCESS;
-    else
-    {
-        PPK_ASSERT_ERROR(false, "Invalid crash type string: %s", str.c_str());
-        return CrashType::SEGMENTATION_FAULT;
-    }
-}
-
-std::string Crasher::crash_type_to_string(Crasher::CrashType type)
-{
-    switch(type)
-    {
-    case CrashType::SEGMENTATION_FAULT: return "segmentation_fault";
-    case CrashType::INFINITE_LOOP: return "infinite_loop";
-    case CrashType::TERMINATE_PROCESSUS_SUCCESS: return "terminate_processus_success";
-    case CrashType::TERMINATE_PROCESSUS_FAILURE: return "terminate_processus_failure";
-    case CrashType::ABORT: return "abort";
-    case CrashType::SUSPEND_PROCESS: return "suspend_process";
-    }
-
-    throw std::invalid_argument("Unknown crash type");
-}
-
-Crasher::Crasher(Workload *workload,
-                   SchedulingDecision *decision,
-                   Queue *queue,
-                   ResourceSelector *selector,
-                   double rjms_delay,
-                   rapidjson::Document *variant_options) :
-    Sequencer(workload, decision, queue, selector, rjms_delay, variant_options)
-{
-    if (variant_options->HasMember("crash_on_start"))
-    {
-        PPK_ASSERT_ERROR((*variant_options)["crash_on_start"].IsBool(),
-                "Invalid options: 'crash_on_start' should be a boolean");
-        _crash_on_start = (*variant_options)["crash_on_start"].GetBool();
-    }
-
-    if (variant_options->HasMember("crash_on_end"))
-    {
-        PPK_ASSERT_ERROR((*variant_options)["crash_on_end"].IsBool(),
-                "Invalid options: 'crash_on_end' should be a boolean");
-        _crash_on_end = (*variant_options)["crash_on_end"].GetBool();
-    }
-
-    if (variant_options->HasMember("crash_on_decision_call"))
-    {
-        PPK_ASSERT_ERROR((*variant_options)["crash_on_decision_call"].IsBool(),
-                "Invalid options: 'crash_on_decision_call' should be a boolean");
-        _crash_on_decision_call = (*variant_options)["crash_on_decision_call"].GetBool();
-    }
-
-    if (variant_options->HasMember("crash_on_decision_call_number"))
-    {
-        PPK_ASSERT_ERROR((*variant_options)["crash_on_decision_call_number"].IsNumber(),
-                "Invalid options: 'crash_on_decision_call_number' should be a number");
-        _crash_on_decision_call_number = (*variant_options)["crash_on_decision_call_number"].GetInt();
-        PPK_ASSERT_ERROR(_crash_on_decision_call_number >= 0,
-                         "Invalid options: 'crash_on_decision_call_number' should be non-negative "
-                         "but got value=%d", _crash_on_decision_call_number);
-    }
-
-    if (variant_options->HasMember("crash_type"))
-    {
-        PPK_ASSERT_ERROR((*variant_options)["crash_type"].IsString(),
-                "Invalid options: 'crash_type' should be a string");
-        std::string crash_type_str = (*variant_options)["crash_type"].GetString();
-        _crash_type = crash_type_from_string(crash_type_str);
-    }
-
-    LOG_SCOPE_FUNCTION(INFO);
-    LOG_F(INFO, "crash_on_start: %d", _crash_on_start);
-    LOG_F(INFO, "crash_on_end: %d", _crash_on_end);
-    LOG_F(INFO, "crash_on_decision_call: %d", _crash_on_decision_call);
-    LOG_F(INFO, "crash_on_decision_call_number: %d", _crash_on_decision_call_number);
-    LOG_F(INFO, "crash_type: %s", crash_type_to_string(_crash_type).c_str());
-}
-
-Crasher::~Crasher()
-{
-
-}
-
-void Crasher::on_simulation_start(double date, const rapidjson::Value &batsim_config)
-{
-    if (_crash_on_start)
-        crash(_crash_type);
-
-    Sequencer::on_simulation_start(date, batsim_config);
-}
-
-void Crasher::on_simulation_end(double date)
-{
-    if (_crash_on_end)
-        crash(_crash_type);
-
-    Sequencer::on_simulation_end(date);
-}
-
-void Crasher::make_decisions(double date,
-                             SortableJobOrder::UpdateInformation *update_info,
-                             SortableJobOrder::CompareInformation *compare_info)
-{
-    ++_decision_call_number;
-    if (_crash_on_decision_call && _decision_call_number >= _crash_on_decision_call_number)
-        crash(_crash_type);
-
-    Sequencer::make_decisions(date, update_info, compare_info);
-}
-
-void Crasher::crash(Crasher::CrashType type)
-{
-    switch(type)
-    {
-    case CrashType::SEGMENTATION_FAULT:
-        raise(SIGSEGV);
-    case CrashType::INFINITE_LOOP:
-    { for (;;); }
-    case CrashType::TERMINATE_PROCESSUS_SUCCESS:
-        exit(EXIT_SUCCESS);
-    case CrashType::TERMINATE_PROCESSUS_FAILURE:
-        exit(EXIT_FAILURE);
-    case CrashType::ABORT:
-        abort();
-    case CrashType::SUSPEND_PROCESS:
-        raise(SIGTSTP);
-    }
-}
diff --git a/src/algo/crasher.hpp b/src/algo/crasher.hpp
deleted file mode 100644
index e954433d995e5d53a8d60e45b6151a7870e0cf51..0000000000000000000000000000000000000000
--- a/src/algo/crasher.hpp
+++ /dev/null
@@ -1,59 +0,0 @@
-#pragma once
-
-#include "sequencer.hpp"
-
-#include "../locality.hpp"
-#include <intervalset.hpp>
-
-class Workload;
-class SchedulingDecision;
-
-/**
- * @brief The amazing and gorgeous Crasher scheduler
- * @details This scheduler is meant to crash!
- *          It allows various types of crash,
- *          and allows to define when the crash should occur.
- */
-
-class Crasher : public Sequencer
-{
-public:
-    enum class CrashType
-    {
-        SEGMENTATION_FAULT,
-        INFINITE_LOOP,
-        TERMINATE_PROCESSUS_SUCCESS,
-        TERMINATE_PROCESSUS_FAILURE,
-        ABORT,
-        SUSPEND_PROCESS,
-    };
-
-    CrashType crash_type_from_string(const std::string & str);
-    std::string crash_type_to_string(CrashType type);
-
-public:
-    Crasher(Workload * workload, SchedulingDecision * decision, Queue * queue, ResourceSelector * selector,
-             double rjms_delay, rapidjson::Document * variant_options);
-
-    virtual ~Crasher();
-
-    void on_simulation_start(double date, const rapidjson::Value & batsim_config);
-
-    void on_simulation_end(double date);
-
-    virtual void make_decisions(double date,
-                                SortableJobOrder::UpdateInformation * update_info,
-                                SortableJobOrder::CompareInformation * compare_info);
-
-private:
-    static void crash(CrashType type);
-
-private:
-    bool _crash_on_start = false;
-    bool _crash_on_end = true;
-
-    bool _crash_on_decision_call = false;
-    int _crash_on_decision_call_number = 0;
-    int _decision_call_number = -1;
-    CrashType _crash_type = CrashType::SEGMENTATION_FAULT;
-};
diff --git a/src/algo/easy_bf_fast.cpp b/src/algo/easy_bf_fast.cpp
deleted file mode 100644
index c74d25a4e99a0245ed4fd2c9d51d45aaf4316f92..0000000000000000000000000000000000000000
--- a/src/algo/easy_bf_fast.cpp
+++ /dev/null
@@ -1,292 +0,0 @@
-#include "easy_bf_fast.hpp"
-
-//#include <loguru.hpp>
-
-#include "../pempek_assert.hpp"
-
-EasyBackfillingFast::EasyBackfillingFast(Workload *workload,
-    SchedulingDecision *decision, Queue *queue, ResourceSelector *selector,
-    double rjms_delay, rapidjson::Document *variant_options) :
-    ISchedulingAlgorithm(workload, decision, queue, selector, rjms_delay,
-        variant_options)
-{}
-
-EasyBackfillingFast::~EasyBackfillingFast()
-{}
-
-void EasyBackfillingFast::on_simulation_start(double date,
-    const rapidjson::Value &batsim_config)
-{
-    (void) date;
-    (void) batsim_config;
-
-    _available_machines.insert(IntervalSet::ClosedInterval(0, _nb_machines - 1));
-    _nb_available_machines = _nb_machines;
-    PPK_ASSERT_ERROR(_available_machines.size() == (unsigned int) _nb_machines);
-}
-
-void EasyBackfillingFast::on_simulation_end(double date)
-{
-    (void) date;
-}
-
-void EasyBackfillingFast::make_decisions(double date,
-    SortableJobOrder::UpdateInformation *update_info,
-    SortableJobOrder::CompareInformation *compare_info)
-{
-    (void) update_info;
-    (void) compare_info;
-
-    // This algorithm is a fast version of EASY backfilling.
-    // It is meant to be fast in the usual case, not to handle corner cases
-    // (use the other easy backfilling available in batsched for this purpose).
-    // It is not meant to be easily readable or hackable ;).
-
-    // This fast EASY backfilling variant in a few words:
-    // - only handles the FCFS queue order
-    // - only handles the basic resource selection policy
-    // - only handles finite jobs (no switchoff), with walltimes
-    // - only handles one priority job (the first of the queue)
-    // - only handles time as floating-point (-> precision errors).
-
-    // Warning: you might obtain different outputs than with easy_bf. This is
-    // due to the fact that this version only keeps track of the priority job
-    // expected start time and the number of machines available then, while
-    // easy_bf keeps track of a full 2D schedule of the future. easy_bf_fast
-    // will sometimes be a little more greedy in backfilling.
-
-    bool job_ended = false;
-
-    // Handle newly finished jobs
-    for (const std::string & ended_job_id : _jobs_ended_recently)
-    {
-        job_ended = true;
-
-        Job * finished_job = (*_workload)[ended_job_id];
-        const Allocation & alloc = _current_allocations[ended_job_id];
-
-        // Update data structures
-        _available_machines.insert(alloc.machines);
-        _nb_available_machines += finished_job->nb_requested_resources;
-        _horizons.erase(alloc.horizon_it);
-        _current_allocations.erase(ended_job_id);
-    }
-
-    // If jobs have finished, let's execute jobs as long as they are priority
-    if (job_ended)
-    {
-        if (_priority_job != nullptr)
-        {
-            Allocation alloc;
-            FinishedHorizonPoint point;
-
-            if (_priority_job->nb_requested_resources <= _nb_available_machines)
-            {
-                //LOG_F(INFO, "Priority job fits!");
-                alloc.machines = _available_machines.left(
-                    _priority_job->nb_requested_resources);
-                _decision->add_execute_job(_priority_job->id, alloc.machines,
-                    date);
-
-                point.nb_released_machines = _priority_job->nb_requested_resources;
-                point.date = date + (double)_priority_job->walltime;
-                alloc.horizon_it = insert_horizon_point(point);
-
-                // Update data structures
-                _available_machines -= alloc.machines;
-                _nb_available_machines -= _priority_job->nb_requested_resources;
-                _current_allocations[_priority_job->id] = alloc;
-                _priority_job = nullptr;
-
-                // Execute the whole queue until a priority job cannot fit
-                for (auto job_it = _pending_jobs.begin();
-                     job_it != _pending_jobs.end(); )
-                {
-                    Job * pending_job = *job_it;
-                    if (pending_job->nb_requested_resources <= _nb_available_machines)
-                    {
-                        alloc.machines = _available_machines.left(
-                            pending_job->nb_requested_resources);
-                        _decision->add_execute_job(pending_job->id,
-                            alloc.machines, date);
-
-                        point.nb_released_machines = pending_job->nb_requested_resources;
-                        point.date = date + (double)pending_job->walltime;
-                        alloc.horizon_it = insert_horizon_point(point);
-
-                        // Update data structures
-                        _available_machines -= alloc.machines;
-                        _nb_available_machines -= pending_job->nb_requested_resources;
-                        _current_allocations[pending_job->id] = alloc;
-                        job_it = _pending_jobs.erase(job_it);
-                    }
-                    else
-                    {
-                        // The job becomes priority!
-                        _priority_job = pending_job;
-                        update_priority_job_expected_earliest_start_time();
-                        _pending_jobs.erase(job_it);
-
-                        // Stop first queue traversal.
-                        break;
-                    }
-                }
-            }
-
-            // Backfill jobs that does not hinder priority job.
-            if (_nb_available_machines > 0)
-            {
-                // Update priority job expected starting time (might have changed if a recently ended job
-                // completed before its walltime)
-                if (_priority_job != nullptr)
-                    update_priority_job_expected_earliest_start_time();
-
-                for (auto job_it = _pending_jobs.begin();
-                     job_it != _pending_jobs.end(); )
-                {
-                    const Job * pending_job = *job_it;
-                    // Can the job be executed now (without hindering priority job)?
-                    if (pending_job->nb_requested_resources <= _nb_available_machines &&
-                    (date + pending_job->walltime <= _priority_job_expected_start_time ||
-                    pending_job->nb_requested_resources <= _remaining_resources_at_priority_job_start))
-                    {
-                        // Yes, it can be backfilled!
-                        alloc.machines = _available_machines.left(
-                            pending_job->nb_requested_resources);
-                        _decision->add_execute_job(pending_job->id,
-                            alloc.machines, date);
-
-                        point.nb_released_machines = pending_job->nb_requested_resources;
-                        point.date = date + (double)pending_job->walltime;
-                        alloc.horizon_it = insert_horizon_point(point);
-
-                        // Update data structures
-                        _available_machines -= alloc.machines;
-                        _nb_available_machines -= pending_job->nb_requested_resources;
-                        _current_allocations[pending_job->id] = alloc;
-                        job_it = _pending_jobs.erase(job_it);
-                        if(date + pending_job->walltime > _priority_job_expected_start_time)
-                            _remaining_resources_at_priority_job_start -= pending_job->nb_requested_resources;
-
-                        // Directly get out of the backfilling loop if all machines are busy.
-                        if (_nb_available_machines <= 0)
-                            break;
-                    }
-                    else
-                    {
-                        ++job_it;
-                    }
-                }
-            }
-        }
-    }
-
-    // Handle newly released jobs
-    for (const std::string & new_job_id : _jobs_released_recently)
-    {
-        Job * new_job = (*_workload)[new_job_id];
-
-
-        // Is the job valid on this platform?
-        if (new_job->nb_requested_resources > _nb_machines)
-        {
-            _decision->add_reject_job(new_job_id, date);
-        }
-        else if (!new_job->has_walltime)
-        {
-            _decision->add_reject_job(new_job_id, date);
-        }
-
-        // Can the job be executed right now?
-        else if (new_job->nb_requested_resources <= _nb_available_machines)
-        {
-            //LOG_F(INFO, "There are enough available resources (%d) to execute job %s", _nb_available_machines, new_job->id.c_str());
-            // Can it be executed now (without hindering priority job)?
-            if (_priority_job == nullptr ||
-                date + new_job->walltime <= _priority_job_expected_start_time ||
-                new_job->nb_requested_resources <= _remaining_resources_at_priority_job_start)
-            {
-                //LOG_F(INFO, "Job %s can be started right away!", new_job->id.c_str());
-                // Yes, the job can be executed right away!
-                Allocation alloc;
-
-                alloc.machines = _available_machines.left(
-                    new_job->nb_requested_resources);
-                _decision->add_execute_job(new_job_id, alloc.machines, date);
-
-                FinishedHorizonPoint point;
-                point.nb_released_machines = new_job->nb_requested_resources;
-                point.date = date + (double)new_job->walltime;
-                alloc.horizon_it = insert_horizon_point(point);
-
-                // Update data structures
-                _available_machines -= alloc.machines;
-                _nb_available_machines -= new_job->nb_requested_resources;
-                _current_allocations[new_job_id] = alloc;
-                if(_priority_job != nullptr && date + new_job->walltime > _priority_job_expected_start_time)
-                    _remaining_resources_at_priority_job_start -= new_job->nb_requested_resources;
-            }
-            else
-            {
-                // No, the job cannot be executed (hinders priority job.)
-                /*LOG_F(INFO, "Not enough time to execute job %s (walltime=%g, priority job expected starting time=%g)",
-                      new_job->id.c_str(), (double)new_job->walltime, _priority_job_expected_start_time);*/
-                _pending_jobs.push_back(new_job);
-            }
-        }
-        else
-        {
-            // The job is too big to fit now.
-
-            if (_priority_job == nullptr)
-            {
-                // The job becomes priority.
-                _priority_job = new_job;
-                update_priority_job_expected_earliest_start_time();
-            }
-            else
-            {
-                // The job is queued up.
-                _pending_jobs.push_back(new_job);
-            }
-        }
-    }
-}
-
-void EasyBackfillingFast::update_priority_job_expected_earliest_start_time()
-{
-    int nb_available = _nb_available_machines;
-    int required = _priority_job->nb_requested_resources;
-
-    for (auto it = _horizons.begin(); it != _horizons.end(); ++it)
-    {
-        nb_available += it->nb_released_machines;
-
-        if (nb_available >= required)
-        {
-            _priority_job_expected_start_time = it->date;
-            _remaining_resources_at_priority_job_start = nb_available - required;
-            return;
-        }
-    }
-
-    PPK_ASSERT_ERROR(false, "The job will never be executable.");
-    return;
-}
-
-std::list<EasyBackfillingFast::FinishedHorizonPoint>::iterator EasyBackfillingFast::insert_horizon_point(const EasyBackfillingFast::FinishedHorizonPoint &point)
-{
-    // The data structure is sorted, we can therefore traverse it in order
-    // until finding an insertion point.
-    for (auto it = _horizons.begin(); it != _horizons.end(); ++it)
-    {
-        if (point.date < it->date)
-        {
-            // Insertion point is before the current iterator.
-            return _horizons.insert(it, point);
-        }
-    }
-
-    // Insertion point not found. Insertion at end.
-    return _horizons.insert(_horizons.end(), point);
-}
diff --git a/src/algo/easy_bf_fast.hpp b/src/algo/easy_bf_fast.hpp
deleted file mode 100644
index 5a449bce0fa3499005309d8d9dc5b90600aa198a..0000000000000000000000000000000000000000
--- a/src/algo/easy_bf_fast.hpp
+++ /dev/null
@@ -1,64 +0,0 @@
-#pragma once
-
-#include <unordered_map>
-#include <list>
-
-#include "../isalgorithm.hpp"
-#include "../json_workload.hpp"
-#include "../locality.hpp"
-
-class EasyBackfillingFast : public ISchedulingAlgorithm
-{
-public:
-    EasyBackfillingFast(Workload * workload, SchedulingDecision * decision,
-        Queue * queue, ResourceSelector * selector,
-        double rjms_delay,
-        rapidjson::Document * variant_options);
-    virtual ~EasyBackfillingFast();
-
-    virtual void on_simulation_start(double date,
-        const rapidjson::Value & batsim_config);
-
-    virtual void on_simulation_end(double date);
-
-    virtual void make_decisions(double date,
-        SortableJobOrder::UpdateInformation * update_info,
-        SortableJobOrder::CompareInformation * compare_info);
-
-private:
-    struct FinishedHorizonPoint
-    {
-        double date;
-        int nb_released_machines;
-    };
-
-    struct Allocation
-    {
-        IntervalSet machines;
-        std::list<FinishedHorizonPoint>::iterator horizon_it;
-    };
-
-private:
-    void update_priority_job_expected_earliest_start_time();
-    std::list<FinishedHorizonPoint>::iterator insert_horizon_point(const FinishedHorizonPoint & point);
-
-private:
-    // Machines currently available
-    IntervalSet _available_machines;
-    int _nb_available_machines = -1;
-
-    // Pending jobs (queue; without the priority job)
-    std::list<Job *> _pending_jobs;
-
-    // Allocations of running jobs
-    std::unordered_map<std::string, Allocation> _current_allocations;
-
-    // When running jobs are expected to finish.
-    // Always sorted by increasing date.
-    std::list<FinishedHorizonPoint> _horizons;
-
-    // At any time, null if there is no priority job (no waiting job)
-    Job * _priority_job = nullptr;
-    double _priority_job_expected_start_time = -1;
-    int _remaining_resources_at_priority_job_start = -1;
-};
diff --git a/src/algo/easy_bf_plot_liquid_load_horizon.cpp b/src/algo/easy_bf_plot_liquid_load_horizon.cpp
deleted file mode 100644
index 338f8ffedc5e14ce97a183120a4bb113cdc8b16f..0000000000000000000000000000000000000000
--- a/src/algo/easy_bf_plot_liquid_load_horizon.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-#include "easy_bf_plot_liquid_load_horizon.hpp"
-
-#include "../pempek_assert.hpp"
-
-using namespace std;
-
-EasyBackfillingPlotLiquidLoadHorizon::EasyBackfillingPlotLiquidLoadHorizon(Workload * workload,
-                                                                           SchedulingDecision * decision,
-                                                                           Queue * queue,
-                                                                           ResourceSelector * selector,
-                                                                           double rjms_delay,
-                                                                           rapidjson::Document * variant_options) :
-    EasyBackfilling(workload, decision, queue, selector, rjms_delay, variant_options)
-{
-
-    PPK_ASSERT_ERROR(variant_options->HasMember("trace_output_filename"),
-                     "Invalid options JSON object: Member 'trace_output_filename' cannot be found");
-    PPK_ASSERT_ERROR((*variant_options)["trace_output_filename"].IsString(),
-            "Invalid options JSON object: Member 'trace_output_filename' must be a string");
-    string trace_output_filename = (*variant_options)["trace_output_filename"].GetString();
-
-    _output_file.open(trace_output_filename);
-    PPK_ASSERT_ERROR(_output_file.is_open(), "Couldn't open file %s", trace_output_filename.c_str());
-
-    string buf = "date,nb_jobs_in_queue,load_in_queue,liquid_load_horizon\n";
-    //string buf = "date,nb_jobs_in_queue,load_in_queue,liquid_load_horizon,qt_mean_wt\n";
-    _output_file.write(buf.c_str(), buf.size());
-}
-
-EasyBackfillingPlotLiquidLoadHorizon::~EasyBackfillingPlotLiquidLoadHorizon()
-{
-    _output_file.close();
-}
-
-void EasyBackfillingPlotLiquidLoadHorizon::make_decisions(double date,
-                                                          SortableJobOrder::UpdateInformation *update_info,
-                                                          SortableJobOrder::CompareInformation *compare_info)
-{
-    for (const string & new_job_id : _jobs_released_recently)
-    {
-        const Job * new_job = (*_workload)[new_job_id];
-        PPK_ASSERT_ERROR(new_job->has_walltime,
-                         "This scheduler only supports jobs with walltimes.");
-    }
-
-    EasyBackfilling::make_decisions(date, update_info, compare_info);
-    write_current_metrics_in_file(date);
-}
-
-void EasyBackfillingPlotLiquidLoadHorizon::write_current_metrics_in_file(double date)
-{
-    Rational liquid_load_horizon = compute_liquid_load_horizon(_schedule, _queue, date);
-
-    /*Rational queueing_theory_period = 60*60*24*10;
-    estimator.remove_old(date - queueing_theory_period);
-    Rational qt_mean_wt = estimator.estimate_waiting_time(queueing_theory_period);*/
-
-    const int buf_size = 256;
-    int nb_printed;
-    char * buf = (char *) malloc(sizeof(char) * buf_size);
-
-    nb_printed = snprintf(buf, buf_size, "%g,%d,%g,%g\n", date, _queue->nb_jobs(),
-                          (double) _queue->compute_load_estimation(),
-                          (double) liquid_load_horizon);
-                          //(double) qt_mean_wt);
-    PPK_ASSERT_ERROR(nb_printed < buf_size - 1,
-                     "Buffer too small, some information might have been lost!");
-    _output_file.write(buf, strlen(buf));
-
-    free(buf);
-}
-
-Rational EasyBackfillingPlotLiquidLoadHorizon::compute_liquid_load_horizon(const Schedule &schedule,
-                                                                           const Queue *queue,
-                                                                           Rational starting_time)
-{
-    // Let's check whether the starting_time is valid
-    PPK_ASSERT_ERROR(starting_time >= schedule.first_slice_begin());
-    PPK_ASSERT_ERROR(starting_time < schedule.infinite_horizon());
-
-    // Let's compute the total load (area) in the queue
-    Rational load_to_distribute = queue->compute_load_estimation();
-
-    // Let's fill the queue load into the schedule by fluidifying it
-    auto slice_it = schedule.find_last_time_slice_before_date(starting_time, false);
-    Rational current_time = starting_time;
-
-    while (load_to_distribute > 0 && slice_it != schedule.end())
-    {
-        const Schedule::TimeSlice & slice = *slice_it;
-
-        // If the starting time is in the middle of the schedule, the whole
-        // time slice length is not to be considered.
-        Rational amount_of_time_to_consider = max(Rational(0), slice.end - max(starting_time, slice.begin));
-        Rational slice_empty_area = slice.available_machines.size() * amount_of_time_to_consider;
-
-        if (slice_empty_area <= load_to_distribute)
-        {
-            load_to_distribute -= slice_empty_area;
-            current_time = slice.end;
-            ++slice_it;
-        }
-        else
-        {
-            PPK_ASSERT_ERROR(slice.available_machines.size() > 0);
-            Rational amount_of_time_needed_to_fill_last_slice = load_to_distribute / slice.available_machines.size();
-            current_time += amount_of_time_needed_to_fill_last_slice;
-            load_to_distribute = 0;
-        }
-    }
-
-    // Degenerate case: all the machines are probably in a sleep state
-    if (load_to_distribute > 0)
-        current_time = schedule.infinite_horizon();
-
-    Rational ret_value = current_time - starting_time;
-    PPK_ASSERT_ERROR(ret_value >= 0);
-    return ret_value;
-}
diff --git a/src/algo/easy_bf_plot_liquid_load_horizon.hpp b/src/algo/easy_bf_plot_liquid_load_horizon.hpp
deleted file mode 100644
index 29f536bd394368e5307c40854bd53cfe5dae38d7..0000000000000000000000000000000000000000
--- a/src/algo/easy_bf_plot_liquid_load_horizon.hpp
+++ /dev/null
@@ -1,36 +0,0 @@
-#pragma once
-
-#include <fstream>
-
-#include "easy_bf.hpp"
-#include "../queueing_theory_waiting_time_estimator.hpp"
-
-class EasyBackfillingPlotLiquidLoadHorizon : public EasyBackfilling
-{
-public:
-    EasyBackfillingPlotLiquidLoadHorizon(Workload * workload,
-                                         SchedulingDecision * decision,
-                                         Queue * queue,
-                                         ResourceSelector * selector,
-                                         double rjms_delay,
-                                         rapidjson::Document * variant_options);
-
-    virtual ~EasyBackfillingPlotLiquidLoadHorizon();
-
-    virtual void make_decisions(double date,
-                                SortableJobOrder::UpdateInformation * update_info,
-                                SortableJobOrder::CompareInformation * compare_info);
-
-public:
-    void write_current_metrics_in_file(double date);
-
-public:
-    static Rational compute_liquid_load_horizon(const Schedule & schedule,
-                                                const Queue * queue,
-                                                Rational starting_time);
-
-private:
-    std::ofstream _output_file;
-    //QueueingTheoryWaitingTimeEstimator estimator;
-};
-
diff --git a/src/algo/energy_bf.cpp b/src/algo/energy_bf.cpp
deleted file mode 100644
index 7f3cb7687583b66c78a1e7fec5fd54f7addeb143..0000000000000000000000000000000000000000
--- a/src/algo/energy_bf.cpp
+++ /dev/null
@@ -1,1373 +0,0 @@
-#include "energy_bf.hpp"
-
-#include <boost/algorithm/string.hpp>
-#include <boost/regex.hpp>
-
-#include <loguru.hpp>
-
-#include "../pempek_assert.hpp"
-
-using namespace std;
-
-EnergyBackfilling::MachineInformation::MachineInformation(int machine_id) :
-    machine_number(machine_id)
-{
-    PPK_ASSERT_ERROR(machine_id >= 0);
-    create_selector();
-}
-
-EnergyBackfilling::MachineInformation::~MachineInformation()
-{
-    free_jobs();
-    free_selector();
-}
-
-void EnergyBackfilling::MachineInformation::create_jobs(double rjms_delay,
-                                                        Rational ensured_sleep_time_lower_bound,
-                                                        Rational ensured_sleep_time_upper_bound)
-{
-    PPK_ASSERT_ERROR(rjms_delay >= 0);
-    PPK_ASSERT_ERROR(ensured_sleep_time_lower_bound <= ensured_sleep_time_upper_bound);
-    PPK_ASSERT_ERROR(switch_on_job == nullptr);
-    PPK_ASSERT_ERROR(switch_off_job == nullptr);
-    PPK_ASSERT_ERROR(ensured_sleep_job == nullptr);
-    PPK_ASSERT_ERROR(potential_sleep_job == nullptr);
-    PPK_ASSERT_ERROR(machine_number > -1);
-    PPK_ASSERT_ERROR(switch_on_seconds > 0);
-    PPK_ASSERT_ERROR(switch_off_seconds > 0);
-    PPK_ASSERT_ERROR(switch_on_energy > 0);
-    PPK_ASSERT_ERROR(switch_off_energy > 0);
-    PPK_ASSERT_ERROR(idle_epower > 0);
-    PPK_ASSERT_ERROR(sleep_epower >= 0);
-    PPK_ASSERT_ERROR(idle_epower > sleep_epower);
-
-    switch_on_job = new Job;
-    switch_on_job->id = "fakejob_son_" + to_string(machine_number);
-    switch_on_job->nb_requested_resources = 1;
-    switch_on_job->submission_time = 0;
-    switch_on_job->walltime = (double) switch_on_seconds + rjms_delay;
-
-    switch_off_job = new Job;
-    switch_off_job->id = "fakejob_soff_" + to_string(machine_number);
-    switch_off_job->nb_requested_resources = 1;
-    switch_off_job->submission_time = 0;
-    switch_off_job->walltime = (double) switch_off_seconds + rjms_delay;
-
-    /* Let us determine the minimum time that should be waited to avoid pure loss of energy via switchON + switchOFF.
-     * When a machine is switched OFF then ON, the time can be split in 3 parts :
-     *   - a, the switching OFF part. In this part, the power is pOFF
-     *   - s, the asleep part. In this part, the power is pSLEEP
-     *   - b, the switching ON part. In this part, the power is pON
-     *
-     * pIDLE is the power used by the machine in idle state.
-     * We want to ensure that the switch OFF then ON does not take more energy than staying in idle state:
-     *   a * pOFF + s * pSLEEP + b * pON <= (a+s+b) * pIDLE
-     *   (a * pOFF) + (s * pSLEEP) + (b * pON) <= ((a+b) * pIDLE) + (s * pIDLE)
-     *   (s * pSLEEP) - (s * pIDLE) <= ((a+b) * pIDLE) - (a * pOFF) - (b * pON)
-     *   s * (pSLEEP - pIDLE) <= ((a+b) * pIDLE) - (a * pOFF) - (b * pON)
-     *   s >= (((a+b) * pIDLE) - (a * pOFF) - (b * pON)) / (pSLEEP - pIDLE) because (pSLEEP - pIDLE) is negative <=> pIDLE > pSLEEP
-     */
-
-    Rational minimum_sleeping_time = ((switch_off_seconds + switch_on_seconds + 2 * rjms_delay) * idle_epower - switch_off_energy - switch_on_energy) / (sleep_epower - idle_epower);
-
-    minimum_sleeping_time = min(max(minimum_sleeping_time,
-                                    ensured_sleep_time_lower_bound),
-                                ensured_sleep_time_upper_bound);
-
-    ensured_sleep_job = new Job;
-    ensured_sleep_job->id = "fakejob_esleep_" + to_string(machine_number);
-    ensured_sleep_job->nb_requested_resources = 1;
-    ensured_sleep_job->submission_time = 0;
-    ensured_sleep_job->walltime = (double) minimum_sleeping_time;
-
-    potential_sleep_job = new Job;
-    potential_sleep_job->id = "fakejob_psleep_" + to_string(machine_number);
-    potential_sleep_job->nb_requested_resources = 1;
-    potential_sleep_job->submission_time = 0;
-    potential_sleep_job->walltime = std::numeric_limits<double>::max();
-}
-
-void EnergyBackfilling::MachineInformation::free_jobs()
-{
-    if (switch_on_job)
-    {
-        delete switch_on_job;
-        switch_on_job = nullptr;
-    }
-
-    if (switch_off_job)
-    {
-        delete switch_off_job;
-        switch_off_job = nullptr;
-    }
-
-    if (ensured_sleep_job)
-    {
-        delete ensured_sleep_job;
-        ensured_sleep_job = nullptr;
-    }
-
-    if (potential_sleep_job)
-    {
-        delete potential_sleep_job;
-        potential_sleep_job = nullptr;
-    }
-}
-
-void EnergyBackfilling::MachineInformation::create_selector()
-{
-    PPK_ASSERT_ERROR(limited_resource_selector  == nullptr);
-    PPK_ASSERT_ERROR(machine_number >= 0);
-
-    limited_resource_selector  = new LimitedRangeResourceSelector(IntervalSet(machine_number));
-}
-
-void EnergyBackfilling::MachineInformation::free_selector()
-{
-    if (limited_resource_selector != nullptr)
-    {
-        delete limited_resource_selector;
-        limited_resource_selector = nullptr;
-    }
-}
-
-
-
-string EnergyBackfilling::machine_state_to_string(const EnergyBackfilling::MachineState &state)
-{
-    switch (state)
-    {
-    case AWAKE: return "awake";
-    case ASLEEP: return "asleep";
-    case SWITCHING_OFF: return "switching_off";
-    case SWITCHING_ON: return "switching_on";
-    }
-
-    PPK_ASSERT_ERROR(false, "Unhandled case");
-    return "unhandled_case";
-}
-
-
-
-EnergyBackfilling::EnergyBackfilling(Workload * workload, SchedulingDecision * decision, Queue * queue, ResourceSelector * selector,
-                                     double rjms_delay, rapidjson::Document * variant_options) :
-    ISchedulingAlgorithm(workload, decision, queue, selector, rjms_delay, variant_options)
-{
-}
-
-EnergyBackfilling::~EnergyBackfilling()
-{
-    clear_machine_informations();
-}
-
-void EnergyBackfilling::on_simulation_start(double date, const rapidjson::Value & batsim_config)
-{
-    _schedule = Schedule(_nb_machines, date);
-    (void) batsim_config;
-
-    generate_machine_informations(_nb_machines);
-
-    _all_machines = IntervalSet::ClosedInterval(0, _nb_machines - 1);
-    PPK_ASSERT_ERROR((int)(_all_machines.size()) == _nb_machines);
-
-    _awake_machines.insert(_all_machines);
-}
-
-void EnergyBackfilling::on_simulation_end(double date)
-{
-    (void) date;
-    // TODO: do something about this?
-}
-
-void EnergyBackfilling::on_machine_state_changed(double date, IntervalSet machines, int new_state)
-{
-    if (_debug)
-    {
-        LOG_F(1, "on_machine_state_changed beginning, schedule : %s", _schedule.to_string().c_str());
-    }
-
-    // Let's update the current schedule to take the machine state change into account
-    IntervalSet switched_off_machines;
-
-    // Let's remove all related switch jobs from the online schedule
-    for (auto machine_it = machines.elements_begin(); machine_it != machines.elements_end(); ++machine_it)
-    {
-        int machine_id = *machine_it;
-        MachineInformation * machine_info = _machine_informations.at(machine_id);
-
-        PPK_ASSERT_ERROR(new_state == machine_info->compute_pstate ||
-                         new_state == machine_info->sleep_pstate,
-                         "Machine %d just changed its pstate to %d, "
-                         "but this pstate is unknown. compute_pstate=%d, "
-                         "sleep_pstate=%d.", machine_id, new_state,
-                         machine_info->compute_pstate,
-                         machine_info->sleep_pstate);
-
-        if (new_state == machine_info->compute_pstate)
-        {
-            // A Switch ON has been acknowledged. Let's remove the switch job from the schedule
-            bool switch_on_job_removed = _schedule.remove_job_if_exists(machine_info->switch_on_job);
-            PPK_ASSERT_ERROR(switch_on_job_removed,
-                             "Machine %d has just been switched ON, but there was "
-                             "no switch ON job for it in the schedule...\n%s",
-                             machine_id, _schedule.to_string().c_str());
-
-            // Update machine state
-            PPK_ASSERT_ERROR(_switching_on_machines.contains(machine_id),
-                             "Machine %d has just been switched ON, but the "
-                             "machine was not marked as a switching ON one. "
-                             "switching_on_machines=%s",
-                             machine_id,
-                             _switching_on_machines.to_string_brackets().c_str());
-            _switching_on_machines.remove(machine_id);
-
-            PPK_ASSERT_ERROR(!_awake_machines.contains(machine_id),
-                             "Machine %d has just been switched ON, but the "
-                             "machine was already marked as an awake machine... "
-                             "awake_machines=%s",
-                             machine_id,
-                             _awake_machines.to_string_brackets().c_str());
-            _awake_machines.insert(machine_id);
-        }
-        else
-        {
-            // A Switch OFF has been acknowledged. Let's remove the switch job from the schedule
-            bool switch_off_job_removed = _schedule.remove_job_if_exists(machine_info->switch_off_job);
-            PPK_ASSERT_ERROR(switch_off_job_removed,
-                             "Machine %d has just been switched OFF, but there was "
-                             "no switch OFF job for it in the schedule...\n%s",
-                             machine_id, _schedule.to_string().c_str());
-
-            // Update machine state
-            PPK_ASSERT_ERROR(_switching_off_machines.contains(machine_id),
-                             "Machine %d has just been switched OFF, but the "
-                             "machine was not marked as a switching OFF one. "
-                             "switching_off_machines=%s",
-                             machine_id,
-                             _switching_off_machines.to_string_brackets().c_str());
-            _switching_off_machines.remove(machine_id);
-
-            PPK_ASSERT_ERROR(!_asleep_machines.contains(machine_id),
-                             "Machine %d has just been switched OFF, but the "
-                             "machine was already marked as an asleep one... "
-                             "asleep_machines=%s",
-                             machine_id, _asleep_machines.to_string_brackets().c_str());
-            _asleep_machines.insert(machine_id);
-
-            if (_schedule.contains_job(machine_info->ensured_sleep_job))
-                _non_wakable_asleep_machines.insert(machine_id);
-            else
-            {
-                PPK_ASSERT_ERROR(_schedule.contains_job(machine_info->potential_sleep_job),
-                                 "Machine %d has just been switched OFF, but there "
-                                 "was no ensured nor potential sleep job in the schedule "
-                                 "for this machine.\n%s", machine_id,
-                                 _schedule.to_string().c_str());
-                _wakable_asleep_machines.insert(machine_id);
-            }
-
-            // Let's mark that the sleep jobs of this machine should be translated to the left
-            switched_off_machines.insert(machine_id);
-        }
-    }
-
-    if (_debug)
-    {
-        LOG_F(1, "on_machine_state_changed, before sleep jobs translation. %s", _schedule.to_string().c_str());
-    }
-
-    // Let's translate to the left (-> present) the sleep jobs that comes from newly asleep machines
-    for (auto machine_it = switched_off_machines.elements_begin(); machine_it != switched_off_machines.elements_end(); ++machine_it)
-    {
-        int machine_id = *machine_it;
-        MachineInformation * machine_info = _machine_informations.at(machine_id);
-
-        // Let's remove previously existing sleep jobs
-        _schedule.remove_job_if_exists(machine_info->ensured_sleep_job);
-
-        bool removed_potential_sleep = _schedule.remove_job_if_exists(machine_info->potential_sleep_job);
-        PPK_ASSERT_ERROR(removed_potential_sleep,
-                         "Machine %d has just been switched OFF, but there was no "
-                         "potential sleep job in the schedule for this machine.\n%s",
-                         machine_id, _schedule.to_string().c_str());
-
-        // Let's insert them back in the schedule at the right place
-        sedate_machine_without_switch(_schedule, machine_id, date);
-    }
-
-    if (_debug)
-    {
-        LOG_F(1, "on_machine_state_changed before update_first_slice, schedule : %s", _schedule.to_string().c_str());
-    }
-}
-
-void EnergyBackfilling::on_requested_call(double date)
-{
-    (void) date;
-    PPK_ASSERT_ERROR(_nb_call_me_later_running > 0,
-                     "Received a REQUESTED_CALL message from Batsim while there "
-                     "was no running call_me_later request.");
-    _nb_call_me_later_running--;
-}
-
-void EnergyBackfilling::generate_machine_informations(int nb_machines)
-{
-    PPK_ASSERT_ERROR(nb_machines > 0);
-
-    // Let's parse the options file
-    PPK_ASSERT_ERROR(_variant_options->HasMember("power_compute"), "Invalid options JSON object: Member 'power_compute' cannot be found");
-    PPK_ASSERT_ERROR((*_variant_options)["power_compute"].IsNumber(), "Invalid options JSON object: Member 'power_compute' must be a number");
-    Rational power_compute = (*_variant_options)["power_compute"].GetDouble();
-    PPK_ASSERT_ERROR(power_compute > 0, "Invalid options JSON object: Member 'power_compute' must be strictly positive (got %g)", (double)power_compute);
-
-    PPK_ASSERT_ERROR(_variant_options->HasMember("power_idle"), "Invalid options JSON object: Member 'power_idle' cannot be found");
-    PPK_ASSERT_ERROR((*_variant_options)["power_idle"].IsNumber(), "Invalid options JSON object: Member 'power_idle' must be a number");
-    Rational power_idle = (*_variant_options)["power_idle"].GetDouble();
-    PPK_ASSERT_ERROR(power_idle > 0, "Invalid options JSON object: Member 'power_idle' must be strictly positive (got %g)", (double)power_idle);
-
-    PPK_ASSERT_ERROR(_variant_options->HasMember("power_sleep"), "Invalid options JSON object: Member 'power_sleep' cannot be found");
-    PPK_ASSERT_ERROR((*_variant_options)["power_sleep"].IsNumber(), "Invalid options JSON object: Member 'power_sleep' must be a number");
-    Rational power_sleep = (*_variant_options)["power_sleep"].GetDouble();
-    PPK_ASSERT_ERROR(power_sleep > 0, "Invalid options JSON object: Member 'power_sleep' must be strictly positive (got %g)", (double)power_sleep);
-
-
-    PPK_ASSERT_ERROR(_variant_options->HasMember("pstate_compute"), "Invalid options JSON object: Member 'pstate_compute' cannot be found");
-    PPK_ASSERT_ERROR((*_variant_options)["pstate_compute"].IsInt(), "Invalid options JSON object: Member 'pstate_compute' must be integral");
-    int pstate_compute = (*_variant_options)["pstate_compute"].GetInt();
-    PPK_ASSERT_ERROR(pstate_compute >= 0, "Invalid options JSON object: Member 'pstate_compute' value must be positive (got %d)", pstate_compute);
-
-    PPK_ASSERT_ERROR(_variant_options->HasMember("pstate_sleep"), "Invalid options JSON object: Member 'pstate_sleep' cannot be found");
-    PPK_ASSERT_ERROR((*_variant_options)["pstate_sleep"].IsInt(), "Invalid options JSON object: Member 'pstate_sleep' must be integral");
-    int pstate_sleep = (*_variant_options)["pstate_sleep"].GetInt();
-    PPK_ASSERT_ERROR(pstate_sleep >= 0, "Invalid options JSON object: Member 'pstate_sleep' value must be positive (got %d)", pstate_sleep);
-
-
-    PPK_ASSERT_ERROR(_variant_options->HasMember("time_switch_on"), "Invalid options JSON object: Member 'time_switch_on' cannot be found");
-    PPK_ASSERT_ERROR((*_variant_options)["time_switch_on"].IsNumber(), "Invalid options JSON object: Member 'time_switch_on' must be a number");
-    Rational time_switch_on = (*_variant_options)["time_switch_on"].GetDouble();
-    PPK_ASSERT_ERROR(time_switch_on > 0, "Invalid options JSON object: Member 'time_switch_on' value must be strictly positive (got %g)", (double)time_switch_on);
-
-    PPK_ASSERT_ERROR(_variant_options->HasMember("time_switch_off"), "Invalid options JSON object: Member 'time_switch_off' cannot be found");
-    PPK_ASSERT_ERROR((*_variant_options)["time_switch_off"].IsNumber(), "Invalid options JSON object: Member 'time_switch_off' must be a number");
-    Rational time_switch_off = (*_variant_options)["time_switch_off"].GetDouble();
-    PPK_ASSERT_ERROR(time_switch_off > 0, "Invalid options JSON object: Member 'time_switch_off' value must be strictly positive (got %g)", (double)time_switch_off);
-
-
-    PPK_ASSERT_ERROR(_variant_options->HasMember("energy_switch_on"), "Invalid options JSON object: Member 'energy_switch_on' cannot be found");
-    PPK_ASSERT_ERROR((*_variant_options)["energy_switch_on"].IsNumber(), "Invalid options JSON object: Member 'energy_switch_on' must be a number");
-    Rational energy_switch_on = (*_variant_options)["energy_switch_on"].GetDouble();
-    PPK_ASSERT_ERROR(energy_switch_on > 0, "Invalid options JSON object: Member 'energy_switch_on' value must be strictly positive (got %g)", (double)energy_switch_on);
-
-    PPK_ASSERT_ERROR(_variant_options->HasMember("energy_switch_off"), "Invalid options JSON object: Member 'energy_switch_off' cannot be found");
-    PPK_ASSERT_ERROR((*_variant_options)["energy_switch_off"].IsNumber(), "Invalid options JSON object: Member 'energy_switch_off' must be a number");
-    Rational energy_switch_off = (*_variant_options)["energy_switch_off"].GetDouble();
-    PPK_ASSERT_ERROR(energy_switch_off > 0, "Invalid options JSON object: Member 'energy_switch_off' value must be strictly positive (got %g)", (double)energy_switch_off);
-
-
-    Rational ensured_sleep_time_lower_bound = 0;
-    if (_variant_options->HasMember("ensured_sleep_time_lower_bound"))
-    {
-        PPK_ASSERT_ERROR((*_variant_options)["ensured_sleep_time_lower_bound"].IsNumber(),
-                "Invalid options JSON object: Member 'ensured_sleep_time_lower_bound' is not a number");
-        ensured_sleep_time_lower_bound = (*_variant_options)["ensured_sleep_time_lower_bound"].GetDouble();
-        PPK_ASSERT_ERROR(ensured_sleep_time_lower_bound >= 0,
-                         "Invalid options JSON object: Member 'ensured_sleep_time_lower_bound' must "
-                         "be positive (got %g)", (double) ensured_sleep_time_lower_bound);
-    }
-
-    Rational ensured_sleep_time_upper_bound = 1e8;
-    if (_variant_options->HasMember("ensured_sleep_time_upper_bound"))
-    {
-        PPK_ASSERT_ERROR((*_variant_options)["ensured_sleep_time_upper_bound"].IsNumber(),
-                "Invalid options JSON object: Member 'ensured_sleep_time_upper_bound' is not a number");
-        ensured_sleep_time_upper_bound = (*_variant_options)["ensured_sleep_time_upper_bound"].GetDouble();
-        PPK_ASSERT_ERROR(ensured_sleep_time_upper_bound >= 0,
-                         "Invalid options JSON object: Member 'ensured_sleep_time_upper_bound' must "
-                         "be positive (got %g)", (double) ensured_sleep_time_upper_bound);
-    }
-
-    PPK_ASSERT_ERROR(ensured_sleep_time_lower_bound <= ensured_sleep_time_upper_bound,
-                     "Invalid options JSON object: ensured_sleep_time_lower_bound (%g) must be "
-                     "lower than or equal to ensured_sleep_time_upper_bound (%g), which is not "
-                     "the case here.", (double) ensured_sleep_time_lower_bound,
-                     (double) ensured_sleep_time_upper_bound);
-
-    for (int i = 0; i < nb_machines; ++i)
-    {
-        MachineInformation * minfo = new MachineInformation(i);
-
-        minfo->compute_pstate = pstate_compute;
-        minfo->sleep_pstate = pstate_sleep;
-        minfo->compute_epower = power_compute;
-        minfo->idle_epower = power_idle;
-        minfo->sleep_epower = power_sleep;
-        minfo->switch_on_energy = energy_switch_on;
-        minfo->switch_off_energy = energy_switch_off;
-        minfo->switch_on_seconds = time_switch_on;
-        minfo->switch_off_seconds = time_switch_off;
-        minfo->switch_on_electrical_power = energy_switch_on / time_switch_on;
-        minfo->switch_off_electrical_power = energy_switch_off / time_switch_off;
-
-        minfo->create_jobs(_rjms_delay, ensured_sleep_time_lower_bound,
-                           ensured_sleep_time_upper_bound);
-
-        _machine_informations[minfo->machine_number] = minfo;
-    }
-
-    LOG_F(INFO, "Ensured sleep length of the first machine : %g seconds.",
-           (double) _machine_informations[0]->ensured_sleep_job->walltime);
-}
-
-void EnergyBackfilling::clear_machine_informations()
-{
-    for (auto mit : _machine_informations)
-    {
-        MachineInformation * minfo = mit.second;
-        delete minfo;
-    }
-
-    _machine_informations.clear();
-}
-
-void EnergyBackfilling::make_decisions(double date,
-                                       SortableJobOrder::UpdateInformation * update_info,
-                                       SortableJobOrder::CompareInformation * compare_info)
-{
-    // Let's remove finished jobs from the schedule
-    for (const string & ended_job_id : _jobs_ended_recently)
-    {
-        const Job * ended_job = (*_workload)[ended_job_id];
-        ++_nb_jobs_completed;
-
-        PPK_ASSERT_ERROR(_schedule.contains_job(ended_job),
-                         "Invalid schedule: job '%s' just finished, "
-                         "but it not in the schedule...\n%s",
-                         ended_job_id.c_str(), _schedule.to_string().c_str());
-        PPK_ASSERT_ERROR(!_queue->contains_job(ended_job),
-                         "Job '%s' just ended, but it is still in the "
-                         "queue...\nQueue : %s",
-                         ended_job_id.c_str(),
-                         _queue->to_string().c_str());
-
-        // Let's remove the finished job from the schedule
-        _schedule.remove_job(ended_job);
-    }
-
-    // Let's handle recently released jobs
-    for (const string & new_job_id : _jobs_released_recently)
-    {
-        const Job * new_job = (*_workload)[new_job_id];
-        ++_nb_jobs_submitted;
-
-        PPK_ASSERT_ERROR(!_schedule.contains_job(new_job),
-                         "Invalid schedule: job '%s' already exists.\n%s",
-                         new_job->id.c_str(), _schedule.to_string().c_str());
-        PPK_ASSERT_ERROR(!_queue->contains_job(new_job),
-                         "Job '%s' is already in the queue!\nQueue:%s",
-                         new_job->id.c_str(), _queue->to_string().c_str());
-
-        if (new_job->nb_requested_resources > _nb_machines)
-        {
-            _decision->add_reject_job(new_job_id, date);
-            ++_nb_jobs_completed;
-        }
-        else
-            _queue->append_job(new_job, update_info);
-    }
-
-    // Let's update the first slice of the schedule
-    update_first_slice_taking_sleep_jobs_into_account(date);
-
-    // Let's update the sorting of the queue
-    _queue->sort_queue(update_info, compare_info);
-
-    Schedule current_schedule = _schedule;
-
-    if (_debug)
-    {
-        LOG_F(1, "Schedule before put_jobs_into_schedule: %s", current_schedule.to_string().c_str());
-    }
-
-    put_jobs_into_schedule(current_schedule);
-
-    if (_debug)
-    {
-        LOG_F(1, "Schedule before sedate_machines_at_the_furthest_moment: %s", current_schedule.to_string().c_str());
-    }
-
-    sedate_machines_at_the_furthest_moment(current_schedule, _awake_machines);
-
-    make_decisions_of_schedule(current_schedule);
-}
-
-void EnergyBackfilling::make_decisions_of_schedule(const Schedule &schedule,
-                                                   bool run_call_me_later_on_nothing_to_do)
-{
-    bool did_something = false;
-
-    PPK_ASSERT_ERROR(schedule.nb_slices() > 0);
-    const Schedule::TimeSlice & slice = *schedule.begin();
-    PPK_ASSERT_ERROR(slice.begin == _schedule.first_slice_begin());
-
-    map<int, IntervalSet> state_switches_to_do;
-
-    for (auto mit : slice.allocated_jobs)
-    {
-        const Job * job = mit.first;
-        const IntervalSet & job_machines = mit.second;
-
-        // If the job is a fake one
-        if (is_fake_job(job->id))
-        {
-            PPK_ASSERT_ERROR(job_machines.size() == 1);
-            MachineInformation * machine_info = _machine_informations.at(job_machines.first_element());
-            int machine_id = machine_info->machine_number;
-
-            if (is_switch_on_job(job->id))
-            {
-                // If the switch ON is new
-                if (!_schedule.contains_job(job))
-                {
-                    // Let's remove the sleep jobs from the online schedule
-                    bool ensured_removed = _schedule.remove_job_if_exists(machine_info->ensured_sleep_job);
-                    bool potential_removed = _schedule.remove_job_if_exists(machine_info->potential_sleep_job);
-                    PPK_ASSERT_ERROR(ensured_removed || potential_removed);
-
-                    // Let's insert the switch ON into the online schedule
-                    Schedule::JobAlloc alloc = _schedule.add_job_first_fit(job, machine_info->limited_resource_selector);
-                    PPK_ASSERT_ERROR(alloc.begin == slice.begin);
-
-                    // Let's register that this machine should be switched ON now
-                    state_switches_to_do[machine_info->compute_pstate].insert(machine_info->machine_number);
-
-                    // Let's update machine states
-                    PPK_ASSERT_ERROR(_asleep_machines.contains(machine_id));
-                    _asleep_machines.remove(machine_id);
-
-                    PPK_ASSERT_ERROR(_wakable_asleep_machines.contains(machine_id));
-                    _wakable_asleep_machines.remove(machine_id);
-
-                    PPK_ASSERT_ERROR(!_switching_on_machines.contains(machine_id));
-                    _switching_on_machines.insert(machine_info->machine_number);
-                }
-            }
-            else if (is_switch_off_job(job->id))
-            {
-                // If the switch OFF is new
-                if (!_schedule.contains_job(job))
-                {
-                    // Let's sedate the machine into the online schedule
-                    sedate_machine(_schedule, machine_info->machine_number, _schedule.begin());
-
-                    // Let's register that this machine should be switched OFF now
-                    state_switches_to_do[machine_info->sleep_pstate].insert(machine_info->machine_number);
-
-                    // Let's update machine states
-                    PPK_ASSERT_ERROR(_awake_machines.contains(machine_id));
-                    _awake_machines.remove(machine_id);
-
-                    PPK_ASSERT_ERROR(!_switching_off_machines.contains(machine_id));
-                    _switching_off_machines.insert(machine_info->machine_number);
-                }
-            }
-        }
-        else // The job is a real one
-        {
-            // If the job is a new one
-            if (_queue->contains_job(job))
-            {
-                // Let's append it to the online schedule
-                LimitedRangeResourceSelector selector(job_machines);
-                Schedule::JobAlloc alloc = _schedule.add_job_first_fit(job, &selector);
-                PPK_ASSERT_ERROR(alloc.started_in_first_slice);
-                PPK_ASSERT_ERROR(alloc.begin == slice.begin);
-
-                // Let's tell the RJMS this job should be executed now
-                _decision->add_execute_job(job->id, job_machines, (double)alloc.begin);
-                did_something = true;
-
-                // Let's remove it from the queue
-                _queue->remove_job(job);
-            }
-        }
-    }
-
-    // Let's make state switch decisions now
-    for (auto mit : state_switches_to_do)
-    {
-        int target_pstate = mit.first;
-        const IntervalSet & machines = mit.second;
-
-        _decision->add_set_resource_state(machines, target_pstate, (double) slice.begin);
-        did_something = true;
-    }
-
-    if (run_call_me_later_on_nothing_to_do)
-    {
-        if (!did_something && (_nb_jobs_completed < _workload->nb_jobs()) && (_nb_call_me_later_running == 0))
-        {
-            // To avoid Batsim's deadlock, we should tell it to wait that we are ready.
-
-            PPK_ASSERT_ERROR(_schedule.nb_slices() >= 1);
-            _decision->add_call_me_later((double) _schedule.begin()->end + 1, (double) _schedule.begin()->begin);
-            _nb_call_me_later_running++;
-        }
-    }
-}
-
-void EnergyBackfilling::update_first_slice_taking_sleep_jobs_into_account(Rational date)
-{
-    PPK_ASSERT_ERROR(_schedule.nb_slices() > 0);
-
-    if (_debug)
-        LOG_F(1, "update_first_slice... Date=%f\n%s",
-               (double) date, _schedule.to_string().c_str());
-
-    // Since we are not only using "real" jobs, the usual assumption that a slice cannot
-    // end prematurely (because of walltimes being greater than execution times) does not stand.
-
-    // We are sure that "Switch ON" and "Switch OFF" jobs behave the same that usual walltime jobs.
-    // However this is not the case for the two sleeping jobs (ensured and potential).
-
-    // Ensured sleeping jobs are used to ensure that a machine is not awaken too soon, which
-    // would cause a pure loss of energy (w.r.t. letting the machine idle). Hence, those jobs
-    // only exists in the scheduler view and Batsim won't tell when these jobs are finished.
-    // Thus, finition of those jobs must be detected by the scheduler.
-
-    // Potential sleeping jobs are used to make sure an asleep machine is not used for
-    // computing jobs. These jobs have an infinite length and their termination should
-    // not be a problem.
-
-
-    // Hence, the update is valid if:
-    //  - No slice ended prematurely
-    //  - If slices ended prematurely, they were only related to ensured->potential sleep jobs.
-
-    auto slice_it = _schedule.begin();
-    bool slices_have_been_ended = false;
-
-    // Complex tests will only be done if some slices ended prematurely
-    if (date >= slice_it->end)
-    {
-        slices_have_been_ended = true;
-
-        // Let's make sure all jobs but ensured-sleep related ones remain in the same
-        // state in the scheduling, from the first slice to the current date
-        IntervalSet sleeping_machines;
-        set<string> non_sleep_jobs;
-
-        const Schedule::TimeSlice & first_slice = *slice_it;
-        for (const auto & mit : first_slice.allocated_jobs)
-        {
-            const Job * job = mit.first;
-            if (!is_ensured_sleep_job(job->id) && !is_potential_sleep_job(job->id))
-                non_sleep_jobs.insert(job->id);
-            else
-                sleeping_machines.insert(mit.second);
-        }
-
-        while (slice_it->end <= date)
-        {
-            set<string> non_sleep_jobs_in_slice;
-            IntervalSet sleeping_machines_in_slice;
-            const Schedule::TimeSlice & slice = *slice_it;
-
-            // Let's check that aside from ensured sleep jobs, the jobs
-            // are the same in the involved slices (those ended + the merge slice)
-            for (const auto & mit : slice.allocated_jobs)
-            {
-                const Job * job = mit.first;
-                if (!is_ensured_sleep_job(job->id) && !is_potential_sleep_job(job->id))
-                {
-                    PPK_ASSERT_ERROR(non_sleep_jobs.find(job->id) != non_sleep_jobs.end(),
-                                     "A time slice ended prematurely, which is only "
-                                     "allowed if the ended slices only exist because of "
-                                     "ensured sleep jobs, which is not the case here, "
-                                     "since job '%s' is not in all involved slices. Date=%g. %s",
-                                     job->id.c_str(),
-                                     (double) date,
-                                     _schedule.to_string().c_str());
-                    non_sleep_jobs_in_slice.insert(job->id);
-                }
-                else
-                    sleeping_machines_in_slice.insert(mit.second);
-
-            }
-
-            PPK_ASSERT_ERROR(non_sleep_jobs_in_slice == non_sleep_jobs,
-                             "A time slice ended prematurely, which is only allowed "
-                             "if the ended slices only exist because of ensured->potential "
-                             "sleep jobs, which is not the case here, because other jobs "
-                             "appeared/vanished in slice '%s'. Date=%g.\n"
-                             "Non sleep jobs in first slice: %s\n"
-                             "Non sleep jobs in current slice: %s\n%s",
-                             slice.to_string().c_str(),
-                             (double) date,
-                             boost::algorithm::join(non_sleep_jobs, ",").c_str(),
-                             boost::algorithm::join(non_sleep_jobs_in_slice, ",").c_str(),
-                             _schedule.to_string().c_str());
-
-            PPK_ASSERT_ERROR(sleeping_machines_in_slice == sleeping_machines,
-                             "A time slice ended prematurely, which is only allowed "
-                             "if the ended slices only exist because of ensured->potential "
-                             "sleep jobs, which is not the case here, since the sleeping "
-                             "machines are not the same in the first slice (%s) and in"
-                             "the current one (%s).",
-                             sleeping_machines.to_string_brackets().c_str(),
-                             sleeping_machines_in_slice.to_string_brackets().c_str());
-
-            if (_debug)
-            {
-                LOG_F(1, "The slice will be removed because everything seems fine.\n"
-                       "sleeping_machines = %s\nnon_sleep_jobs=%s\n%s",
-                       sleeping_machines.to_string_brackets().c_str(),
-                       boost::algorithm::join(non_sleep_jobs, ",").c_str(),
-                       slice.to_string().c_str());
-            }
-
-            ++slice_it;
-        }
-    }
-
-    // The schedule seems to be fine.
-    _schedule.update_first_slice_removing_remaining_jobs(date);
-
-    if (slices_have_been_ended)
-    {
-        // Let's update whether machines are wakable.
-        slice_it = _schedule.begin();
-
-        IntervalSet wakable_machines_now, non_wakable_machines_now;
-
-        for (const auto mit : slice_it->allocated_jobs)
-        {
-            const Job * job = mit.first;
-            const IntervalSet & alloc = mit.second;
-            if (is_ensured_sleep_job(job->id))
-                non_wakable_machines_now.insert(alloc);
-            else if (is_potential_sleep_job(job->id))
-                wakable_machines_now.insert(alloc);
-        }
-
-        // Let's make sure these machines are valid.
-        PPK_ASSERT_ERROR((wakable_machines_now & non_wakable_machines_now) == IntervalSet::empty_interval_set(),
-                         "Invalid schedule update: the new wakable and non-wakable machines are not"
-                         "distinct. New wakable: %s. New non wakable: %s.",
-                         wakable_machines_now.to_string_brackets().c_str(),
-                         non_wakable_machines_now.to_string_brackets().c_str());
-        PPK_ASSERT_ERROR((wakable_machines_now + non_wakable_machines_now) == _asleep_machines,
-                         "Invalid schedule update: the asleep machines have changed. "
-                         "Asleep machines before: %s. Asleep machines now: %s.",
-                         _asleep_machines.to_string_brackets().c_str(),
-                         (wakable_machines_now + non_wakable_machines_now).to_string_brackets().c_str());
-
-        _wakable_asleep_machines = wakable_machines_now;
-        _non_wakable_asleep_machines = non_wakable_machines_now;
-    }
-
-}
-
-void EnergyBackfilling::put_jobs_into_schedule(Schedule &schedule) const
-{
-    Rational initial_infinite_horizon = schedule.infinite_horizon();
-
-    for (auto job_it = _queue->begin(); job_it != _queue->end(); ++job_it)
-    {
-        const Job * job = (*job_it)->job;
-
-        // Let's try to put the job into the schedule at the first available slot.
-        Schedule::JobAlloc alloc = schedule.add_job_first_fit(job, _selector, false);
-
-        // Because of sleeping machines, the allocation might be impossible.
-        // If this happens, some machines must be awaken
-        if (!alloc.has_been_inserted)
-        {
-            // The nodes we will try to switch ON are the ones in a potential sleep state between
-            // the finite horizon and the infinite one. Let's find which ones should be awakened.
-            auto slice_it = schedule.end();
-            --slice_it;
-            const Schedule::TimeSlice & last_slice = *slice_it;
-
-            // Let's compute which machines can be awakened in the last slice
-            IntervalSet machines_that_can_be_awakened = compute_potentially_awaken_machines(last_slice);
-
-            // Let's find which machines to awaken
-            IntervalSet machines_to_awaken;
-            _selector->select_resources_to_awaken_to_make_job_fit(job, last_slice.available_machines, machines_that_can_be_awakened, machines_to_awaken);
-            PPK_ASSERT_ERROR(machines_to_awaken.size() > 0);
-
-            // Let's find the first moment in time (the earliest) when all the machines to awaken can be awakened
-            Rational earliest_awakening_time = find_earliest_moment_to_awaken_machines(schedule, machines_to_awaken);
-
-            // Let's modify the future schedule of the machines which should be used for computing the job
-            //   1. Let's reduce the length (or remove) the potential sleep jobs they have
-            //   2. Let's insert a wake up job for each sleeping machine
-            for (auto machine_it = machines_to_awaken.elements_begin(); machine_it != machines_to_awaken.elements_end(); ++machine_it)
-            {
-                int machine_id = *machine_it;
-                awaken_machine(schedule, machine_id, earliest_awakening_time);
-            }
-
-            if (_debug)
-            {
-                LOG_F(1, "schedule before job insertion: %s", schedule.to_string().c_str());
-                LOG_F(1, "job : (id='%s', walltime=%g)", job->id.c_str(), (double) job->walltime);
-            }
-
-            // Let's finally insert the job
-            auto job_alloc = schedule.add_job_first_fit_after_time(job, earliest_awakening_time, _selector);
-
-            if (_debug)
-            {
-                LOG_F(1, "schedule after job insertion: %s", schedule.to_string().c_str());
-            }
-
-            // Let's make sure the machine awakening was not useless
-            PPK_ASSERT_ERROR((job_alloc.used_machines & machines_to_awaken) != IntervalSet::empty_interval_set());
-
-            // Let's make sure the infinite horizon has not been changed
-            PPK_ASSERT_ERROR(initial_infinite_horizon == schedule.infinite_horizon());
-        }
-    }
-}
-
-Rational EnergyBackfilling::sedate_machines_at_the_furthest_moment(Schedule &schedule, const IntervalSet &machines_to_sedate) const
-{
-    PPK_ASSERT_ERROR(schedule.nb_slices() >= 1);
-
-    auto time_slice_it = schedule.end();
-    --time_slice_it;
-
-    PPK_ASSERT_ERROR(time_slice_it->end == schedule.infinite_horizon());
-    PPK_ASSERT_ERROR(time_slice_it->begin == schedule.finite_horizon());
-
-    Rational earliest_sedating_date = schedule.infinite_horizon();
-
-    // Let's store awaken_machines into one variable
-    IntervalSet awaken_machines = time_slice_it->available_machines; // Since sleep jobs targets the infinite horizon, the sleeping machines are not available in the last time slice
-
-    while ((machines_to_sedate & awaken_machines) != IntervalSet::empty_interval_set())
-    {
-        if (time_slice_it != schedule.begin())
-            --time_slice_it;
-
-        // Let's find which machines which should be sedated just after the current time slice.
-        // Since time slices are traversed from future to past, we know that if a machine is still awaken,
-        // it does nothing in the future. Then, if a machine in the awaken_machines set does something in the
-        // current time slice, it should be sedated at the end of the time slice currently being traversed.
-        IntervalSet machines_to_sedate_now;
-
-        if (_debug)
-        {
-            LOG_F(1, "Schedule : %s", schedule.to_string().c_str());
-            LOG_F(1, "Current time slice : %s", time_slice_it->to_string().c_str());
-        }
-
-
-        for (auto mit : time_slice_it->allocated_jobs)
-        {
-            const Job * job = mit.first;
-            const IntervalSet & job_machines = mit.second;
-
-            // If the job is a fake one
-            if (is_fake_job(job->id))
-            {
-                PPK_ASSERT_ERROR(job_machines.size() == 1);
-
-                int machine_id = job_machines.first_element();
-                boost::regex e("fakejob_(.*)_(\\d+)");
-
-                boost::match_results<std::string::const_iterator> results;
-                bool matched = boost::regex_match(job->id, results, e);
-                PPK_ASSERT_ERROR(matched);
-
-                int machine_id_from_job_id = stoi(results[2]);
-                PPK_ASSERT_ERROR(machine_id == machine_id_from_job_id);
-
-                // If the fake job is a switch ON one
-                if (results[1] == "son")
-                    machines_to_sedate_now.insert(machine_id);
-            }
-            else
-                machines_to_sedate_now.insert(job_machines);
-        }
-
-        // Only machines that are awaken should be sedated now
-        machines_to_sedate_now &= awaken_machines;
-
-        // Only machines that need to be sedated should be sedated now
-        machines_to_sedate_now &= machines_to_sedate;
-
-        // Let's sedate all the machines that must be
-        for (auto machine_it = machines_to_sedate_now.elements_begin(); machine_it != machines_to_sedate_now.elements_end(); ++machine_it)
-        {
-            int machine_id = *machine_it;
-            sedate_machine(schedule, machine_id, time_slice_it, false);
-            earliest_sedating_date = time_slice_it->end;
-            // Fortunately, inserting after the current time slice can only change the iterators after (-> future) the current iterator,
-            // not the ones before (-> past), which makes the traversal work
-        }
-
-        // Let's mark machines that will be sedated as not awaken
-        awaken_machines -= machines_to_sedate_now;
-
-        if (time_slice_it == schedule.begin())
-        {
-            // If we reached the schedule's beginning, all awaken machines that should be sedated should be put into sleep now.
-            machines_to_sedate_now = awaken_machines & machines_to_sedate;
-
-            for (auto machine_it = machines_to_sedate_now.elements_begin(); machine_it != machines_to_sedate_now.elements_end(); ++machine_it)
-            {
-                int machine_id = *machine_it;
-                sedate_machine(schedule, machine_id, time_slice_it, true);
-                earliest_sedating_date = time_slice_it->begin;
-                // In this case, the sleep jobs should be inserted into the given time slice, not just after it
-            }
-
-            awaken_machines -= machines_to_sedate_now;
-
-            PPK_ASSERT_ERROR((awaken_machines & machines_to_sedate) == IntervalSet::empty_interval_set());
-        }
-    }
-
-    return earliest_sedating_date;
-}
-
-void EnergyBackfilling::sedate_machine(Schedule &schedule,
-                                       int machine_id,
-                                       std::list<Schedule::TimeSlice>::iterator time_slice,
-                                       bool insert_in_slice) const
-{
-    // Let's retrieve the MachineInformation
-    MachineInformation * minfo = _machine_informations.at(machine_id);
-
-    if (_debug)
-    {
-        LOG_F(1, "\n-----\n");
-        LOG_F(1, "Machine to sedate: %d", machine_id);
-        LOG_F(1, "Schedule before switch_off_alloc : %s", schedule.to_string().c_str());
-    }
-
-    // Let's add the switch OFF job into the schedule
-    Schedule::JobAlloc switch_off_alloc = schedule.add_job_first_fit_after_time_slice(minfo->switch_off_job, time_slice, minfo->limited_resource_selector);
-
-    if (_debug)
-    {
-        LOG_F(1, "Schedule after switch_off_alloc : %s", schedule.to_string().c_str());
-    }
-
-    if (insert_in_slice)
-        PPK_ASSERT_ERROR(switch_off_alloc.begin == time_slice->begin,
-                         "switch_off_alloc.begin = %g, time_slice->begin = %g,",
-                         (double) switch_off_alloc.begin, (double) time_slice->begin);
-    else
-        PPK_ASSERT_ERROR(switch_off_alloc.begin == time_slice->end,
-                         "switch_off_alloc.begin = %g, time_slice->end = %g,",
-                         (double) switch_off_alloc.begin, (double) time_slice->end);
-
-    sedate_machine_without_switch(schedule, machine_id, switch_off_alloc.end);
-}
-
-void EnergyBackfilling::sedate_machine_without_switch(Schedule &schedule,
-                                                      int machine_id,
-                                                      Rational when_it_should_start) const
-{
-    // Let's retrieve the MachineInformation
-    MachineInformation * minfo = _machine_informations.at(machine_id);
-
-    Rational when_ensured_sleep_job_finishes = when_it_should_start;
-
-    if (minfo->ensured_sleep_job->walltime > 0)
-    {
-        // Let's add the ensured sleep job into the schedule, right after the previous one
-        Schedule::JobAlloc ensured_sleep_alloc = schedule.add_job_first_fit_after_time(minfo->ensured_sleep_job, when_it_should_start, minfo->limited_resource_selector);
-
-        if (_debug)
-        {
-            LOG_F(1, "Schedule after ensured_sleep_alloc : %s", schedule.to_string().c_str());
-        }
-
-        PPK_ASSERT_ERROR(ensured_sleep_alloc.begin == when_it_should_start,
-                         "ensured_sleep_alloc.begin = %g, when_it_should_start = %g",
-                         (double) ensured_sleep_alloc.begin, (double) when_it_should_start);
-
-        when_ensured_sleep_job_finishes = ensured_sleep_alloc.end;
-    }
-
-    // Let's change the walltime of the potential sleep job to make sure it perfectly reaches the infinite horizon
-    minfo->potential_sleep_job->walltime = schedule.infinite_horizon() - when_ensured_sleep_job_finishes;
-    Rational infinite_horizon_before = schedule.infinite_horizon();
-
-    // Let's add the potential sleep job into the schedule, right after the previous one
-    Schedule::JobAlloc potential_sleep_alloc = schedule.add_job_first_fit_after_time(minfo->potential_sleep_job, when_it_should_start, minfo->limited_resource_selector);
-
-    if (_debug)
-    {
-        LOG_F(1, "Schedule after potential_sleep_alloc : %s", schedule.to_string().c_str());
-    }
-
-    PPK_ASSERT_ERROR(potential_sleep_alloc.begin == when_ensured_sleep_job_finishes);
-    PPK_ASSERT_ERROR(potential_sleep_alloc.end == schedule.infinite_horizon());
-    PPK_ASSERT_ERROR(schedule.infinite_horizon() == infinite_horizon_before);
-}
-
-void EnergyBackfilling::awaken_machine(Schedule &schedule, int machine_id, Rational awakening_date) const
-{
-    MachineInformation * machine_info = _machine_informations.at(machine_id);
-
-    // Let's find when the potential sleep job starts
-    auto potential_job_beginning_slice = schedule.find_last_occurence_of_job(machine_info->potential_sleep_job, schedule.begin());
-    Rational previously_potential_job_beginning_time = potential_job_beginning_slice->begin;
-
-    // Let's remove the previous potential sleep job from the schedule
-    schedule.remove_job_last_occurence(machine_info->potential_sleep_job);
-
-    // If the machine can still have a potential sleep job (of reduced length), one is added into the schedule
-    Rational potential_sleep_maximum_length = awakening_date - previously_potential_job_beginning_time;
-    PPK_ASSERT_ERROR(potential_sleep_maximum_length >= 0);
-
-    if (_debug)
-    {
-        LOG_F(1, "EnergyBackfilling::awaken_machine.\n"
-               "potential_sleep_maximum_length = %f\n%s",
-               (double) potential_sleep_maximum_length,
-               schedule.to_string().c_str());
-    }
-
-    if (potential_sleep_maximum_length > 0)
-    {
-        Job * job = machine_info->potential_sleep_job;
-        job->walltime = potential_sleep_maximum_length;
-        auto potential_sleep_alloc = schedule.add_job_first_fit_after_time(job, previously_potential_job_beginning_time, machine_info->limited_resource_selector);
-        PPK_ASSERT_ERROR(potential_sleep_alloc.begin == previously_potential_job_beginning_time);
-
-        if (_debug)
-        {
-            LOG_F(1, "EnergyBackfilling::awaken_machine.\n"
-                   "The potential job has been inserted back into the schedule.\n%s",
-                   schedule.to_string().c_str());
-        }
-    }
-
-    // Let's wake the machine up
-    auto wake_up_alloc = schedule.add_job_first_fit_after_time(machine_info->switch_on_job, previously_potential_job_beginning_time, machine_info->limited_resource_selector);
-    PPK_ASSERT_ERROR(wake_up_alloc.begin == awakening_date);
-
-    if (_debug)
-    {
-        LOG_F(1, "EnergyBackfilling::awaken_machine after wake up\n%s",
-               schedule.to_string().c_str());
-    }
-}
-
-Rational EnergyBackfilling::awaken_machine_as_soon_as_possible(Schedule &schedule, int machine_id) const
-{
-    MachineInformation * machine_info = _machine_informations.at(machine_id);
-
-    // Let's find when the potential sleep job starts
-    auto potential_job_beginning_slice = schedule.find_last_occurence_of_job(machine_info->potential_sleep_job, schedule.begin());
-    PPK_ASSERT_ERROR(potential_job_beginning_slice != schedule.end(),
-                     "Cannot awaken machine %d: The machine is not sleeping\n", machine_id);
-
-    Rational insertion_time = potential_job_beginning_slice->begin;
-
-    awaken_machine(schedule, machine_id, insertion_time);
-    return insertion_time;
-}
-
-EnergyBackfilling::ScheduleMetrics EnergyBackfilling::compute_metrics_of_schedule(const Schedule &schedule, Rational min_job_length) const
-{
-    PPK_ASSERT_ERROR(schedule.nb_slices() > 0);
-    ScheduleMetrics ret;
-
-    ret.makespan = schedule.finite_horizon();
-
-    struct JobInfo
-    {
-        bool traversed_left = false;
-        bool traversed_right = false;
-
-        Rational submission_time;
-        Rational starting_time;
-        Rational ending_time;
-
-        Rational waiting_time;
-        Rational turnaround_time;
-        Rational slowdown;
-        Rational bounded_slowdown;
-    };
-
-    map<string, JobInfo> jobs_info;
-
-    // Past -> Future traversal to find starting times
-    for (auto time_slice_it = schedule.begin(); time_slice_it != schedule.end(); ++time_slice_it)
-    {
-        const Schedule::TimeSlice & slice = *time_slice_it;
-
-        for (auto mit : slice.allocated_jobs)
-        {
-            const Job * job = mit.first;
-
-            if (!is_fake_job(job->id))
-            {
-                if (jobs_info.count(job->id) == 0)
-                    jobs_info[job->id] = JobInfo();
-
-                JobInfo & info = jobs_info[job->id];
-
-                // If the job has not been taken into account
-                if (!info.traversed_right)
-                {
-                    info.submission_time = job->submission_time;
-                    info.starting_time = slice.begin;
-
-                    info.traversed_right = true;
-                }
-            }
-        }
-    }
-
-    // Future -> Past traversal to find expected ending times
-    bool should_continue_traversal = true;
-    auto last_slice = schedule.end();
-    --last_slice;
-    for (auto time_slice_it = last_slice; should_continue_traversal; --time_slice_it)
-    {
-        const Schedule::TimeSlice & slice = *time_slice_it;
-
-        for (auto mit : slice.allocated_jobs)
-        {
-            const Job * job = mit.first;
-
-            if (! is_fake_job(job->id))
-            {
-                JobInfo & info = jobs_info[job->id];
-
-                // If the job has not been taken into account
-                if (!info.traversed_left)
-                {
-                    info.ending_time = slice.end;
-
-                    // Now that both starting and end times are known, metrics can be computed
-                    info.waiting_time = info.starting_time - info.submission_time;
-                    info.turnaround_time = info.ending_time - info.submission_time;
-                    info.slowdown = info.turnaround_time / (info.ending_time - info.starting_time);
-                    info.bounded_slowdown = info.turnaround_time / std::max(min_job_length, Rational(info.ending_time - info.starting_time));
-
-                    // Let's compute the sum of the metrics there
-                    ret.mean_waiting_time += info.waiting_time;
-                    ret.mean_turnaround_time += info.turnaround_time;
-                    ret.mean_slowdown += info.slowdown;
-                    ret.mean_bounded_slowdown += info.bounded_slowdown;
-
-                    // The same with the max of each metrics
-                    ret.max_waiting_time = std::max(ret.max_waiting_time, info.waiting_time);
-                    ret.max_turnaround_time = std::max(ret.max_turnaround_time, info.turnaround_time);
-                    ret.max_slowdown = std::max(ret.max_slowdown, info.slowdown);
-                    ret.max_bounded_slowdown = std::max(ret.max_bounded_slowdown, info.bounded_slowdown);
-
-                    info.traversed_left = true;
-                }
-            }
-        }
-
-        if (time_slice_it == schedule.begin())
-            should_continue_traversal = false;
-    }
-
-    // Let's divide the sum of each metrics by the number of jobs to get the mean
-    if (jobs_info.size() > 0)
-    {
-        ret.mean_waiting_time /= jobs_info.size();
-        ret.mean_turnaround_time /= jobs_info.size();
-        ret.mean_slowdown /= jobs_info.size();
-        ret.mean_bounded_slowdown /= jobs_info.size();
-    }
-
-    return ret;
-}
-
-IntervalSet EnergyBackfilling::compute_potentially_awaken_machines(const Schedule::TimeSlice &time_slice)
-{
-    // Computes the machines that can be awaken in one time slice.
-    // These machines are the one on which potential sleep jobs are allocated
-
-    IntervalSet res;
-
-    for (auto mit : time_slice.allocated_jobs)
-    {
-        const Job * job = mit.first;
-        const IntervalSet & job_machines = mit.second;
-
-        if (is_potential_sleep_job(job->id))
-            res.insert(job_machines);
-    }
-
-    return res;
-}
-
-IntervalSet EnergyBackfilling::compute_sleeping_machines(const Schedule::TimeSlice &time_slice)
-{
-    // Computes the machines that are sleeping in one time slice:
-    //   - those in ensured sleep
-    //   - those in potential sleep
-
-    IntervalSet res;
-
-    for (auto mit : time_slice.allocated_jobs)
-    {
-        const Job * job = mit.first;
-        const IntervalSet & job_machines = mit.second;
-
-        if (is_potential_sleep_job(job->id) || is_ensured_sleep_job(job->id))
-            res.insert(job_machines);
-    }
-
-    return res;
-}
-
-Rational EnergyBackfilling::find_earliest_moment_to_awaken_machines(Schedule &schedule, const IntervalSet &machines_to_awaken) const
-{
-    // Let's traverse the schedule Future -> Past
-    // As soon as we find any machine to awaken not computing a potential sleep job,
-    // the moment of time we seek is found.
-    PPK_ASSERT_ERROR(schedule.nb_slices() > 0);
-
-    auto slice_it = schedule.end(); // Finite horizon -> Infinite horizon
-    --slice_it;
-
-    // Let's make sure this method is called correctly by checking that all machines are sleeping in the last time slice
-    IntervalSet sleeping_machines = compute_potentially_awaken_machines(*slice_it);
-    PPK_ASSERT_ERROR((sleeping_machines & machines_to_awaken) == machines_to_awaken);
-
-    do
-    {
-        if (slice_it != schedule.begin())
-            --slice_it;
-
-        sleeping_machines = compute_potentially_awaken_machines(*slice_it);
-
-        // If all the machines are not in a potential sleep yet
-        if ((sleeping_machines & machines_to_awaken) != machines_to_awaken)
-            return slice_it->end;
-
-    } while (slice_it != schedule.begin());
-
-    return schedule.first_slice_begin();
-}
-
-Rational EnergyBackfilling::estimate_energy_of_schedule(const Schedule &schedule, Rational horizon) const
-{
-    PPK_ASSERT_ERROR(horizon < schedule.infinite_horizon());
-    Rational energy = 0;
-
-    // Let's iterate the slices
-    for (auto slice_it = schedule.begin(); (slice_it->begin < horizon) && (slice_it != schedule.end()); ++slice_it)
-    {
-        const Schedule::TimeSlice & slice = *slice_it;
-
-        Rational length = slice.length;
-        if (slice_it->end > horizon)
-            length = horizon - slice_it->begin;
-
-        IntervalSet idle_machines = _all_machines;
-
-        for (auto mit : slice.allocated_jobs)
-        {
-            const Job * job = mit.first;
-            const IntervalSet & mr = mit.second;
-
-            idle_machines -= mr;
-            Rational job_power_in_slice = 0;
-
-            if (is_fake_job(job->id))
-            {
-                if (is_switch_on_job(job->id))
-                    for (auto machine_it = mr.elements_begin(); machine_it != mr.elements_end(); ++machine_it)
-                        job_power_in_slice += _machine_informations.at(*machine_it)->switch_on_electrical_power;
-                else if (is_switch_off_job(job->id))
-                    for (auto machine_it = mr.elements_begin(); machine_it != mr.elements_end(); ++machine_it)
-                        job_power_in_slice += _machine_informations.at(*machine_it)->switch_off_electrical_power;
-                else if (is_ensured_sleep_job(job->id))
-                    for (auto machine_it = mr.elements_begin(); machine_it != mr.elements_end(); ++machine_it)
-                        job_power_in_slice += _machine_informations.at(*machine_it)->sleep_epower;
-                else if (is_potential_sleep_job(job->id))
-                    for (auto machine_it = mr.elements_begin(); machine_it != mr.elements_end(); ++machine_it)
-                        job_power_in_slice += _machine_informations.at(*machine_it)->sleep_epower;
-                else
-                    PPK_ASSERT_ERROR(false);
-            }
-            else
-            {
-                for (auto machine_it = mr.elements_begin(); machine_it != mr.elements_end(); ++machine_it)
-                    job_power_in_slice += _machine_informations.at(*machine_it)->compute_epower;
-            }
-
-            energy += job_power_in_slice * length;
-        }
-
-        // Let's add the energy of idle machines
-        for (auto machine_it = idle_machines.elements_begin(); machine_it != idle_machines.elements_end(); ++ machine_it)
-        {
-            int machine_id = *machine_it;
-            MachineInformation * minfo = _machine_informations.at(machine_id);
-
-            energy += minfo->idle_epower * length;
-        }
-    }
-
-    return energy;
-}
-
-bool EnergyBackfilling::is_switch_on_job(const std::string & job_id)
-{
-    return boost::starts_with(job_id, "fakejob_son_");
-}
-
-bool EnergyBackfilling::is_switch_off_job(const std::string & job_id)
-{
-    return boost::starts_with(job_id, "fakejob_soff_");
-}
-
-bool EnergyBackfilling::is_ensured_sleep_job(const std::string & job_id)
-{
-    return boost::starts_with(job_id, "fakejob_esleep_");
-}
-
-bool EnergyBackfilling::is_potential_sleep_job(const std::string & job_id)
-{
-    return boost::starts_with(job_id, "fakejob_psleep_");
-}
-
-bool EnergyBackfilling::is_fake_job(const std::string & job_id)
-{
-    return boost::starts_with(job_id, "fakejob_");
-}
-
-bool EnergyBackfilling::contains_any_fake_job(const Schedule &schedule)
-{
-    for (auto slice_it = schedule.begin(); slice_it != schedule.end(); ++slice_it)
-    {
-        for (auto mit : slice_it->allocated_jobs)
-        {
-            const Job * job = mit.first;
-            if (is_fake_job(job->id))
-                return true;
-        }
-    }
-    return false;
-}
-
-bool EnergyBackfilling::contains_any_nonfake_job(const Schedule &schedule)
-{
-    for (auto slice_it = schedule.begin(); slice_it != schedule.end(); ++slice_it)
-    {
-        for (auto mit : slice_it->allocated_jobs)
-        {
-            const Job * job = mit.first;
-            if (!is_fake_job(job->id))
-                return true;
-        }
-    }
-    return false;
-}
diff --git a/src/algo/energy_bf.hpp b/src/algo/energy_bf.hpp
deleted file mode 100644
index cba51a36e7d5a13eb00f023f5d56b498f546d133..0000000000000000000000000000000000000000
--- a/src/algo/energy_bf.hpp
+++ /dev/null
@@ -1,180 +0,0 @@
-#pragma once
-
-#include <list>
-#include <map>
-
-#include "../isalgorithm.hpp"
-#include "../json_workload.hpp"
-#include "../locality.hpp"
-#include "../schedule.hpp"
-
-class EnergyBackfilling : public ISchedulingAlgorithm
-{
-public:
-    enum MachineState
-    {
-        AWAKE,
-        ASLEEP,
-        SWITCHING_OFF,
-        SWITCHING_ON
-    };
-
-    struct ScheduleMetrics
-    {
-        Rational makespan = 0;
-
-        Rational mean_waiting_time = 0;
-        Rational max_waiting_time = 0;
-
-        Rational mean_turnaround_time = 0;
-        Rational max_turnaround_time = 0;
-
-        Rational mean_slowdown = 0;
-        Rational max_slowdown = 0;
-
-        Rational mean_bounded_slowdown = 0;
-        Rational max_bounded_slowdown = 0;
-    };
-
-    std::string machine_state_to_string(const MachineState & state);
-
-    struct MachineInformation
-    {
-        MachineInformation(int machine_number);
-        ~MachineInformation();
-
-        void create_jobs(double rjms_delay,
-                         Rational ensured_sleep_time_lower_bound,
-                         Rational ensured_sleep_time_upper_bound);
-        void free_jobs();
-
-    private:
-        void create_selector();
-        void free_selector();
-
-    public:
-        int machine_number = -1; //! The machine number the MachineInformation corresponds to
-        LimitedRangeResourceSelector * limited_resource_selector = nullptr;
-        MachineState state = AWAKE;
-
-        int compute_pstate = 0;
-        int sleep_pstate = 1;
-
-        Rational compute_epower = 0;
-        Rational idle_epower = 0;
-        Rational sleep_epower = 0;
-
-        Rational switch_on_seconds = 0;
-        Rational switch_on_energy = 0;
-        Rational switch_on_electrical_power = 0;
-
-        Rational switch_off_seconds = 0;
-        Rational switch_off_energy = 0;
-        Rational switch_off_electrical_power = 0;
-
-        Job * switch_on_job = nullptr; //! This job corresponds to the switching ON state of the machine
-        Job * switch_off_job = nullptr; //! This job corresponds to the switching OFF state of the machine
-
-        Job * ensured_sleep_job = nullptr; //! This job corresponds to the sleeping state of the machine. It cannot be stopped. It is used to avoid pure loss of energy via too frequent switches OFF and ON
-        Job * potential_sleep_job = nullptr; //! This job corresponds to the sleeping state of the machine. It can be stopped if a job cannot fit in the schedule otherwise
-    };
-
-public:
-    EnergyBackfilling(Workload * workload, SchedulingDecision * decision, Queue * queue, ResourceSelector * selector,
-                      double rjms_delay, rapidjson::Document * variant_options);
-    virtual ~EnergyBackfilling();
-
-    virtual void on_simulation_start(double date, const rapidjson::Value & batsim_config);
-
-    virtual void on_simulation_end(double date);
-
-    virtual void on_machine_state_changed(double date, IntervalSet machines, int newState);
-
-    virtual void on_requested_call(double date);
-
-    virtual void make_decisions(double date,
-                                SortableJobOrder::UpdateInformation * update_info,
-                                SortableJobOrder::CompareInformation * compare_info);
-
-protected:
-    void generate_machine_informations(int nb_machines);
-    void clear_machine_informations();
-
-    void make_decisions_of_schedule(const Schedule & schedule, bool run_call_me_later_on_nothing_to_do = true);
-
-    void update_first_slice_taking_sleep_jobs_into_account(Rational date);
-
-    void put_jobs_into_schedule(Schedule & schedule) const;
-
-    /**
-     * @brief Sedates machines as soon as they remain idle.
-     * @param[in] schedule The Schedule into which the sedatings should be done
-     * @param[in] machines_to_sedate The machines to sedate
-     * @return The earliest sedating decision date
-     */
-    Rational sedate_machines_at_the_furthest_moment(Schedule & schedule,
-                                                    const IntervalSet & machines_to_sedate) const;
-    void sedate_machine(Schedule & schedule,
-                        int machine_id,
-                        std::list<Schedule::TimeSlice>::iterator time_slice,
-                        bool insert_in_slice = true) const;
-    void sedate_machine_without_switch(Schedule & schedule,
-                                       int machine_id,
-                                       Rational when_it_should_start) const;
-
-    void awaken_machine(Schedule & schedule,
-                        int machine_id,
-                        Rational awakening_date) const;
-
-    /**
-     * @brief Awakens a machine as soon as possible
-     * @param[in] schedule The Schedule into which the awakening should be done
-     * @param[in] machine_id The machine to awaken
-     * @return The moment at which the machine should be awakened
-     */
-    Rational awaken_machine_as_soon_as_possible(Schedule & schedule,
-                                                int machine_id) const;
-
-    ScheduleMetrics compute_metrics_of_schedule(const Schedule & schedule, Rational min_job_length = 30) const;
-
-    /**
-     * @brief Computes the machines that can be awakened inside a given time slice.
-     * @details These machines are the ones on which potential sleep jobs are allocated
-     * @param[in] time_slice The time slice
-     * @return The machines that can be awaked inside the given time slice
-     */
-    static IntervalSet compute_potentially_awaken_machines(const Schedule::TimeSlice & time_slice);
-    static IntervalSet compute_sleeping_machines(const Schedule::TimeSlice & time_slice);
-
-    Rational find_earliest_moment_to_awaken_machines(Schedule & schedule, const IntervalSet & machines_to_awaken) const;
-
-    Rational estimate_energy_of_schedule(const Schedule & schedule, Rational horizon) const;
-
-    static bool is_switch_on_job(const std::string & job_id);
-    static bool is_switch_off_job(const std::string & job_id);
-    static bool is_ensured_sleep_job(const std::string & job_id);
-    static bool is_potential_sleep_job(const std::string & job_id);
-    static bool is_fake_job(const std::string & job_id);
-
-    static bool contains_any_fake_job(const Schedule & schedule);
-    static bool contains_any_nonfake_job(const Schedule & schedule);
-
-protected:
-    Schedule _schedule;
-    bool _debug = false;
-
-    int _nb_call_me_later_running = 0;
-
-    int _nb_jobs_submitted = 0;
-    int _nb_jobs_completed = 0;
-
-    std::map<int, MachineInformation*> _machine_informations;
-
-    IntervalSet _all_machines; //!< All the machines that can be used for computing jobs
-    IntervalSet _switching_on_machines; //!< The machines currently being switched ON
-    IntervalSet _switching_off_machines; //!< The machines currently being switched OFF
-    IntervalSet _asleep_machines; //!< The machines currently in a sleepy state. They cannot be used to compute jobs now. This is the union of _wakable_asleep_machines and _non_wakable_asleep_machines
-    IntervalSet _wakable_asleep_machines; //!< Subset of _asleep_machines. Those machines have been sleeping for enough time, they can be awakened.
-    IntervalSet _non_wakable_asleep_machines; //!< Subset of _asleep_machines. Those machines have NOT been sleeping for enough time, they cannot be awakened yet.
-    IntervalSet _awake_machines; //!< The machines currently in a computation pstate. They can represent the machines which compute jobs, or idle machines.
-};
diff --git a/src/algo/energy_bf_dicho.cpp b/src/algo/energy_bf_dicho.cpp
deleted file mode 100644
index b8fb35718c0bca51066e8ab54281f8b718588895..0000000000000000000000000000000000000000
--- a/src/algo/energy_bf_dicho.cpp
+++ /dev/null
@@ -1,292 +0,0 @@
-#include "energy_bf_dicho.hpp"
-
-#include <loguru.hpp>
-
-#include "../pempek_assert.hpp"
-
-using namespace std;
-
-EnergyBackfillingDichotomy::EnergyBackfillingDichotomy(Workload *workload, SchedulingDecision *decision, Queue *queue,
-                                                       ResourceSelector *selector, double rjms_delay,
-                                                       rapidjson::Document *variant_options) :
-    EnergyBackfilling(workload, decision, queue, selector, rjms_delay, variant_options)
-{
-    _str_to_comparison_type["switch_on"] = SWITCH_ON;
-    _str_to_comparison_type["remove_sleep_jobs"] = REMOVE_SLEEP_JOBS;
-
-    // Let's get the tolerated slowdown loss ratio from the variant options
-    PPK_ASSERT_ERROR(variant_options->HasMember("tolerated_slowdown_loss_ratio"),
-                     "Invalid options JSON object: Member 'tolerated_slowdown_loss_ratio' cannot be found");
-    PPK_ASSERT_ERROR((*variant_options)["tolerated_slowdown_loss_ratio"].IsNumber(),
-                     "Invalid options JSON object: Member 'tolerated_slowdown_loss_ratio' should be a number");
-    _tolerated_slowdown_loss_ratio = (*variant_options)["tolerated_slowdown_loss_ratio"].GetDouble();
-    PPK_ASSERT_ERROR(_tolerated_slowdown_loss_ratio >= 0,
-                     "Invalid options JSON object: Member 'tolerated_slowdown_loss_ratio' should be positive or null (got %g)",
-                     (double) _tolerated_slowdown_loss_ratio);
-
-    if (variant_options->HasMember("comparison_type"))
-    {
-        PPK_ASSERT_ERROR((*variant_options)["comparison_type"].IsString(),
-                         "Invalid options JSON object: Member 'comparison_type' should be a string");
-        string comp_type = (*variant_options)["comparison_type"].GetString();
-        PPK_ASSERT_ERROR(_str_to_comparison_type.count(comp_type) == 1,
-                         "Invalid options JSON object: invalid 'comparison_type' value (%s)",
-                         comp_type.c_str());
-        _comparison_type = _str_to_comparison_type.at(comp_type);
-    }
-}
-
-EnergyBackfillingDichotomy::~EnergyBackfillingDichotomy()
-{
-
-}
-
-void EnergyBackfillingDichotomy::make_decisions(double date,
-                                                SortableJobOrder::UpdateInformation *update_info,
-                                                SortableJobOrder::CompareInformation *compare_info)
-{
-    // Let's remove finished jobs from the schedule
-    for (const string & ended_job_id : _jobs_ended_recently)
-    {
-        const Job * ended_job = (*_workload)[ended_job_id];
-        ++_nb_jobs_completed;
-
-        PPK_ASSERT_ERROR(_schedule.contains_job(ended_job),
-                         "Invalid schedule: job '%s' just finished, "
-                         "but it not in the schedule...\n%s",
-                         ended_job_id.c_str(), _schedule.to_string().c_str());
-        PPK_ASSERT_ERROR(!_queue->contains_job(ended_job),
-                         "Job '%s' just ended, but it is still in the "
-                         "queue...\nQueue : %s",
-                         ended_job_id.c_str(),
-                         _queue->to_string().c_str());
-
-        // Let's remove the finished job from the schedule
-        _schedule.remove_job(ended_job);
-    }
-
-    // Let's handle recently released jobs
-    for (const string & new_job_id : _jobs_released_recently)
-    {
-        const Job * new_job = (*_workload)[new_job_id];
-        ++_nb_jobs_submitted;
-
-        PPK_ASSERT_ERROR(!_schedule.contains_job(new_job),
-                         "Invalid schedule: job '%s' already exists.\n%s",
-                         new_job->id.c_str(), _schedule.to_string().c_str());
-        PPK_ASSERT_ERROR(!_queue->contains_job(new_job),
-                         "Job '%s' is already in the queue!\nQueue:%s",
-                         new_job->id.c_str(), _queue->to_string().c_str());
-
-        if (new_job->nb_requested_resources > _nb_machines)
-        {
-            _decision->add_reject_job(new_job_id, date);
-            ++_nb_jobs_completed;
-        }
-        else
-            _queue->append_job(new_job, update_info);
-    }
-
-    // Let's update the first slice of the schedule
-    update_first_slice_taking_sleep_jobs_into_account(date);
-
-    // Let's update the sorting of the queue
-    _queue->sort_queue(update_info, compare_info);
-
-    // Let's find the schedule which:
-    //  - minimises the estimated energy consumption
-    //  - respects the slowdown constraint: not worse in avg bds (for jobs in schedule) than
-    //    tolerated_slowdown_loss_ratio times the bds of the schedule in which all nodes are awaken first.
-
-    // *******************************************************************
-    // Let's compute global informations about the current online schedule
-    // *******************************************************************
-    const Schedule::TimeSlice & online_first_slice = *_schedule.begin();
-    IntervalSet sleeping_machines = compute_sleeping_machines(online_first_slice);
-    IntervalSet awakenable_sleeping_machines = compute_potentially_awaken_machines(online_first_slice);
-    const IntervalSet & available_machines = online_first_slice.available_machines;
-
-    // ****************************************************************
-    // Let's first compute the schedule in which all nodes are awakened
-    // ****************************************************************
-    Schedule awakened_schedule = _schedule;
-
-    if (_comparison_type == SWITCH_ON)
-    {
-        // Let's awaken every machine at the earliest moment for each machine
-        for (auto machine_it = sleeping_machines.elements_begin(); machine_it != sleeping_machines.elements_end(); ++machine_it)
-        {
-            int machine_id = *machine_it;
-            Rational wake_up_moment = find_earliest_moment_to_awaken_machines(awakened_schedule, IntervalSet(machine_id));
-            awaken_machine(awakened_schedule, machine_id, wake_up_moment);
-        }
-    }
-    else if (_comparison_type == REMOVE_SLEEP_JOBS)
-    {
-        // Let's simply remove sleep jobs from the schedule!
-        for (auto machine_it = sleeping_machines.elements_begin(); machine_it != sleeping_machines.elements_end(); ++machine_it)
-        {
-            int machine_id = *machine_it;
-            MachineInformation *minfo = _machine_informations.at(machine_id);
-            while (awakened_schedule.remove_job_if_exists(minfo->ensured_sleep_job));
-            while (awakened_schedule.remove_job_if_exists(minfo->potential_sleep_job));
-        }
-    }
-
-    // Let's add jobs into the schedule
-    put_jobs_into_schedule(awakened_schedule);
-
-    // *********************************************************************************
-    // Let's determine if the online schedule respects our avg bds constraint.
-    // If so, we should try to sedate machines. Otherwise, we should try to awaken some.
-    // *********************************************************************************
-    Schedule online_schedule = _schedule;
-    put_jobs_into_schedule(online_schedule);
-
-    //Rational online_awakened_comparison_horizon = max(awakened_schedule.finite_horizon(), online_schedule.finite_horizon());
-
-    // Let's compute the jobs metrics and energy of the two schedules
-    ScheduleMetrics online_sched_metrics = compute_metrics_of_schedule(online_schedule);
-    ScheduleMetrics awakened_sched_metrics = compute_metrics_of_schedule(awakened_schedule);
-    //Rational online_sched_energy = estimate_energy_of_schedule(online_schedule, online_awakened_comparison_horizon);
-    //Rational awakened_sched_energy = estimate_energy_of_schedule(awakened_schedule, online_awakened_comparison_horizon);
-
-    bool should_sedate_machines = false;
-    if (online_sched_metrics.mean_slowdown <= awakened_sched_metrics.mean_slowdown * _tolerated_slowdown_loss_ratio)
-        should_sedate_machines = true;
-
-    // *****************************************************************************************
-    // Let's do a dichotomy on the number of machines to awaken/sedate to find the best solution
-    // *****************************************************************************************
-
-    LOG_F(INFO, "should_sedate_machines=%d", should_sedate_machines);
-
-    if (should_sedate_machines)
-    {
-         // Sleeping machines are not available since they compute "fake" jobs
-        IntervalSet sedatable_machines = available_machines;
-
-        int nb_to_sedate_min = 1; // Online schedule is nb_to_sedate = 0
-        int nb_to_sedate_max = sedatable_machines.size();
-
-        Schedule best_schedule = online_schedule;
-        ScheduleMetrics best_sched_metrics = online_sched_metrics;
-        //Rational best_sched_energy = online_sched_energy;
-        int best_nb_to_sedate = 0;
-
-        // Dichotomy
-        while (nb_to_sedate_min < nb_to_sedate_max)
-        {
-            // Select machines to sedate
-            int nb_to_sedate = (nb_to_sedate_min + nb_to_sedate_max) / 2;
-
-            IntervalSet machines_to_sedate;
-            _selector->select_resources_to_sedate(nb_to_sedate, available_machines, sedatable_machines, machines_to_sedate);
-
-            // Create the schedule with the desired sedated machines
-            Schedule schedule = _schedule;
-
-            for (auto machine_it = machines_to_sedate.elements_begin(); machine_it != machines_to_sedate.elements_end(); ++machine_it)
-            {
-                int machine_id = *machine_it;
-                sedate_machine(schedule, machine_id, schedule.begin());
-            }
-
-            put_jobs_into_schedule(schedule);
-
-            // Let's compute jobs metrics about the current schedule
-            ScheduleMetrics sched_metrics = compute_metrics_of_schedule(schedule);
-
-            // If the schedule respects the avg slowdown constraint
-            if (sched_metrics.mean_slowdown <= awakened_sched_metrics.mean_slowdown * _tolerated_slowdown_loss_ratio)
-            {
-                // Let's compute the energy of both schedules to compare them
-                Rational comparison_horizon = max(best_schedule.finite_horizon(), schedule.finite_horizon());
-                Rational best_sched_energy = estimate_energy_of_schedule(best_schedule, comparison_horizon);
-                Rational sched_energy = estimate_energy_of_schedule(schedule, comparison_horizon);
-
-                LOG_F(INFO, "Current schedule respects the mean slowdown constraint. "
-                     "(best_energy, curr_energy) : (%g, %g)",
-                     (double)best_sched_energy, (double)sched_energy);
-
-                // Let's update the best solution if needed
-                if ((sched_energy < best_sched_energy) ||
-                    ((sched_energy == best_sched_energy) && (nb_to_sedate > best_nb_to_sedate)))
-                {
-                    best_schedule = schedule;
-                    best_sched_metrics = sched_metrics;
-                    best_sched_energy = sched_energy;
-                    best_nb_to_sedate = nb_to_sedate;
-                }
-
-                nb_to_sedate_min = nb_to_sedate + 1;
-            }
-            else
-                nb_to_sedate_max = nb_to_sedate - 1;
-        }
-
-        // Let's apply the decisions of the best schedule
-        make_decisions_of_schedule(best_schedule);
-    }
-    else
-    {
-        int nb_to_awaken_min = 1; // online schedule is nb_to_awaken = 0
-        int nb_to_awaken_max = awakenable_sleeping_machines.size();
-
-        Schedule best_schedule = online_schedule;
-        ScheduleMetrics best_sched_metrics = online_sched_metrics;
-        int best_nb_to_awaken = 0;
-
-        // Dichotomy
-        while (nb_to_awaken_min < nb_to_awaken_max)
-        {
-            // Select machines to awaken
-            int nb_to_awaken = (nb_to_awaken_min + nb_to_awaken_max) / 2;
-            IntervalSet machines_to_awaken;
-            _selector->select_resources_to_awaken(nb_to_awaken, available_machines, awakenable_sleeping_machines, machines_to_awaken);
-
-            // Create the schedule with the desired awakened machines
-            Schedule schedule = _schedule;
-
-            for (auto machine_it = machines_to_awaken.elements_begin(); machine_it != machines_to_awaken.elements_end(); ++machine_it)
-            {
-                int machine_id = *machine_it;
-                Rational wake_up_date = find_earliest_moment_to_awaken_machines(schedule, IntervalSet(machine_id));
-                awaken_machine(schedule, machine_id, wake_up_date);
-            }
-
-            put_jobs_into_schedule(schedule);
-
-            ScheduleMetrics sched_metrics = compute_metrics_of_schedule(schedule);
-
-            // If the schedule respects our avg slowdown constraint
-            if (sched_metrics.mean_slowdown <= awakened_sched_metrics.mean_slowdown * _tolerated_slowdown_loss_ratio)
-            {
-                // Let's compute the energy of both schedules to compare them
-                Rational comparison_horizon = max(best_schedule.finite_horizon(), schedule.finite_horizon());
-                Rational best_sched_energy = estimate_energy_of_schedule(best_schedule, comparison_horizon);
-                Rational sched_energy = estimate_energy_of_schedule(schedule, comparison_horizon);
-
-                LOG_F(INFO, "Current schedule respects the mean slowdown constraint. "
-                     "(best_energy, curr_energy) : (%g, %g)",
-                     (double)best_sched_energy, (double)sched_energy);
-
-                // Let's update the best solution if needed
-                if ((sched_energy < best_sched_energy) ||
-                    ((sched_energy == best_sched_energy) && (nb_to_awaken < best_nb_to_awaken)))
-                {
-                    best_schedule = schedule;
-                    best_sched_metrics = sched_metrics;
-                    best_nb_to_awaken = nb_to_awaken;
-                }
-
-                nb_to_awaken_max = nb_to_awaken - 1;
-            }
-            else
-                nb_to_awaken_min = nb_to_awaken + 1;
-        }
-
-        // Let's apply the decisions of the best schedule
-        make_decisions_of_schedule(best_schedule);
-    }
-}
diff --git a/src/algo/energy_bf_dicho.hpp b/src/algo/energy_bf_dicho.hpp
deleted file mode 100644
index a1031d6b894784b91d9d87d706e974b191fe39f7..0000000000000000000000000000000000000000
--- a/src/algo/energy_bf_dicho.hpp
+++ /dev/null
@@ -1,28 +0,0 @@
-#pragma once
-
-#include "energy_bf.hpp"
-
-class EnergyBackfillingDichotomy : public EnergyBackfilling
-{
-    enum AwakeningComparisonType
-    {
-        SWITCH_ON,
-        REMOVE_SLEEP_JOBS
-    };
-
-public:
-    EnergyBackfillingDichotomy(Workload * workload, SchedulingDecision * decision, Queue * queue, ResourceSelector * selector,
-                               double rjms_delay, rapidjson::Document * variant_options);
-    virtual ~EnergyBackfillingDichotomy();
-
-protected:
-    virtual void make_decisions(double date,
-                                SortableJobOrder::UpdateInformation * update_info,
-                                SortableJobOrder::CompareInformation * compare_info);
-
-private:
-    Rational _tolerated_slowdown_loss_ratio;
-    AwakeningComparisonType _comparison_type = REMOVE_SLEEP_JOBS;
-
-    std::map<std::string, AwakeningComparisonType> _str_to_comparison_type;
-};
diff --git a/src/algo/energy_bf_idle_sleeper.cpp b/src/algo/energy_bf_idle_sleeper.cpp
deleted file mode 100644
index 0bc195be469cf7f90bb96f79a1bd966f1cedcfb9..0000000000000000000000000000000000000000
--- a/src/algo/energy_bf_idle_sleeper.cpp
+++ /dev/null
@@ -1,239 +0,0 @@
-#include "energy_bf_idle_sleeper.hpp"
-
-#include <loguru.hpp>
-
-#include "../pempek_assert.hpp"
-
-using namespace std;
-
-EnergyBackfillingIdleSleeper::EnergyBackfillingIdleSleeper(Workload *workload,
-                                                           SchedulingDecision *decision,
-                                                           Queue *queue,
-                                                           ResourceSelector *selector,
-                                                           double rjms_delay,
-                                                           rapidjson::Document *variant_options) :
-    EnergyBackfillingMonitoringInertialShutdown(workload, decision, queue, selector, rjms_delay, variant_options)
-{
-}
-
-EnergyBackfillingIdleSleeper::~EnergyBackfillingIdleSleeper()
-{
-
-}
-
-void EnergyBackfillingIdleSleeper::on_monitoring_stage(double date)
-{
-    update_first_slice_taking_sleep_jobs_into_account(date);
-    _inertial_schedule = _schedule;
-
-    update_idle_states(date, _inertial_schedule, _all_machines, _idle_machines,
-                       _machines_idle_start_date);
-    make_idle_sleep_decisions(date);
-}
-
-void EnergyBackfillingIdleSleeper::select_idle_machines_to_sedate(Rational current_date,
-                                                                  const IntervalSet &idle_machines,
-                                                                  const IntervalSet &machines_awake_soon,
-                                                                  const Job *priority_job,
-                                                                  const std::map<int, Rational> idle_machines_start_date,
-                                                                  Rational minimum_idle_time_to_sedate,
-                                                                  IntervalSet &machines_to_sedate,
-                                                                  bool take_priority_job_into_account)
-{
-    int nb_awake_soon = machines_awake_soon.size();
-
-    int nb_needed_for_priority_job = 0;
-    if (priority_job != nullptr && take_priority_job_into_account)
-        nb_needed_for_priority_job = priority_job->nb_requested_resources;
-
-    Rational sedate_thresh = current_date - minimum_idle_time_to_sedate;
-    IntervalSet sedatable_idle_machines;
-
-    for (auto machine_it = idle_machines.elements_begin();
-         machine_it != idle_machines.elements_end();
-         ++machine_it)
-    {
-        const int machine_id = *machine_it;
-        if (idle_machines_start_date.at(machine_id) <= sedate_thresh)
-            sedatable_idle_machines.insert(machine_id);
-    }
-
-    // To avoid blocking the priority job with switches OFF, let's reduce
-    // the number of machines to switch OFF if needed.
-    int nb_machines_to_sedate = max(0, min(nb_awake_soon - nb_needed_for_priority_job,
-                                           (int)sedatable_idle_machines.size()));
-
-    machines_to_sedate.clear();
-    if (nb_machines_to_sedate > 0)
-        machines_to_sedate = sedatable_idle_machines.left(nb_machines_to_sedate);
-}
-
-void EnergyBackfillingIdleSleeper::select_idle_machines_to_awaken(const Queue *queue,
-                                                                  const Schedule &schedule,
-                                                                  ResourceSelector * priority_job_selector,
-                                                                  const IntervalSet &idle_machines,
-                                                                  AwakeningPolicy policy,
-                                                                  int maximum_nb_machines_to_awaken,
-                                                                  IntervalSet &machines_to_awaken,
-                                                                  bool take_priority_job_into_account)
-{
-    PPK_ASSERT_ERROR(maximum_nb_machines_to_awaken >= 0);
-    machines_to_awaken.clear();
-
-    // If there are no jobs to compute, there is nothing more to do.
-    if (queue->nb_jobs() <= 0)
-        return;
-
-    // If we only awaken for the priority job, this is already done by Inertial Shutdown.
-    if (policy == AWAKEN_FOR_PRIORITY_JOB_ONLY)
-        return;
-
-    Schedule schedule_copy = schedule;
-
-    // Let's try to backfill some jobs into the awakenable machines, and wake them up if needed.
-    IntervalSet awakable_machines = compute_potentially_awaken_machines(*schedule_copy.begin());
-
-    if (awakable_machines.size() > (unsigned int)maximum_nb_machines_to_awaken)
-        awakable_machines = awakable_machines.left(maximum_nb_machines_to_awaken);
-
-    IntervalSet usable_machines = idle_machines + awakable_machines;
-    IntervalSet usable_idle_machines = idle_machines;
-
-    // Let's find the priority job and related stuff to avoid penalizing the priority job
-
-    const Job * priority_job;
-    bool priority_job_needs_awakenings;
-    Schedule::JobAlloc priority_job_alloc;
-    IntervalSet priority_job_reserved_machines;
-    IntervalSet machines_that_can_be_used_by_the_priority_job;
-    compute_priority_job_and_related_stuff(schedule_copy, queue, priority_job,
-                                           priority_job_selector,
-                                           priority_job_needs_awakenings,
-                                           priority_job_alloc,
-                                           priority_job_reserved_machines,
-                                           machines_that_can_be_used_by_the_priority_job);
-
-    if (policy == AWAKEN_FOR_ALL_JOBS_RESPECTING_PRIORITY_JOB && take_priority_job_into_account)
-    {
-        // Let's remove the priority_job_reserved_machines from the usable_machines
-        usable_idle_machines -= priority_job_reserved_machines;
-        usable_machines -= priority_job_reserved_machines;
-    }
-
-    auto job_it = queue->begin();
-    while (usable_machines.size() > 0 && job_it != queue->end())
-    {
-        const Job * job = (*job_it)->job;
-        if (job->nb_requested_resources <= (int)usable_machines.size())
-        {
-            IntervalSet machines_to_use_for_this_job;
-
-            if (usable_idle_machines.size() > 0)
-            {
-                int nb_idle_machines_to_use = min((int)usable_idle_machines.size(), job->nb_requested_resources);
-                machines_to_use_for_this_job = usable_idle_machines.left(nb_idle_machines_to_use);
-                usable_idle_machines -= machines_to_use_for_this_job;
-            }
-
-            machines_to_use_for_this_job += usable_machines.left(job->nb_requested_resources - (int)machines_to_use_for_this_job.size());
-            IntervalSet machines_to_awaken_for_this_job = (awakable_machines & machines_to_use_for_this_job);
-
-            usable_machines -= machines_to_use_for_this_job;
-            awakable_machines -= machines_to_awaken_for_this_job;
-            machines_to_awaken += machines_to_awaken_for_this_job;
-        }
-
-        ++job_it;
-    }
-
-    PPK_ASSERT_ERROR((int)machines_to_awaken.size() <= maximum_nb_machines_to_awaken);
-}
-
-void EnergyBackfillingIdleSleeper::update_idle_states(Rational current_date,
-                                                      const Schedule & schedule,
-                                                      const IntervalSet & all_machines,
-                                                      IntervalSet & idle_machines,
-                                                      map<int,Rational> & machines_idle_start_date)
-{
-    PPK_ASSERT_ERROR(schedule.nb_slices() > 0);
-    PPK_ASSERT_ERROR(schedule.first_slice_begin() == Rational(current_date));
-
-    const Schedule::TimeSlice & slice = *schedule.begin();
-
-    IntervalSet machines_newly_available = (slice.available_machines & (all_machines - idle_machines));
-
-    for (auto machine_it = machines_newly_available.elements_begin();
-         machine_it != machines_newly_available.elements_end();
-         ++machine_it)
-    {
-        int machine_id = *machine_it;
-        machines_idle_start_date[machine_id] = current_date;
-    }
-
-    IntervalSet machines_newly_busy = ((all_machines - slice.available_machines) & idle_machines);
-
-    for (auto machine_it = machines_newly_busy.elements_begin();
-         machine_it != machines_newly_busy.elements_end();
-         ++machine_it)
-    {
-        int machine_id = *machine_it;
-        machines_idle_start_date[machine_id] = schedule.infinite_horizon();
-    }
-
-    PPK_ASSERT_ERROR((machines_newly_available & machines_newly_busy) == IntervalSet::empty_interval_set(),
-                     "machines_newly_available=%s. machines_newly_busy=%s",
-                     machines_newly_available.to_string_brackets().c_str(),
-                     machines_newly_busy.to_string_brackets().c_str());
-
-    PPK_ASSERT_ERROR((machines_newly_available & idle_machines) == IntervalSet::empty_interval_set(),
-                     "machines_newly_available=%s. _idle_machines=%s",
-                     machines_newly_available.to_string_brackets().c_str(),
-                     idle_machines.to_string_brackets().c_str());
-
-    PPK_ASSERT_ERROR((machines_newly_busy & idle_machines) == machines_newly_busy,
-                     "machines_newly_busy=%s. _idle_machines=%s",
-                     machines_newly_busy.to_string_brackets().c_str(),
-                     idle_machines.to_string_brackets().c_str());
-
-    idle_machines += machines_newly_available;
-    idle_machines -= machines_newly_busy;
-}
-
-void EnergyBackfillingIdleSleeper::make_idle_sleep_decisions(double date)
-{
-    const Job * priority_job = _queue->first_job_or_nullptr();
-    IntervalSet machines_awake_soon = (_awake_machines + _switching_on_machines - _switching_off_machines)
-                                       + _machines_to_awaken - _machines_to_sedate;
-
-    IntervalSet machines_to_sedate;
-    select_idle_machines_to_sedate(date, _idle_machines, machines_awake_soon,
-                                   priority_job, _machines_idle_start_date,
-                                   _needed_amount_of_idle_time_to_be_sedated,
-                                   machines_to_sedate);
-
-    if (machines_to_sedate.size() > 0)
-    {
-        _machines_to_sedate += machines_to_sedate;
-        _nb_machines_sedated_for_being_idle += machines_to_sedate.size();
-
-        IntervalSet machines_sedated_this_turn, machines_awakened_this_turn;
-        handle_queued_switches(_inertial_schedule, _machines_to_sedate, _machines_to_awaken,
-                               machines_sedated_this_turn, machines_awakened_this_turn);
-
-        if (machines_sedated_this_turn.size() > 0)
-            LOG_F(INFO, "Date=%g. Those machines should be put to sleep now: %s",
-                   date, machines_sedated_this_turn.to_string_brackets().c_str());
-        if (machines_awakened_this_turn.size() > 0)
-            LOG_F(INFO, "Date=%g. Those machines should be awakened now: %s",
-                   date, machines_awakened_this_turn.to_string_brackets().c_str());
-
-        _machines_to_sedate -= machines_sedated_this_turn;
-        _machines_to_awaken -= machines_awakened_this_turn;
-        _machines_sedated_since_last_monitoring_stage_inertia = machines_sedated_this_turn;
-        _machines_awakened_since_last_monitoring_stage_inertia = machines_awakened_this_turn;
-
-        PPK_ASSERT_ERROR((_machines_to_awaken & _machines_to_sedate) == IntervalSet::empty_interval_set());
-
-        make_decisions_of_schedule(_inertial_schedule, false);
-    }
-}
diff --git a/src/algo/energy_bf_idle_sleeper.hpp b/src/algo/energy_bf_idle_sleeper.hpp
deleted file mode 100644
index cf45001fdc141a7881b925f80c4a0be428171ca0..0000000000000000000000000000000000000000
--- a/src/algo/energy_bf_idle_sleeper.hpp
+++ /dev/null
@@ -1,82 +0,0 @@
-#pragma once
-
-#include "energy_bf_monitoring_inertial_shutdown.hpp"
-
-#include <map>
-
-class EnergyBackfillingIdleSleeper : public EnergyBackfillingMonitoringInertialShutdown
-{
-public:
-    enum AwakeningPolicy
-    {
-        AWAKEN_FOR_PRIORITY_JOB_ONLY,
-        AWAKEN_FOR_ALL_JOBS_WITHOUT_RESPECTING_PRIORITY_JOB,
-        AWAKEN_FOR_ALL_JOBS_RESPECTING_PRIORITY_JOB
-    };
-
-public:
-    EnergyBackfillingIdleSleeper(Workload * workload, SchedulingDecision * decision,
-                                           Queue * queue, ResourceSelector * selector,
-                                           double rjms_delay, rapidjson::Document * variant_options);
-
-    virtual ~EnergyBackfillingIdleSleeper();
-
-    virtual void on_monitoring_stage(double date);
-
-public:
-    /**
-     * @brief Selects which machines should be sedated for being idle for too long
-     * @param[in] current_date The current date
-     * @param[in] idle_machines The machines currently idle
-     * @param[in] machines_awake_soon The machines that will be awake soon (those awake now and those switching ON)
-     * @param[in] priority_job The priority job (nullptr if there is no priority job)
-     * @param[in] idle_machines_start_date A map which associates machine_ids to the starting time of their idle state
-     * @param[in] minimum_idle_time_to_sedate The machines must be idle for a longer time than idle_sedate_thresh to be sedated
-     * @param[out] machines_to_sedate The machines that can be sedated for being idle for too long (output parameter)
-     */
-    static void select_idle_machines_to_sedate(Rational current_date,
-                                               const IntervalSet & idle_machines,
-                                               const IntervalSet & machines_awake_soon,
-                                               const Job * priority_job,
-                                               const std::map<int, Rational> idle_machines_start_date,
-                                               Rational minimum_idle_time_to_sedate,
-                                               IntervalSet & machines_to_sedate,
-                                               bool take_priority_job_into_account = true);
-
-    /**
-     * @brief Selects which machines should be awakened to compute some jobs
-     * @param[in] queue The queue which contains jobs (or not)
-     * @param[in] schedule The current schedule. It should not be modified by this function.
-     * @param[in,out] priority_job_selector The ResourceSelector to insert the priority_job into the schedule
-     * @param[in] idle_machines The machines currently idle
-     * @param[in] policy The AwakeningPolicy to apply
-     * @param[in] maximum_nb_machines_to_awaken The maximum number of machines to awaken for this call
-     * @param[out] machines_to_awaken The machines that can be awakened to execute jobs (output parameter)
-     */
-    static void select_idle_machines_to_awaken(const Queue *queue,
-                                               const Schedule &schedule,
-                                               ResourceSelector * priority_job_selector,
-                                               const IntervalSet &idle_machines,
-                                               AwakeningPolicy policy,
-                                               int maximum_nb_machines_to_awaken,
-                                               IntervalSet &machines_to_awaken,
-                                               bool take_priority_job_into_account = true);
-
-    /**
-     * @brief Updates whichever machines are idle and their idle starting time if needed,
-     *        based on the first slice of the given schedule
-     * @param[in] current_date The current date
-     * @param[in] schedule The current schedule. Its first slice must reflect the platform usage
-     * @param[in] all_machines All computing machines
-     * @param[in,out] idle_machines The machines currently being idle
-     * @param[in,out] machines_idle_start_date The starting time of the idle period of the idle machines
-     */
-    static void update_idle_states(Rational current_date,
-                                   const Schedule & schedule,
-                                   const IntervalSet & all_machines,
-                                   IntervalSet & idle_machines,
-                                   std::map<int,Rational> & machines_idle_start_date);
-
-protected:
-    void make_idle_sleep_decisions(double date);
-};
diff --git a/src/algo/energy_bf_machine_subpart_sleeper.cpp b/src/algo/energy_bf_machine_subpart_sleeper.cpp
deleted file mode 100644
index 5425d3c5b4d916f0facd239e065dd66785feaf76..0000000000000000000000000000000000000000
--- a/src/algo/energy_bf_machine_subpart_sleeper.cpp
+++ /dev/null
@@ -1,271 +0,0 @@
-#include "energy_bf_machine_subpart_sleeper.hpp"
-
-#include <loguru.hpp>
-
-#include "energy_bf_idle_sleeper.hpp"
-#include "../pempek_assert.hpp"
-
-
-using namespace std;
-
-EnergyBackfillingMachineSubpartSleeper::EnergyBackfillingMachineSubpartSleeper(Workload *workload, SchedulingDecision *decision,
-                                                                               Queue *queue, ResourceSelector *selector,
-                                                                               double rjms_delay, rapidjson::Document *variant_options) :
-    EnergyBackfillingMonitoringInertialShutdown(workload, decision, queue, selector, rjms_delay, variant_options)
-{
-    PPK_ASSERT_ERROR(variant_options->HasMember("fraction_of_machines_to_let_awake"),
-                     "Invalid options JSON object: Member 'fraction_of_machines_to_let_awake' cannot be found");
-    PPK_ASSERT_ERROR((*variant_options)["fraction_of_machines_to_let_awake"].IsNumber(),
-                     "Invalid options JSON object: Member 'fraction_of_machines_to_let_awake' must be a number");
-    _fraction_of_machines_to_let_awake = (*variant_options)["fraction_of_machines_to_let_awake"].GetDouble();
-
-    PPK_ASSERT_ERROR(_fraction_of_machines_to_let_awake >= 0 && _fraction_of_machines_to_let_awake <= 1,
-                     "Invalid options JSON object: Member 'fraction_of_machines_to_let_awake' has an invalid "
-                     "value (%g)", (double) _fraction_of_machines_to_let_awake);
-
-    LOG_SCOPE_FUNCTION(INFO);
-    LOG_F(INFO, "Fraction of machines to let awake: %g",
-           (double) _fraction_of_machines_to_let_awake);
-}
-
-EnergyBackfillingMachineSubpartSleeper::~EnergyBackfillingMachineSubpartSleeper()
-{
-
-}
-
-void EnergyBackfillingMachineSubpartSleeper::on_monitoring_stage(double date)
-{
-    update_first_slice_taking_sleep_jobs_into_account(date);
-    _inertial_schedule = _schedule;
-
-    // Let's check whether the asleep machines are consistent
-    IntervalSet machines_asleep_soon = (_asleep_machines + _switching_off_machines - _switching_on_machines)
-                                        + _machines_to_sedate - _machines_to_awaken;
-    PPK_ASSERT_ERROR((int)machines_asleep_soon.size() == _nb_machines_sedated_by_inertia +
-                                                         _nb_machines_sedated_for_being_idle,
-                     "Asleep machines inconsistency. nb_asleep_soon=%d (%s). nb_sedated_inertia=%d. "
-                     "nb_sedated_idle=%d\n",
-                     (int)machines_asleep_soon.size(), machines_asleep_soon.to_string_brackets().c_str(),
-                     _nb_machines_sedated_by_inertia, _nb_machines_sedated_for_being_idle);
-
-    // Let's clear the machines to sedate, to possibly take new ones which would be sedated before
-    if (_machines_to_sedate.size() > 0)
-    {
-        // The machines sedated for being idle should never be done in the future, so
-        // cancelled switches OFF are inertial ones. However, for coherency's sake,
-        // the number of idle-sedated machines might also be decreased if there is no
-        // inertially-sedated machines left.
-        int nb_cancelled_switches_off = (int) _machines_to_sedate.size();
-        int nb_cancelled_inertially_sedated_machines = min(nb_cancelled_switches_off,
-                                                           _nb_machines_sedated_by_inertia);
-
-        int nb_cancelled_idle_sedated_machines = 0;
-        if (nb_cancelled_inertially_sedated_machines < nb_cancelled_switches_off)
-            nb_cancelled_idle_sedated_machines = nb_cancelled_switches_off -
-                                                 nb_cancelled_inertially_sedated_machines;
-
-        PPK_ASSERT_ERROR(nb_cancelled_inertially_sedated_machines +
-                         nb_cancelled_idle_sedated_machines == nb_cancelled_switches_off);
-
-        _nb_machines_sedated_by_inertia -= nb_cancelled_inertially_sedated_machines;
-        _nb_machines_sedated_for_being_idle -= nb_cancelled_idle_sedated_machines;
-
-        PPK_ASSERT_ERROR(_nb_machines_sedated_by_inertia >= 0);
-        PPK_ASSERT_ERROR(_nb_machines_sedated_for_being_idle >= 0);
-
-        _machines_to_sedate.clear();
-
-        // Let's check whether the asleep machines are consistent
-        machines_asleep_soon = (_asleep_machines + _switching_off_machines - _switching_on_machines)
-                               + _machines_to_sedate - _machines_to_awaken;
-        PPK_ASSERT_ERROR((int)machines_asleep_soon.size() == _nb_machines_sedated_by_inertia +
-                                                             _nb_machines_sedated_for_being_idle,
-                         "Asleep machines inconsistency. nb_asleep_soon=%d (%s). nb_sedated_inertia=%d. "
-                         "nb_sedated_idle=%d\n",
-                         (int)machines_asleep_soon.size(), machines_asleep_soon.to_string_brackets().c_str(),
-                         _nb_machines_sedated_by_inertia, _nb_machines_sedated_for_being_idle);
-    }
-
-    const Job * priority_job = _queue->first_job_or_nullptr();
-    IntervalSet machines_awake_soon = (_awake_machines + _switching_on_machines - _switching_off_machines)
-                                       + _machines_to_awaken - _machines_to_sedate;
-    int nb_machines_to_let_awakened = (int) (_fraction_of_machines_to_let_awake * _all_machines.size());
-    if (_inertial_shutdown_debug)
-        LOG_F(1, "Date=%g. nb_machines_to_let_awakened=%d", date, nb_machines_to_let_awakened);
-
-    IntervalSet machines_that_can_be_used_by_the_priority_job;
-    Schedule::JobAlloc priority_job_alloc;
-    IntervalSet priority_job_reserved_machines;
-    bool priority_job_needs_awakenings = false;
-
-    if (_inertial_shutdown_debug)
-        LOG_F(1, "Schedule without priority_job.%s", _inertial_schedule.to_string().c_str());
-
-    compute_priority_job_and_related_stuff(_inertial_schedule, _queue, priority_job,
-                                           _selector,
-                                           priority_job_needs_awakenings,
-                                           priority_job_alloc,
-                                           priority_job_reserved_machines,
-                                           machines_that_can_be_used_by_the_priority_job);
-
-    if (!priority_job_needs_awakenings)
-    {
-        if (priority_job != nullptr)
-            nb_machines_to_let_awakened = max(nb_machines_to_let_awakened, priority_job->nb_requested_resources);
-
-        int nb_machines_to_sedate = (int)machines_awake_soon.size() - nb_machines_to_let_awakened;
-        if (_inertial_shutdown_debug)
-            LOG_F(1, "Date=%g. nb_machines_to_sedate=%d", date, nb_machines_to_sedate);
-        if (nb_machines_to_sedate > 0)
-        {
-            if (_inertial_shutdown_debug)
-                LOG_F(1, "Date=%g. nb_machines_to_sedate=%d. machines_awake_soon=%s. "
-                       "machines_that_can_be_used_by_the_priority_job=%s",
-                       date, nb_machines_to_sedate,
-                       machines_awake_soon.to_string_brackets().c_str(),
-                       machines_that_can_be_used_by_the_priority_job.to_string_brackets().c_str());
-
-            // Let's "steal" some machines sedated for being idle if needed
-            int nb_idle_machines_to_steal = 0;
-            if (_nb_machines_sedated_for_being_idle > 0)
-            {
-                nb_idle_machines_to_steal = min(_nb_machines_sedated_for_being_idle,
-                                                    (int) nb_machines_to_sedate);
-                _nb_machines_sedated_by_inertia += nb_idle_machines_to_steal;
-                _nb_machines_sedated_for_being_idle -= nb_idle_machines_to_steal;
-            }
-
-            IntervalSet machines_to_sedate;
-            select_machines_to_sedate(nb_machines_to_sedate, machines_awake_soon,
-                                      machines_that_can_be_used_by_the_priority_job,
-                                      machines_to_sedate, priority_job);
-            LOG_F(INFO, "Date=%g. Machines to sedate were %s", date,
-                   _machines_to_sedate.to_string_brackets().c_str());
-            LOG_F(INFO, "Date=%g. Machines asleep soon were %s", date,
-                   machines_asleep_soon.to_string_brackets().c_str());
-
-            if (_inertial_shutdown_debug)
-                LOG_F(1, "Date=%g. machines_to_sedate=%s",
-                       date, machines_to_sedate.to_string_brackets().c_str());
-
-            _machines_to_sedate += machines_to_sedate;
-            _nb_machines_sedated_by_inertia += (int) machines_to_sedate.size();
-
-            LOG_F(INFO, "Machines to sedate are now %s", _machines_to_sedate.to_string_brackets().c_str());
-
-            IntervalSet machines_sedated_this_turn, machines_awakened_this_turn, empty_range;
-            handle_queued_switches(_inertial_schedule, _machines_to_sedate,
-                                   empty_range, machines_sedated_this_turn,
-                                   machines_awakened_this_turn);
-
-            PPK_ASSERT_ERROR(machines_awakened_this_turn == IntervalSet::empty_interval_set());
-
-            if (machines_sedated_this_turn.size() > 0)
-                LOG_F(INFO, "Date=%g. Those machines should be put to sleep now: %s",
-                       date, machines_sedated_this_turn.to_string_brackets().c_str());
-
-            _machines_to_sedate -= machines_sedated_this_turn;
-
-            PPK_ASSERT_ERROR((_machines_to_awaken & _machines_to_sedate) == IntervalSet::empty_interval_set());
-
-            make_decisions_of_schedule(_inertial_schedule, false);
-
-            // Let's make sure the asleep machines are still consistent
-            machines_asleep_soon = (_asleep_machines + _switching_off_machines - _switching_on_machines)
-                                   + _machines_to_sedate - _machines_to_awaken;
-            PPK_ASSERT_ERROR((int)machines_asleep_soon.size() == _nb_machines_sedated_by_inertia +
-                                                                 _nb_machines_sedated_for_being_idle,
-                             "Asleep machines inconsistency. nb_asleep_soon=%d (%s). nb_sedated_inertia=%d. "
-                             "nb_sedated_idle=%d\n",
-                             (int)machines_asleep_soon.size(), machines_asleep_soon.to_string_brackets().c_str(),
-                             _nb_machines_sedated_by_inertia, _nb_machines_sedated_for_being_idle);
-        }
-
-        // Let's now try to sedate the machines which have been idle for too long
-        EnergyBackfillingIdleSleeper::update_idle_states(date, _inertial_schedule, _all_machines,
-                                                         _idle_machines, _machines_idle_start_date);
-        machines_awake_soon = _awake_machines + _switching_on_machines +
-                              _machines_to_awaken - _machines_to_sedate;
-
-        // Guard to prevent switch ON/OFF cycles
-        if (_switching_on_machines.size() == 0 && _machines_to_awaken.size() == 0)
-        {
-            IntervalSet machines_to_sedate_for_being_idle;
-            EnergyBackfillingIdleSleeper::select_idle_machines_to_sedate(date,
-                                            _idle_machines, machines_awake_soon,
-                                            priority_job, _machines_idle_start_date,
-                                            _needed_amount_of_idle_time_to_be_sedated,
-                                            machines_to_sedate_for_being_idle);
-
-            if (machines_to_sedate_for_being_idle.size() > 0)
-            {
-                // Let's handle queue switches
-                IntervalSet machines_sedated_this_turn;
-                IntervalSet machines_awakened_this_turn;
-                IntervalSet empty_range;
-
-                handle_queued_switches(_inertial_schedule, machines_to_sedate_for_being_idle, empty_range,
-                                       machines_sedated_this_turn, machines_awakened_this_turn);
-
-                // A subset of those machines can be sedated (not all of them because it might be jobs
-                // in the future on some resources)
-                PPK_ASSERT_ERROR((machines_sedated_this_turn & machines_to_sedate_for_being_idle) ==
-                                 machines_sedated_this_turn,
-                                 "The sedated machines are not the expected ones.Sedated=%s.\nExpected=subset of %s",
-                                 machines_sedated_this_turn.to_string_brackets().c_str(),
-                                 machines_to_sedate_for_being_idle.to_string_brackets().c_str());
-
-                PPK_ASSERT_ERROR(machines_awakened_this_turn == IntervalSet::empty_interval_set(),
-                                 "The awakened machines are not the expected ones.Awakened=%s.\nExpected=%s",
-                                 machines_awakened_this_turn.to_string_brackets().c_str(),
-                                 IntervalSet::empty_interval_set().to_string_brackets().c_str());
-
-                LOG_F(INFO, "Date=%g. Those machines should be put to sleep now for being idle: %s",
-                           date, machines_sedated_this_turn.to_string_brackets().c_str());
-
-
-                PPK_ASSERT_ERROR((_machines_to_awaken & _machines_to_sedate) == IntervalSet::empty_interval_set());
-
-                if (_inertial_shutdown_debug)
-                {
-                    LOG_F(1, "Date=%g. Before make_decisions_of_schedule. %s",
-                           date, _inertial_schedule.to_string().c_str());
-                    write_schedule_debug("_on_monitoring_before_make_decisions_of_schedule");
-                }
-
-                // Let's finally make the idle decisions!
-                make_decisions_of_schedule(_inertial_schedule, false);
-
-                _nb_machines_sedated_for_being_idle += machines_sedated_this_turn.size();
-                PPK_ASSERT_ERROR(_nb_machines_sedated_for_being_idle <= _nb_machines);
-
-                // Let's make sure the asleep machines are still consistent
-                machines_asleep_soon = (_asleep_machines + _switching_off_machines - _switching_on_machines)
-                                       + _machines_to_sedate - _machines_to_awaken;
-                PPK_ASSERT_ERROR((int)machines_asleep_soon.size() == _nb_machines_sedated_by_inertia +
-                                                                     _nb_machines_sedated_for_being_idle,
-                                 "Asleep machines inconsistency. nb_asleep_soon=%d (%s). nb_sedated_inertia=%d. "
-                                 "nb_sedated_idle=%d\n",
-                                 (int)machines_asleep_soon.size(), machines_asleep_soon.to_string_brackets().c_str(),
-                                 _nb_machines_sedated_by_inertia, _nb_machines_sedated_for_being_idle);
-            }
-        }
-    }
-
-    PPK_ASSERT_ERROR(_nb_machines_sedated_by_inertia <= _nb_machines - nb_machines_to_let_awakened);
-
-    // Let's update the reason why machines are sedated if needed
-    if (_nb_machines_sedated_for_being_idle > nb_machines_to_let_awakened)
-    {
-        int nb_machines_to_transfer = _nb_machines_sedated_for_being_idle - nb_machines_to_let_awakened;
-        PPK_ASSERT_ERROR(nb_machines_to_transfer > 0);
-
-        _nb_machines_sedated_for_being_idle -= nb_machines_to_transfer;
-        _nb_machines_sedated_by_inertia += nb_machines_to_transfer;
-
-        PPK_ASSERT_ERROR(_nb_machines_sedated_for_being_idle >= 0);
-        PPK_ASSERT_ERROR(_nb_machines_sedated_by_inertia <= _nb_machines);
-    }
-
-    PPK_ASSERT_ERROR(_nb_machines_sedated_for_being_idle <= nb_machines_to_let_awakened);
-}
diff --git a/src/algo/energy_bf_machine_subpart_sleeper.hpp b/src/algo/energy_bf_machine_subpart_sleeper.hpp
deleted file mode 100644
index 5c5ddf9fee29ccc659e46837fc080d6f7bb01908..0000000000000000000000000000000000000000
--- a/src/algo/energy_bf_machine_subpart_sleeper.hpp
+++ /dev/null
@@ -1,17 +0,0 @@
-#pragma once
-
-#include "energy_bf_monitoring_inertial_shutdown.hpp"
-
-class EnergyBackfillingMachineSubpartSleeper : public EnergyBackfillingMonitoringInertialShutdown
-{
-public:
-    EnergyBackfillingMachineSubpartSleeper(Workload * workload, SchedulingDecision * decision,
-                                           Queue * queue, ResourceSelector * selector,
-                                           double rjms_delay, rapidjson::Document * variant_options);
-    virtual ~EnergyBackfillingMachineSubpartSleeper();
-
-    virtual void on_monitoring_stage(double date);
-
-private:
-    Rational _fraction_of_machines_to_let_awake;
-};
diff --git a/src/algo/energy_bf_monitoring_inertial_shutdown.cpp b/src/algo/energy_bf_monitoring_inertial_shutdown.cpp
deleted file mode 100644
index 3da4934be937b2fc4f0129044ada05332f18a765..0000000000000000000000000000000000000000
--- a/src/algo/energy_bf_monitoring_inertial_shutdown.cpp
+++ /dev/null
@@ -1,1498 +0,0 @@
-#include "energy_bf_monitoring_inertial_shutdown.hpp"
-#include "easy_bf_plot_liquid_load_horizon.hpp"
-
-#include <boost/regex.hpp>
-
-#include <loguru.hpp>
-
-#include "../pempek_assert.hpp"
-#include "energy_bf_idle_sleeper.hpp"
-
-using namespace std;
-
-EnergyBackfillingMonitoringInertialShutdown::EnergyBackfillingMonitoringInertialShutdown(Workload *workload,
-    SchedulingDecision *decision, Queue *queue, ResourceSelector *selector,
-    double rjms_delay, rapidjson::Document *variant_options) :
-    EnergyBackfillingMonitoringPeriod(workload, decision, queue, selector, rjms_delay, variant_options)
-{
-    PPK_ASSERT_ERROR(variant_options->HasMember("trace_output_filename"),
-                     "Invalid options JSON object: Member 'trace_output_filename' cannot be found");
-    PPK_ASSERT_ERROR((*variant_options)["trace_output_filename"].IsString(),
-            "Invalid options JSON object: Member 'trace_output_filename' must be a string");
-    string trace_output_filename = (*variant_options)["trace_output_filename"].GetString();
-
-    _output_file.open(trace_output_filename);
-    PPK_ASSERT_ERROR(_output_file.is_open(), "Couldn't open file %s", trace_output_filename.c_str());
-
-    string buf = "date,nb_jobs_in_queue,first_job_size,priority_job_expected_waiting_time,load_in_queue,liquid_load_horizon\n";
-    _output_file.write(buf.c_str(), buf.size());
-
-    if (variant_options->HasMember("allow_future_switches"))
-    {
-        PPK_ASSERT_ERROR((*variant_options)["allow_future_switches"].IsBool(),
-                         "Invalid options JSON object: Member 'allow_future_switches' must be a boolean");
-
-        _allow_future_switches = (*variant_options)["allow_future_switches"].GetBool();
-    }
-
-    if (variant_options->HasMember("upper_llh_threshold"))
-    {
-        PPK_ASSERT_ERROR((*variant_options)["upper_llh_threshold"].IsNumber(),
-                         "Invalid options JSON object: Member 'upper_llh_threshold' must be a number");
-        _upper_llh_threshold = (*variant_options)["upper_llh_threshold"].GetDouble();
-
-        PPK_ASSERT_ERROR(_upper_llh_threshold >= 0,
-                         "Invalid options JSON object: Member 'upper_llh_threshold' must be non-negative.");
-    }
-
-    if (variant_options->HasMember("inertial_alteration"))
-    {
-        PPK_ASSERT_ERROR((*variant_options)["inertial_alteration"].IsString(),
-                         "Invalid options JSON object: Member 'inertial_alteration' must be a string");
-
-        string inertial_alteration = (*variant_options)["inertial_alteration"].GetString();
-
-        boost::regex r("\\s*(x|p)\\s*(\\d+|\\d+\\.\\d+)\\s*");
-
-        boost::match_results<std::string::const_iterator> results;
-        bool matched = boost::regex_match(inertial_alteration, results, r);
-        PPK_ASSERT_ERROR(matched, "Invalid options JSON object: Member 'inertial_alteration' has an invalid format");
-
-        string alteration_type_string = results[1];
-        string alteration_number_string = results[2];
-
-        PPK_ASSERT_ERROR(alteration_type_string.size() == 1);
-        char alteration_type_char = alteration_type_string[0];
-        double alteration_number = std::stod(alteration_number_string);
-
-        if (alteration_type_char == 'p')
-            _alteration_type = SUM;
-        else if (alteration_type_char == 'x')
-            _alteration_type = PRODUCT;
-        else
-            PPK_ASSERT_ERROR(false);
-
-        PPK_ASSERT_ERROR(alteration_number >= 0,
-                         "Invalid options JSON object: Member 'inertial_alteration' "
-                         "has an invalid value ('%s' -> %g)",
-                         alteration_number_string.c_str(),
-                         alteration_number);
-        _inertial_alteration_number = alteration_number;
-    }
-
-    if (variant_options->HasMember("idle_time_to_sedate"))
-    {
-        _needed_amount_of_idle_time_to_be_sedated = (*variant_options)["idle_time_to_sedate"].GetDouble();
-
-        PPK_ASSERT_ERROR(_needed_amount_of_idle_time_to_be_sedated >= 0,
-                         "Invalid options JSON object: Member 'idle_time_to_sedate' "
-                         "has an invalid value (%g)", _needed_amount_of_idle_time_to_be_sedated);
-    }
-
-    if (variant_options->HasMember("sedate_idle_on_classical_events"))
-    {
-        _sedate_idle_on_classical_events = (*variant_options)["sedate_idle_on_classical_events"].GetBool();
-    }
-
-    LOG_SCOPE_FUNCTION(INFO);
-    LOG_F(INFO, "needed amount of idle time to be sedated: %g", _needed_amount_of_idle_time_to_be_sedated);
-    LOG_F(INFO, "Sedate on classical events: %s", _sedate_idle_on_classical_events ? "true" : "false");
-}
-
-void EnergyBackfillingMonitoringInertialShutdown::on_simulation_start(double date, const rapidjson::Value & batsim_config)
-{
-    EnergyBackfillingMonitoringPeriod::on_simulation_start(date, batsim_config);
-
-    _inertial_schedule = _schedule;
-
-    for (int i = 0; i < _nb_machines; ++i)
-        _machines_idle_start_date[i] = date;
-
-    _idle_machines = _all_machines;
-}
-// break energy_bf_monitoring_inertial_shutdown.cpp:119 if date >= 3300
-void EnergyBackfillingMonitoringInertialShutdown::make_decisions(double date,
-                                                                 SortableJobOrder::UpdateInformation * update_info,
-                                                                 SortableJobOrder::CompareInformation * compare_info)
-{
-    PPK_ASSERT_ERROR(_nb_machines_sedated_for_being_idle >= 0 &&
-                     _nb_machines_sedated_for_being_idle <= (int)_all_machines.size(),
-                     "Invalid nb_machines_sedated_for_being_idle value: %d\n",
-                     _nb_machines_sedated_for_being_idle);
-
-    if (!_jobs_ended_recently.empty())
-    {
-        // Let's remove finished jobs from the schedule
-        for (const string & ended_job_id : _jobs_ended_recently)
-        {
-            const Job * ended_job = (*_workload)[ended_job_id];
-            ++_nb_jobs_completed;
-
-            PPK_ASSERT_ERROR(_schedule.contains_job(ended_job),
-                             "Invalid schedule: job '%s' just finished, "
-                             "but it not in the schedule...\n%s",
-                             ended_job_id.c_str(), _schedule.to_string().c_str());
-            PPK_ASSERT_ERROR(!_queue->contains_job(ended_job),
-                             "Job '%s' just ended, but it is still in the "
-                             "queue...\nQueue : %s",
-                             ended_job_id.c_str(),
-                             _queue->to_string().c_str());
-
-            // Let's remove the finished job from the schedule
-            _schedule.remove_job(ended_job);
-        }
-
-        // Stop sending CALL_ME_LATER if all jobs have been executed.
-        if (_no_more_static_job_to_submit_received &&
-            _queue->is_empty() &&
-            !EnergyBackfilling::contains_any_nonfake_job(_schedule))
-            _stop_sending_call_me_later = true;
-    }
-
-    // Let's update the first slice of the schedule
-    update_first_slice_taking_sleep_jobs_into_account(date);
-
-    // We can now (after updating the first slice AND before adding new jobs into the queue),
-    // compute a  LLH value to know how much the LLH decreased since the last computation.
-    Rational llh = EasyBackfillingPlotLiquidLoadHorizon::compute_liquid_load_horizon(_inertial_schedule,
-                                                                                     _queue, date);
-
-    Rational trapezoid_area = ((_last_llh_value + llh) / 2) * (date - _last_llh_date);
-    PPK_ASSERT_ERROR(trapezoid_area >= 0,
-                     "Invalid area computed (%g): Cannot be negative.",
-                     (double) trapezoid_area);
-
-    // In order to be visualized properly, this value is stored as date-epsilon
-    Rational time_diff_from_last_llh_computation = date - _last_llh_date;
-
-    if (time_diff_from_last_llh_computation > 0)
-    {
-        Rational epsilon = min(Rational(1e-6), time_diff_from_last_llh_computation / 2);
-        if (_write_output_file)
-        {
-            int first_job_size = -1;
-            const Job * first_job = _queue->first_job_or_nullptr();
-            if (first_job != nullptr)
-                first_job_size = first_job->nb_requested_resources;
-
-            write_output_file((double)(Rational(date) - epsilon), _queue->nb_jobs(),
-                              first_job_size,
-                              (double) _queue->compute_load_estimation(),
-                              (double) llh);
-        }
-    }
-
-    _llh_integral_since_last_monitoring_stage += trapezoid_area;
-    _last_llh_value = llh;
-    _last_llh_date = date;
-
-    // Let's handle recently released jobs
-    for (const string & new_job_id : _jobs_released_recently)
-    {
-        const Job * new_job = (*_workload)[new_job_id];
-        PPK_ASSERT_ERROR(new_job->has_walltime,
-                         "This scheduler only supports jobs with walltimes.");
-        ++_nb_jobs_submitted;
-
-        PPK_ASSERT_ERROR(!_schedule.contains_job(new_job),
-                         "Invalid schedule: job '%s' already exists.\n%s",
-                         new_job->id.c_str(), _schedule.to_string().c_str());
-        PPK_ASSERT_ERROR(!_queue->contains_job(new_job),
-                         "Job '%s' is already in the queue!\nQueue:%s",
-                         new_job->id.c_str(), _queue->to_string().c_str());
-
-        if (new_job->nb_requested_resources > _nb_machines)
-        {
-            _decision->add_reject_job(new_job_id, date);
-            ++_nb_jobs_completed;
-        }
-        else
-            _queue->append_job(new_job, update_info);
-    }
-
-    // Let's update the sorting of the queue
-    _queue->sort_queue(update_info, compare_info);
-
-    // Simple Easy Backfilling
-    _inertial_schedule = _schedule;
-    const Job * priority_job = nullptr;
-    IntervalSet priority_job_reserved_machines;
-    bool priority_job_can_be_started_soon = true;
-
-    Rational time_to_wake_up = (*_variant_options)["time_switch_on"].GetDouble();
-    Rational soon_horizon = time_to_wake_up * 2 + date;
-
-    if (_inertial_shutdown_debug)
-    {
-        LOG_SCOPE_FUNCTION(1);
-        LOG_F(1, "Date=%g. Beginning of make_decisions. Queue: %s.\n%s",
-               date, _queue->to_string().c_str(), _inertial_schedule.to_string().c_str());
-        write_schedule_debug("_make_decisions_begin");
-    }
-    else
-    {
-        LOG_SCOPE_FUNCTION(INFO);
-    }
-
-    set<const Job *> allocated_jobs;
-
-    IntervalSet machines_sedated_this_turn, machines_awakened_this_turn;
-    handle_queued_switches(_inertial_schedule, _machines_to_sedate, _machines_to_awaken,
-                           machines_sedated_this_turn, machines_awakened_this_turn);
-
-    if (_queue->is_empty())
-    {
-        _machines_to_sedate -= machines_sedated_this_turn;
-        _machines_to_awaken -= machines_awakened_this_turn;
-
-        _priority_job_starting_time_expectancy = date;
-    }
-    else
-    {
-        bool priority_job_launched_now = true;
-
-        auto job_it = _queue->begin();
-        while (priority_job_launched_now && job_it != _queue->end())
-        {
-            const Job * job = (*job_it)->job;
-            priority_job = job;
-
-            if (_inertial_shutdown_debug)
-                LOG_F(1, "Date=%g. make_decisions, priority loop, trying to insert priority job '%s'.%s",
-                       date, priority_job->id.c_str(), _inertial_schedule.to_string().c_str());
-
-            Schedule::JobAlloc alloc = _inertial_schedule.add_job_first_fit(priority_job, _selector, false);
-
-            if (alloc.has_been_inserted)
-            {
-                priority_job_reserved_machines = alloc.used_machines;
-
-                if (alloc.started_in_first_slice)
-                {
-                    priority_job = nullptr;
-                    priority_job_reserved_machines.clear();
-                    _priority_job_starting_time_expectancy = alloc.begin;
-
-                    priority_job_launched_now = true;
-                    allocated_jobs.insert(job);
-                }
-                else
-                {
-                    priority_job_launched_now = false;
-
-                    _priority_job_starting_time_expectancy = compute_priority_job_starting_time_expectancy(_inertial_schedule, priority_job);
-                    priority_job_can_be_started_soon = _priority_job_starting_time_expectancy <= soon_horizon;
-                    priority_job_can_be_started_soon = true; // REMOVEME. Forces the previous behaviour.
-                }
-            }
-            else
-            {
-                priority_job_launched_now = false;
-
-                // The priority job couldn't be inserted into the Schedule... It means some machines must be awakened first.
-
-                // Before doing anything else, let's compute when the priority job would start if all machines were to be awakened.
-                _priority_job_starting_time_expectancy = compute_priority_job_starting_time_expectancy(_inertial_schedule, priority_job);
-                priority_job_can_be_started_soon = _priority_job_starting_time_expectancy <= soon_horizon;
-                priority_job_can_be_started_soon = true; // REMOVEME. Forces the previous behaviour.
-
-                // If the job can be started "soon", we must make sure is is runnable.
-                if (priority_job_can_be_started_soon)
-                {
-                    // Let's first check whether this was caused by a decision made this turn, so we can cancel the decision before applying it.
-                    // To do so, we'll first remove the fake jobs of the machines which have been switched OFF this turn, hopefully to create empty room
-                    // for the priority job
-                    LOG_F(INFO, "In order to make priority job '%s' fit, canceling the switches OFF of machines %s",
-                           priority_job->id.c_str(),
-                           _machines_to_sedate.to_string_brackets().c_str());
-
-                    for (auto mit = _machines_to_sedate.elements_begin(); mit != _machines_to_sedate.elements_end(); ++mit)
-                    {
-                        int machine_id = *mit;
-                        MachineInformation * minfo = _machine_informations[machine_id];
-
-                        _inertial_schedule.remove_job_last_occurence(minfo->switch_off_job);
-                        if (minfo->ensured_sleep_job->walltime > 0)
-                            _inertial_schedule.remove_job_last_occurence(minfo->ensured_sleep_job);
-                        _inertial_schedule.remove_job_last_occurence(minfo->potential_sleep_job);
-                    }
-
-                    alloc = _inertial_schedule.add_job_first_fit(priority_job, _selector, false);
-                    if (alloc.has_been_inserted)
-                    {
-                        // The job could fit by only cancelling some switches OFF \o/
-                        // Let's perserve the switches OFF that do not disturb the priority job.
-                        IntervalSet non_disturbing_machines_switches_off = _machines_to_sedate - alloc.used_machines;
-                        IntervalSet disturbing_machines_switches_off = (_machines_to_sedate & alloc.used_machines);
-
-                        // The machines sedated for being idle should never be done in the future, so
-                        // cancelled switches OFF are inertial ones. However, for coherency's sake,
-                        // the number of idle-sedated machines might also be decreased if there is no
-                        // inertially-sedated machines left.
-                        int nb_cancelled_switches_off = (int) disturbing_machines_switches_off.size();
-                        int nb_cancelled_inertially_sedated_machines = min(nb_cancelled_switches_off,
-                                                                           _nb_machines_sedated_by_inertia);
-
-                        int nb_cancelled_idle_sedated_machines = 0;
-                        if (nb_cancelled_inertially_sedated_machines < nb_cancelled_switches_off)
-                            nb_cancelled_idle_sedated_machines = nb_cancelled_switches_off -
-                                                                 nb_cancelled_inertially_sedated_machines;
-
-                        PPK_ASSERT_ERROR(nb_cancelled_inertially_sedated_machines +
-                                         nb_cancelled_idle_sedated_machines == nb_cancelled_switches_off);
-
-                        _nb_machines_sedated_by_inertia -= nb_cancelled_inertially_sedated_machines;
-                        _nb_machines_sedated_for_being_idle -= nb_cancelled_idle_sedated_machines;
-
-                        PPK_ASSERT_ERROR(_nb_machines_sedated_by_inertia >= 0);
-                        PPK_ASSERT_ERROR(_nb_machines_sedated_for_being_idle >= 0);
-
-                        LOG_F(INFO, "The priority job '%s' could be inserted by cancelling some switches OFF (%s). "
-                               "Let's reinsert a subpart of these switches off : %s",
-                               priority_job->id.c_str(),
-                               disturbing_machines_switches_off.to_string_brackets().c_str(),
-                               non_disturbing_machines_switches_off.to_string_brackets().c_str());
-
-                        // Let's put these machines to sleep.
-                        IntervalSet thrash, machines_sedated_this_turn_tmp, empty_range;
-                        handle_queued_switches(_inertial_schedule, non_disturbing_machines_switches_off,
-                                               empty_range, machines_sedated_this_turn_tmp, thrash);
-
-                        PPK_ASSERT_ERROR((machines_sedated_this_turn_tmp &
-                                          non_disturbing_machines_switches_off) == machines_sedated_this_turn_tmp,
-                                         "The machines that have been sedated are not the expected ones.\n"
-                                         "sedated=%s\nexpected=subset of %s",
-                                         machines_sedated_this_turn_tmp.to_string_brackets().c_str(),
-                                         non_disturbing_machines_switches_off.to_string_brackets().c_str());
-
-                        PPK_ASSERT_ERROR(thrash == IntervalSet::empty_interval_set(),
-                                         "The machines that have been awakeend by this call are not the "
-                                         "expected ones.\nawakened=%s\nexpected=%s",
-                                         thrash.to_string_elements().c_str(),
-                                         IntervalSet::empty_interval_set().to_string_brackets().c_str());
-
-                        machines_sedated_this_turn -= disturbing_machines_switches_off;
-                        _machines_to_sedate -= disturbing_machines_switches_off;
-                    }
-                    else
-                    {
-                        LOG_F(INFO, "Cancelling some switches OFF was not enough... Some machines must be awakened.");
-
-                        // Cancelling some switches OFF was not enough... Some machines must be awakened.
-                        // Let's determine how many of them should be awakened.
-                        IntervalSet machines_awake_in_the_prediction_schedule = _awake_machines +
-                                _switching_on_machines + _machines_to_awaken; // no machines to sedate, because they were already canceled
-
-                        if (_inertial_shutdown_debug)
-                        {
-                            LOG_F(1, "_awake_machines: %s", _awake_machines.to_string_brackets().c_str());
-                            LOG_F(1, "_switching_on_machines: %s", _switching_on_machines.to_string_brackets().c_str());
-                            LOG_F(1, "_switching_off_machines: %s", _switching_off_machines.to_string_brackets().c_str());
-                            LOG_F(1, "_machines_to_awaken: %s", _machines_to_awaken.to_string_brackets().c_str());
-                            LOG_F(1, "_machines_to_sedate: %s", _machines_to_sedate.to_string_brackets().c_str());
-
-                            LOG_F(1, "Awake machines in prediction schedule: %s (size=%d)",
-                                   machines_awake_in_the_prediction_schedule.to_string_brackets().c_str(),
-                                   (int)machines_awake_in_the_prediction_schedule.size());
-                        }
-
-                        int minimum_nb_machines_to_awaken = job->nb_requested_resources - (int)machines_awake_in_the_prediction_schedule.size();
-                        PPK_ASSERT_ERROR(minimum_nb_machines_to_awaken > 0,
-                                         "Schedule seems to be inconsistent.\n"
-                                         "job->nb_requested_resources=%d. machines_awake_in_the_prediction_schedule=%d\n"
-                                         "awake machines: %s. machines being switched ON: %s. Machines to awaken:%s\n%s",
-                                         job->nb_requested_resources,
-                                         (int)machines_awake_in_the_prediction_schedule.size(),
-                                         _awake_machines.to_string_brackets().c_str(),
-                                         _switching_on_machines.to_string_brackets().c_str(),
-                                         _machines_to_awaken.to_string_brackets().c_str(),
-                                         _inertial_schedule.to_string().c_str());
-
-                        LOG_F(INFO, "Date=%g. make_decisions. Would like to awaken %d machines to execute job '%s', "
-                               "which requests %d resources.",
-                               date, minimum_nb_machines_to_awaken, priority_job->id.c_str(),
-                               priority_job->nb_requested_resources);
-
-                        // Let's select which machines should be awakened
-                        IntervalSet machines_to_awaken_to_make_priority_job_fit;
-                        select_machines_to_awaken(minimum_nb_machines_to_awaken, _asleep_machines + _switching_off_machines,
-                                                  machines_to_awaken_to_make_priority_job_fit);
-
-                        // Let's awaken the machines in the schedule
-                        IntervalSet thrash, machines_really_awakened_to_make_priority_job_fit;
-                        handle_queued_switches(_inertial_schedule, IntervalSet(),
-                                               machines_to_awaken_to_make_priority_job_fit,
-                                               thrash, machines_really_awakened_to_make_priority_job_fit);
-                        PPK_ASSERT_ERROR(thrash == IntervalSet::empty_interval_set(),
-                                         "The machines that have been sedated by this call are not the "
-                                         "expected ones.\nsedated=%s\nexpected=%s",
-                                         thrash.to_string_elements().c_str(),
-                                         IntervalSet::empty_interval_set().to_string_brackets().c_str());
-                        PPK_ASSERT_ERROR((machines_really_awakened_to_make_priority_job_fit &
-                                          machines_to_awaken_to_make_priority_job_fit) ==
-                                         machines_really_awakened_to_make_priority_job_fit,
-                                         "The machines that have been awakened by this call are not the"
-                                         "expected ones.\nawakened=%s\nexpected=subset of %s",
-                                         machines_really_awakened_to_make_priority_job_fit.to_string_brackets().c_str(),
-                                         machines_to_awaken_to_make_priority_job_fit.to_string_brackets().c_str());
-
-                        // Now the priority job should fit the platform. Let's insert it into it
-                        alloc = _inertial_schedule.add_job_first_fit(priority_job, _selector, false);
-                        PPK_ASSERT_ERROR(alloc.has_been_inserted,
-                                         "Cannot insert the priority job, which should not happen now! "
-                                         "priority_job='%s', nb_res=%d\n%s",
-                                         priority_job->id.c_str(), priority_job->nb_requested_resources,
-                                         _inertial_schedule.to_string().c_str());
-                        PPK_ASSERT_ERROR(alloc.begin > _inertial_schedule.first_slice_begin());
-
-                        // Let's update which machines are sedated now.
-                        // The machines sedated for being idle should never be done in the future, so
-                        // cancelled switches OFF and newly awakened machines are inertial ones.
-                        // However, for coherency's sake,
-                        // the number of idle-sedated machines might also be decreased if there is no
-                        // inertially-sedated machines left.
-                        int nb_cancelled_switches_off = (int)_machines_to_sedate.size();
-                        int nb_cancelled_inertially_sedated_machines = min(nb_cancelled_switches_off,
-                                                                           _nb_machines_sedated_by_inertia);
-
-                        int nb_cancelled_idle_sedated_machines = 0;
-                        if (nb_cancelled_inertially_sedated_machines < nb_cancelled_switches_off)
-                            nb_cancelled_idle_sedated_machines = nb_cancelled_switches_off -
-                                                                 nb_cancelled_inertially_sedated_machines;
-
-                        PPK_ASSERT_ERROR(nb_cancelled_inertially_sedated_machines +
-                                         nb_cancelled_idle_sedated_machines == nb_cancelled_switches_off);
-
-                        _nb_machines_sedated_by_inertia -= nb_cancelled_inertially_sedated_machines;
-                        _nb_machines_sedated_for_being_idle -= nb_cancelled_idle_sedated_machines;
-
-                        PPK_ASSERT_ERROR(_nb_machines_sedated_by_inertia >= 0);
-                        PPK_ASSERT_ERROR(_nb_machines_sedated_for_being_idle >= 0);
-
-                        // Update after awakenings
-                        int nb_awakened_machines = (int) machines_to_awaken_to_make_priority_job_fit.size();
-                        int nb_awakened_inertially_sedated_machines = min(nb_awakened_machines,
-                                                                          _nb_machines_sedated_by_inertia);
-
-                        int nb_awakened_idle_sedated_machines = 0;
-                        if (nb_awakened_inertially_sedated_machines < nb_awakened_machines)
-                            nb_awakened_idle_sedated_machines = nb_awakened_machines -
-                                                                nb_awakened_inertially_sedated_machines;
-
-                        PPK_ASSERT_ERROR(nb_awakened_idle_sedated_machines +
-                                         nb_awakened_inertially_sedated_machines == nb_awakened_machines);
-
-                        _nb_machines_sedated_by_inertia -= nb_awakened_inertially_sedated_machines;
-                        _nb_machines_sedated_for_being_idle -= nb_awakened_idle_sedated_machines;
-
-                        PPK_ASSERT_ERROR(_nb_machines_sedated_by_inertia >= 0);
-                        PPK_ASSERT_ERROR(_nb_machines_sedated_for_being_idle >= 0);
-
-                        machines_sedated_this_turn -= _machines_to_sedate;
-                        _machines_to_sedate.clear();
-                        machines_awakened_this_turn += machines_really_awakened_to_make_priority_job_fit;
-                        _machines_to_awaken += (machines_to_awaken_to_make_priority_job_fit - machines_really_awakened_to_make_priority_job_fit);
-                    }
-                }
-            }
-
-            job_it++;
-        } // end of priority job management loop
-
-        _machines_to_sedate -= machines_sedated_this_turn;
-        _machines_to_awaken -= machines_awakened_this_turn;
-        _machines_sedated_since_last_monitoring_stage_inertia += machines_sedated_this_turn;
-        _machines_awakened_since_last_monitoring_stage_inertia += machines_awakened_this_turn;
-
-        PPK_ASSERT_ERROR((_machines_to_awaken & _machines_to_sedate) == IntervalSet::empty_interval_set(),
-                         "The machines to awaken and those to sedate should be distinct...\n"
-                         "machines_to_awaken=%s\nmachines_to_sedate=%s",
-                         _machines_to_awaken.to_string_brackets().c_str(),
-                         _machines_to_sedate.to_string_brackets().c_str());
-
-        if (machines_sedated_this_turn.size() > 0)
-            LOG_F(INFO, "Date=%g. Those machines should be put to sleep now: %s", date,
-                   machines_sedated_this_turn.to_string_brackets().c_str());
-
-        if (machines_awakened_this_turn.size() > 0)
-            LOG_F(INFO, "Date=%g. Those machines should be awakened now: %s", date,
-                   machines_awakened_this_turn.to_string_brackets().c_str());
-
-        if (_inertial_shutdown_debug)
-        {
-            LOG_F(1, "Date=%g. After priority job loop. %s",
-                   date, _inertial_schedule.to_string().c_str());
-            write_schedule_debug("_make_decisions_after_priority_job_loop");
-        }
-
-        int nb_machines_available_now = (int) _inertial_schedule.begin()->available_machines.size();
-
-        job_it = _queue->begin();
-        while (job_it != _queue->end() && nb_machines_available_now > 0)
-        {
-            const Job * job = (*job_it)->job;
-            if (job != priority_job && // Not the priority job
-                allocated_jobs.count(job) == 0 && // Not already scheduled
-                job->nb_requested_resources <= nb_machines_available_now) // Thin enough to fit the first hole
-            {
-                Schedule::JobAlloc alloc = _inertial_schedule.add_job_first_fit(job, _selector, false);
-                if (alloc.has_been_inserted)
-                {
-                    if (alloc.started_in_first_slice)
-                    {
-                        allocated_jobs.insert(job);
-                        nb_machines_available_now -= job->nb_requested_resources;
-                        PPK_ASSERT_ERROR(nb_machines_available_now >= 0);
-                    }
-                    else
-                        _inertial_schedule.remove_job(job);
-                }
-            }
-
-            job_it++;
-        }
-    }
-
-    if (_inertial_shutdown_debug)
-    {
-        LOG_F(1, "Date=%g. End of make_decisions. %s", date, _inertial_schedule.to_string().c_str());
-        write_schedule_debug("_make_decisions_end");
-    }
-
-    // Let's make the first decision parts (executing new jobs / awakening some machines for the priority job)
-    make_decisions_of_schedule(_inertial_schedule, false);
-
-    IntervalSet machines_asleep_soon = (_asleep_machines + _switching_off_machines - _switching_on_machines)
-                                        + _machines_to_sedate - _machines_to_awaken;
-    PPK_ASSERT_ERROR((int)machines_asleep_soon.size() == _nb_machines_sedated_by_inertia +
-                                                         _nb_machines_sedated_for_being_idle,
-                     "Asleep machines inconsistency. nb_asleep_soon=%d (%s). nb_sedated_inertia=%d. "
-                     "nb_sedated_idle=%d\n",
-                     (int)machines_asleep_soon.size(), machines_asleep_soon.to_string_brackets().c_str(),
-                     _nb_machines_sedated_by_inertia, _nb_machines_sedated_for_being_idle);
-
-    // Let's make sure all the jobs we marked as executed were removed from the queue
-    for (const Job * allocated_job : allocated_jobs)
-        PPK_ASSERT_ERROR(!_queue->contains_job(allocated_job),
-                         "Inconsistency: job '%s' is marked as allocated but it has not "
-                         "been removed from the queue.", allocated_job->id.c_str());
-
-    // Let's awake sedated idle machines if needed
-    EnergyBackfillingIdleSleeper::update_idle_states(date, _inertial_schedule, _all_machines,
-                                                     _idle_machines, _machines_idle_start_date);
-
-    IntervalSet machines_to_awaken_for_being_idle;
-    EnergyBackfillingIdleSleeper::select_idle_machines_to_awaken(_queue,
-        _inertial_schedule, _selector,
-        _idle_machines,
-        EnergyBackfillingIdleSleeper::AwakeningPolicy::AWAKEN_FOR_ALL_JOBS_RESPECTING_PRIORITY_JOB,
-        _nb_machines_sedated_for_being_idle,
-        machines_to_awaken_for_being_idle,
-        true); // <--------------------------------------------------------------------------------- Choice to make.
-
-    if (machines_to_awaken_for_being_idle.size() > 0)
-    {
-        _machines_to_awaken += machines_to_awaken_for_being_idle;
-
-        // The awakened machines are the previously idle ones
-        _nb_machines_sedated_for_being_idle -= machines_to_awaken_for_being_idle.size();
-        PPK_ASSERT_ERROR(_nb_machines_sedated_for_being_idle >= 0,
-                         "Invalid nb_machines_sedated_for_being_idle value: %d\n",
-                         _nb_machines_sedated_for_being_idle);
-
-        IntervalSet machines_sedated_this_turn, machines_awakened_this_turn, empty_range;
-        machines_sedated_this_turn.clear();
-        machines_awakened_this_turn.clear();
-        handle_queued_switches(_inertial_schedule, empty_range, machines_to_awaken_for_being_idle,
-                               machines_sedated_this_turn, machines_awakened_this_turn);
-
-        PPK_ASSERT_ERROR(machines_awakened_this_turn == machines_to_awaken_for_being_idle,
-                         "Unexpected awakened machines.\n Awakened=%s.\nExpected=%s.",
-                         machines_awakened_this_turn.to_string_brackets().c_str(),
-                         machines_to_awaken_for_being_idle.to_string_brackets().c_str());
-
-        PPK_ASSERT_ERROR(machines_sedated_this_turn == IntervalSet::empty_interval_set(),
-                         "The sedated machines are not the expected ones.Sedated=%s.\nExpected=%s",
-                         machines_sedated_this_turn.to_string_brackets().c_str(),
-                         IntervalSet::empty_interval_set().to_string_brackets().c_str());
-
-        LOG_F(INFO, "Date=%g. Those machines should be awakened now (previously idle ones): %s",
-               date, machines_awakened_this_turn.to_string_brackets().c_str());
-
-        _machines_to_awaken -= machines_awakened_this_turn;
-
-        PPK_ASSERT_ERROR((_machines_to_awaken & _machines_to_sedate) == IntervalSet::empty_interval_set());
-
-        // Let's make the new decisions (switches ON)!
-        make_decisions_of_schedule(_inertial_schedule, false);
-
-        machines_asleep_soon = (_asleep_machines + _switching_off_machines - _switching_on_machines)
-                               + _machines_to_sedate - _machines_to_awaken;
-        PPK_ASSERT_ERROR((int)machines_asleep_soon.size() == _nb_machines_sedated_by_inertia +
-                                                             _nb_machines_sedated_for_being_idle,
-                         "Asleep machines inconsistency. nb_asleep_soon=%d (%s). nb_sedated_inertia=%d. "
-                         "nb_sedated_idle=%d\n",
-                         (int)machines_asleep_soon.size(), machines_asleep_soon.to_string_brackets().c_str(),
-                         _nb_machines_sedated_by_inertia, _nb_machines_sedated_for_being_idle);
-    }
-    else if (_sedate_idle_on_classical_events &&
-             // Guard to prevent switch ON/OFF cycles
-             _switching_on_machines.size() == 0 && _machines_to_awaken.size() == 0)
-    {
-        // If no machine has been awakened for being idle AND
-        // if we should sedate on classical events AND
-        // if no machine should be awakened (currently or in the future),
-        // we can try to sedate idle machines now.
-
-        // Let's try to sedate the machines which have been idle for too long
-        EnergyBackfillingIdleSleeper::update_idle_states(date, _inertial_schedule, _all_machines,
-                                                         _idle_machines, _machines_idle_start_date);
-
-        IntervalSet machines_awake_soon = (_awake_machines + _switching_on_machines - _switching_off_machines)
-                                           + _machines_to_awaken - _machines_to_sedate;
-
-        IntervalSet machines_to_sedate_for_being_idle;
-        EnergyBackfillingIdleSleeper::select_idle_machines_to_sedate(date,
-                                        _idle_machines, machines_awake_soon,
-                                        priority_job, _machines_idle_start_date,
-                                        _needed_amount_of_idle_time_to_be_sedated,
-                                        machines_to_sedate_for_being_idle,
-                                        true); // <------------------------------------------------- Choice to make.
-
-        if (machines_to_sedate_for_being_idle.size() > 0)
-        {
-            // Let's handle queue switches
-            IntervalSet empty_range;
-            machines_sedated_this_turn.clear();
-            machines_awakened_this_turn.clear();
-            handle_queued_switches(_inertial_schedule, machines_to_sedate_for_being_idle, empty_range,
-                                   machines_sedated_this_turn, machines_awakened_this_turn);
-
-
-            PPK_ASSERT_ERROR((machines_sedated_this_turn & machines_to_sedate_for_being_idle) ==
-                             machines_sedated_this_turn,
-                             "The sedated machines are not the expected ones.Sedated=%s.\nExpected=subset of %s",
-                             machines_sedated_this_turn.to_string_brackets().c_str(),
-                             machines_to_sedate_for_being_idle.to_string_brackets().c_str());
-
-            PPK_ASSERT_ERROR(machines_awakened_this_turn == IntervalSet::empty_interval_set(),
-                             "The awakened machines are not the expected ones.Awakened=%s.\nExpected=%s",
-                             machines_awakened_this_turn.to_string_brackets().c_str(),
-                             IntervalSet::empty_interval_set().to_string_brackets().c_str());
-
-            LOG_F(INFO, "Date=%g. Those machines should be put to sleep now for being idle: %s",
-                       date, machines_sedated_this_turn.to_string_brackets().c_str());
-
-            PPK_ASSERT_ERROR((_machines_to_awaken & _machines_to_sedate) == IntervalSet::empty_interval_set());
-
-            if (_inertial_shutdown_debug)
-            {
-                LOG_F(1, "Date=%g. Before make_decisions_of_schedule. %s",
-                       date, _inertial_schedule.to_string().c_str());
-                write_schedule_debug("_on_monitoring_before_make_decisions_of_schedule");
-            }
-
-            // Let's finally make the decisions!
-            make_decisions_of_schedule(_inertial_schedule, false);
-
-            _nb_machines_sedated_for_being_idle += machines_sedated_this_turn.size();
-            PPK_ASSERT_ERROR(_nb_machines_sedated_for_being_idle <= (int)_all_machines.size());
-        }
-    }
-
-    // Now that the decisions have been made, let's compute the LLH again.
-    llh = EasyBackfillingPlotLiquidLoadHorizon::compute_liquid_load_horizon(_inertial_schedule,
-                                                                            _queue, date);
-    if (_write_output_file)
-    {
-        int first_job_size = -1;
-        const Job * first_job = _queue->first_job_or_nullptr();
-        if (first_job != nullptr)
-            first_job_size = first_job->nb_requested_resources;
-
-        write_output_file(date, _queue->nb_jobs(),
-                          first_job_size,
-                          (double) _queue->compute_load_estimation(),
-                          (double) llh);
-    }
-
-    _last_llh_value = llh;
-    _last_llh_date = date;
-
-    machines_asleep_soon = (_asleep_machines + _switching_off_machines - _switching_on_machines)
-                           + _machines_to_sedate - _machines_to_awaken;
-    PPK_ASSERT_ERROR((int)machines_asleep_soon.size() == _nb_machines_sedated_by_inertia +
-                                                         _nb_machines_sedated_for_being_idle,
-                     "Asleep machines inconsistency. nb_asleep_soon=%d (%s). nb_sedated_inertia=%d. "
-                     "nb_sedated_idle=%d\n",
-                     (int)machines_asleep_soon.size(), machines_asleep_soon.to_string_brackets().c_str(),
-                     _nb_machines_sedated_by_inertia, _nb_machines_sedated_for_being_idle);
-}
-
-
-
-
-
-
-
-// break energy_bf_monitoring_inertial_shutdown.cpp:691 if date >= 3600
-void EnergyBackfillingMonitoringInertialShutdown::on_monitoring_stage(double date)
-{
-    PPK_ASSERT_ERROR(_nb_machines_sedated_for_being_idle >= 0 &&
-                     _nb_machines_sedated_for_being_idle <= (int)_all_machines.size(),
-                     "Invalid nb_machines_sedated_for_being_idle value: %d\n",
-                     _nb_machines_sedated_for_being_idle);
-    LOG_SCOPE_FUNCTION(INFO);
-
-    // Let's update the first slice of the schedule
-    update_first_slice_taking_sleep_jobs_into_account(date);
-
-    // Let's compute a first LLH value
-    Rational llh = EasyBackfillingPlotLiquidLoadHorizon::compute_liquid_load_horizon(_inertial_schedule,
-                                                                                     _queue, date);
-
-    Rational trapezoid_area = ((_last_llh_value + llh) / 2) * (date - _last_llh_date);
-    PPK_ASSERT_ERROR(trapezoid_area >= 0,
-                     "Invalid area computed (%g): Cannot be negative.",
-                     (double) trapezoid_area);
-
-    // In order to be visualized properly, this value is stored as date-epsilon
-    Rational time_diff_from_last_llh_computation = date - _last_llh_date;
-
-    if (time_diff_from_last_llh_computation > 0)
-    {
-        Rational epsilon = min(Rational(1e-6), time_diff_from_last_llh_computation / 2);
-        if (_write_output_file)
-        {
-            int first_job_size = -1;
-            const Job * first_job = _queue->first_job_or_nullptr();
-            if (first_job != nullptr)
-                first_job_size = first_job->nb_requested_resources;
-
-            write_output_file((double)(Rational(date) - epsilon), _queue->nb_jobs(),
-                              first_job_size,
-                              (double) _queue->compute_load_estimation(),
-                              (double) llh);
-        }
-    }
-
-    _llh_integral_since_last_monitoring_stage += trapezoid_area;
-    _last_llh_value = llh;
-    _last_llh_date = date;
-
-    _inertial_schedule = _schedule;
-    const Job * priority_job = nullptr;
-    IntervalSet priority_job_reserved_machines;
-    bool priority_job_can_be_started_soon = true;
-    (void) priority_job_can_be_started_soon;
-
-    Rational time_to_wake_up = (*_variant_options)["time_switch_on"].GetDouble();
-    Rational soon_horizon = time_to_wake_up * 2 + date;
-
-    if (_inertial_shutdown_debug)
-        LOG_F(1, "Date=%g. Begin of on_monitoring_stage.", date);
-
-    if (_machines_to_sedate.size() > 0)
-    {
-        // The machines sedated for being idle should never be done in the future, so
-        // cancelled switches OFF are inertial ones. However, for coherency's sake,
-        // the number of idle-sedated machines might also be decreased if there is no
-        // inertially-sedated machines left.
-        int nb_cancelled_switches_off = (int) _machines_to_sedate.size();
-        int nb_cancelled_inertially_sedated_machines = min(nb_cancelled_switches_off,
-                                                           _nb_machines_sedated_by_inertia);
-
-        int nb_cancelled_idle_sedated_machines = 0;
-        if (nb_cancelled_inertially_sedated_machines < nb_cancelled_switches_off)
-            nb_cancelled_idle_sedated_machines = nb_cancelled_switches_off -
-                                                 nb_cancelled_inertially_sedated_machines;
-
-        PPK_ASSERT_ERROR(nb_cancelled_inertially_sedated_machines +
-                         nb_cancelled_idle_sedated_machines == nb_cancelled_switches_off);
-
-        _nb_machines_sedated_by_inertia -= nb_cancelled_inertially_sedated_machines;
-        _nb_machines_sedated_for_being_idle -= nb_cancelled_idle_sedated_machines;
-
-        PPK_ASSERT_ERROR(_nb_machines_sedated_by_inertia >= 0);
-        PPK_ASSERT_ERROR(_nb_machines_sedated_for_being_idle >= 0);
-
-        _machines_to_sedate.clear();
-    }
-
-    //_machines_to_awaken.clear();
-
-    if (_inertial_shutdown_debug)
-    {
-        LOG_F(1, "LLH computed. %s", _inertial_schedule.to_string().c_str());
-        write_schedule_debug("_on_monitoring_after_llh");
-    }
-
-    IntervalSet machines_that_can_be_used_by_the_priority_job;
-    Schedule::JobAlloc priority_job_alloc;
-    bool priority_job_needs_awakenings = false;
-
-    if (_inertial_shutdown_debug)
-        LOG_F(1, "Schedule without priority_job.%s", _inertial_schedule.to_string().c_str());
-
-    compute_priority_job_and_related_stuff(_inertial_schedule, _queue, priority_job,
-                                           _selector,
-                                           priority_job_needs_awakenings,
-                                           priority_job_alloc,
-                                           priority_job_reserved_machines,
-                                           machines_that_can_be_used_by_the_priority_job);
-
-    if (priority_job != nullptr)
-    {
-        Rational priority_job_starting_time_expectancy = _priority_job_starting_time_expectancy;
-        priority_job_can_be_started_soon = priority_job_starting_time_expectancy <= soon_horizon;
-        priority_job_can_be_started_soon = true; // REMOVEME. Forces the previous behaviour.
-    }
-    else
-    {
-        _priority_job_starting_time_expectancy = date;
-    }
-
-    if (_first_monitoring_stage)
-    {
-        _first_monitoring_stage = false;
-        _last_decision = AWAKEN_MACHINES;
-        _inertial_number = 0;
-    }
-    else if (!priority_job_needs_awakenings)
-    {
-        Rational mean_llh_over_last_period = _llh_integral_since_last_monitoring_stage / period();
-
-        if (mean_llh_over_last_period >= _upper_llh_threshold)
-        {
-            // If the threshold is met, the next decision is forced by hacking some variables.
-            if (_last_decision == SEDATE_MACHINES)
-            {
-                _last_decision = AWAKEN_MACHINES;
-                _inertial_number = 0;
-            }
-
-            _llh_integral_of_preceding_monitoring_stage_slice = 0;
-        }
-
-        if (_last_decision == AWAKEN_MACHINES)
-        {
-            if (_llh_integral_since_last_monitoring_stage > _llh_integral_of_preceding_monitoring_stage_slice)
-            {
-                // The LLH's integral is still increasing! We may want to awaken more machines!
-                IntervalSet awakable_machines = _asleep_machines - _machines_to_awaken;
-
-                if (!_allow_future_switches)
-                    awakable_machines -= _non_wakable_asleep_machines;
-
-                int nb_machines_to_awaken_by_inertia = 0;
-                if (_alteration_type == PRODUCT)
-                    nb_machines_to_awaken_by_inertia = (int)((int)_machines_awakened_since_last_monitoring_stage_inertia.size() *
-                                                       _inertial_alteration_number);
-                else if (_alteration_type == SUM)
-                    nb_machines_to_awaken_by_inertia = (int)((int)_machines_awakened_since_last_monitoring_stage_inertia.size() +
-                                                       _inertial_alteration_number);
-                else
-                    PPK_ASSERT_ERROR(false);
-
-                _inertial_number = min(max(nb_machines_to_awaken_by_inertia,1),
-                                       (int)awakable_machines.size());
-
-                if (_inertial_number > 0)
-                {
-                    LOG_F(INFO, "Date=%g. on_monitoring_stage. Would like to awaken %d machines.",
-                           date, _inertial_number);
-
-                    IntervalSet machines_to_awaken;
-                    select_machines_to_awaken(_inertial_number, awakable_machines, machines_to_awaken);
-
-                    LOG_F(INFO, "Date=%g. Decided to awaken machines %s", date, machines_to_awaken.to_string_brackets().c_str());
-
-                    _machines_to_awaken += machines_to_awaken;
-
-                    // The awakened machines are the inertially-sedated ones.
-                    // If there is no inertially-sedated machines left, the idle-sedated ones are impacted
-                    int nb_awakened_inertially_sedated_machines = min((int)machines_to_awaken.size(),
-                                                                      _nb_machines_sedated_by_inertia);
-                    int nb_awakened_idle_sedated_machines = 0;
-                    if (nb_awakened_inertially_sedated_machines < (int)machines_to_awaken.size())
-                        nb_awakened_idle_sedated_machines = (int)machines_to_awaken.size() -
-                                                            nb_awakened_inertially_sedated_machines;
-
-                    _nb_machines_sedated_by_inertia -= nb_awakened_inertially_sedated_machines;
-                    _nb_machines_sedated_for_being_idle -= nb_awakened_idle_sedated_machines;
-
-                    PPK_ASSERT_ERROR(_nb_machines_sedated_by_inertia >= 0);
-                    PPK_ASSERT_ERROR(_nb_machines_sedated_for_being_idle >= 0);
-                }
-            }
-            else
-            {
-                // The LLH has decreased, let's switch to sedate mode :)
-                _last_decision = SEDATE_MACHINES;
-                _inertial_number = 0;
-
-                LOG_F(INFO, "Date=%g. Decided to do nothing now, but switching to sedate mode!", date);
-            }
-        } // end if (_last_decision == AWAKEN_MACHINES)
-        else // if (_last_decision == SEDATE_MACHINES)
-        {
-            if (_llh_integral_since_last_monitoring_stage <= _llh_integral_of_preceding_monitoring_stage_slice)
-            {
-                // The LLH's integral is still decreasing, let's sedate more machines!
-
-                IntervalSet sedatable_machines = _awake_machines - _machines_to_sedate;
-
-                if (!_allow_future_switches)
-                {
-                    PPK_ASSERT_ERROR(_inertial_schedule.nb_slices() > 0);
-                    auto slice_it = _inertial_schedule.begin();
-                    const Schedule::TimeSlice & slice = *slice_it;
-
-                    sedatable_machines -= (_all_machines - slice.available_machines);
-                }
-
-                int nb_sedatable_machines = sedatable_machines.size();
-
-                if (priority_job != nullptr)
-                    nb_sedatable_machines = max(0, (int)sedatable_machines.size() - (int)priority_job_reserved_machines.size());
-
-                int nb_machines_to_sedate_by_inertia = 0;
-                if (_alteration_type == PRODUCT)
-                    nb_machines_to_sedate_by_inertia = (int)((int)_machines_sedated_since_last_monitoring_stage_inertia.size() *
-                                                       _inertial_alteration_number);
-                else if (_alteration_type == SUM)
-                    nb_machines_to_sedate_by_inertia = (int)((int)_machines_sedated_since_last_monitoring_stage_inertia.size() +
-                                                       _inertial_alteration_number);
-                else
-                    PPK_ASSERT_ERROR(false);
-
-                _inertial_number = min(max(nb_machines_to_sedate_by_inertia,1),
-                                       nb_sedatable_machines);
-
-                if (_inertial_number > 0)
-                {
-                    IntervalSet machines_to_sedate;
-                    int nb_idle_machines_to_steal = 0;
-                    int nb_new_machines_to_sedate = _inertial_number;
-
-                    // Let's just use already sedated machines (for being idle) as if they were inertially sedated
-                    if (_nb_machines_sedated_for_being_idle > 0)
-                    {
-                        nb_idle_machines_to_steal = min(_nb_machines_sedated_for_being_idle,
-                                                            (int) _inertial_number);
-                        nb_new_machines_to_sedate = _inertial_number - nb_idle_machines_to_steal;
-
-                        PPK_ASSERT_ERROR(nb_idle_machines_to_steal >= 0 &&
-                                         nb_idle_machines_to_steal <= _nb_machines_sedated_for_being_idle);
-                        PPK_ASSERT_ERROR(nb_new_machines_to_sedate >= 0);
-                    }
-
-                    if (nb_new_machines_to_sedate > 0)
-                        select_machines_to_sedate(_inertial_number, sedatable_machines,
-                                                  machines_that_can_be_used_by_the_priority_job,
-                                                  machines_to_sedate, priority_job);
-
-                    LOG_F(INFO, "Date=%g. Decided to sedate machines %s",
-                           date, machines_to_sedate.to_string_brackets().c_str());
-                    if (nb_idle_machines_to_steal > 0)
-                        LOG_F(INFO, "... and to steal %d idle-sedated machines",
-                               nb_idle_machines_to_steal);
-
-                    _nb_machines_sedated_by_inertia += machines_to_sedate.size() + nb_idle_machines_to_steal;
-                    _nb_machines_sedated_for_being_idle -= nb_idle_machines_to_steal;
-                    _machines_to_sedate += machines_to_sedate;
-
-                    PPK_ASSERT_ERROR(_nb_machines_sedated_by_inertia + _nb_machines_sedated_for_being_idle <= _nb_machines);
-                    PPK_ASSERT_ERROR(_nb_machines_sedated_for_being_idle >= 0);
-                }
-            }
-            else
-            {
-                // The LLH has increased, let's switch to awakening mode :)
-                _last_decision = AWAKEN_MACHINES;
-                _inertial_number = 0;
-
-                LOG_F(INFO, "Date=%g. Decided to do nothing now, but switching to awakening mode!", date);
-            }
-        }
-    }
-
-    if (priority_job != nullptr && !priority_job_needs_awakenings)
-    {
-        // Let's make sure the priority job has not been delayed by the choices we made.
-        Schedule::JobAlloc priority_job_alloc2 = _inertial_schedule.add_job_first_fit(priority_job, _selector);
-
-        if (_inertial_shutdown_debug)
-        {
-            LOG_F(1, "After decisions.%s", _inertial_schedule.to_string().c_str());
-        }
-
-        PPK_ASSERT_ERROR(priority_job_alloc2.has_been_inserted &&
-                         priority_job_alloc2.begin <= priority_job_alloc.begin,
-                         "Invalid energy-related decisions have been made: "
-                         "These decisions delayed the priority job. "
-                         "Starting time before:%g. Starting time after:%g\n",
-                         (double)priority_job_alloc.begin, (double)priority_job_alloc2.begin);
-    }
-
-    _last_llh_value = llh;
-    _last_llh_date = date;
-    _llh_integral_of_preceding_monitoring_stage_slice = _llh_integral_since_last_monitoring_stage;
-    _llh_integral_since_last_monitoring_stage = 0;
-
-    // Let's handle queue switches (first run, to make the first decisions)
-    IntervalSet machines_sedated_this_turn, machines_awakened_this_turn;
-    handle_queued_switches(_inertial_schedule, _machines_to_sedate, _machines_to_awaken,
-                           machines_sedated_this_turn, machines_awakened_this_turn);
-
-    if (machines_sedated_this_turn.size() > 0)
-        LOG_F(INFO, "Date=%g. Those machines should be put to sleep now: %s",
-               date, machines_sedated_this_turn.to_string_brackets().c_str());
-    if (machines_awakened_this_turn.size() > 0)
-        LOG_F(INFO, "Date=%g. Those machines should be awakened now: %s",
-               date, machines_awakened_this_turn.to_string_brackets().c_str());
-
-    _machines_to_sedate -= machines_sedated_this_turn;
-    _machines_to_awaken -= machines_awakened_this_turn;
-    _machines_sedated_since_last_monitoring_stage_inertia = machines_sedated_this_turn;
-    _machines_awakened_since_last_monitoring_stage_inertia = machines_awakened_this_turn;
-
-    // Let's make the inertial decisions
-    make_decisions_of_schedule(_inertial_schedule, false);
-
-    IntervalSet machines_asleep_soon = (_asleep_machines + _switching_off_machines - _switching_on_machines)
-                                        + _machines_to_sedate - _machines_to_awaken;
-    PPK_ASSERT_ERROR((int)machines_asleep_soon.size() == _nb_machines_sedated_by_inertia +
-                                                         _nb_machines_sedated_for_being_idle,
-                     "Asleep machines inconsistency. nb_asleep_soon=%d (%s). nb_sedated_inertia=%d. "
-                     "nb_sedated_idle=%d\n",
-                     (int)machines_asleep_soon.size(), machines_asleep_soon.to_string_brackets().c_str(),
-                     _nb_machines_sedated_by_inertia, _nb_machines_sedated_for_being_idle);
-
-    if (priority_job_needs_awakenings)
-    {
-        // In this case, we can only try to add the priority job after doing the previously requested awakenings.
-        PPK_ASSERT_ERROR(priority_job != nullptr);
-
-        _inertial_schedule.add_job_first_fit(priority_job, _selector, false);
-    }
-
-    // Let's now try to sedate the machines which have been idle for too long
-    EnergyBackfillingIdleSleeper::update_idle_states(date, _inertial_schedule, _all_machines,
-                                                     _idle_machines, _machines_idle_start_date);
-    IntervalSet machines_awake_soon = (_awake_machines + _switching_on_machines - _switching_off_machines)
-                                       + _machines_to_awaken - _machines_to_sedate;
-
-    // Guard to prevent switch ON/OFF cycles
-    if (_switching_on_machines.size() == 0 && _machines_to_awaken.size() == 0)
-    {
-        IntervalSet machines_to_sedate_for_being_idle;
-        EnergyBackfillingIdleSleeper::select_idle_machines_to_sedate(date,
-                                        _idle_machines, machines_awake_soon,
-                                        priority_job, _machines_idle_start_date,
-                                        _needed_amount_of_idle_time_to_be_sedated,
-                                        machines_to_sedate_for_being_idle,
-                                        true); // <------------------------------------------------- Choice to make.
-
-        if (machines_to_sedate_for_being_idle.size() > 0)
-        {
-            // Let's handle queue switches
-            machines_sedated_this_turn.clear();
-            machines_awakened_this_turn.clear();
-            IntervalSet empty_range;
-
-            handle_queued_switches(_inertial_schedule, machines_to_sedate_for_being_idle, empty_range,
-                                   machines_sedated_this_turn, machines_awakened_this_turn);
-
-            // A subset of those machines can be sedated (not all of them because it might be jobs
-            // in the future on some resources)
-            PPK_ASSERT_ERROR((machines_sedated_this_turn & machines_to_sedate_for_being_idle) ==
-                             machines_sedated_this_turn,
-                             "The sedated machines are not the expected ones.Sedated=%s.\nExpected=subset of %s",
-                             machines_sedated_this_turn.to_string_brackets().c_str(),
-                             machines_to_sedate_for_being_idle.to_string_brackets().c_str());
-
-            PPK_ASSERT_ERROR(machines_awakened_this_turn == IntervalSet::empty_interval_set(),
-                             "The awakened machines are not the expected ones.Awakened=%s.\nExpected=%s",
-                             machines_awakened_this_turn.to_string_brackets().c_str(),
-                             IntervalSet::empty_interval_set().to_string_brackets().c_str());
-
-            LOG_F(INFO, "Date=%g. Those machines should be put to sleep now for being idle: %s",
-                       date, machines_sedated_this_turn.to_string_brackets().c_str());
-
-
-            PPK_ASSERT_ERROR((_machines_to_awaken & _machines_to_sedate) == IntervalSet::empty_interval_set());
-
-            if (_inertial_shutdown_debug)
-            {
-                LOG_F(1, "Date=%g. Before make_decisions_of_schedule. %s",
-                       date, _inertial_schedule.to_string().c_str());
-                write_schedule_debug("_on_monitoring_before_make_decisions_of_schedule");
-            }
-
-            // Let's finally make the idle decisions!
-            make_decisions_of_schedule(_inertial_schedule, false);
-
-            _nb_machines_sedated_for_being_idle += machines_sedated_this_turn.size();
-            PPK_ASSERT_ERROR(_nb_machines_sedated_for_being_idle <= _nb_machines);
-        }
-    }
-
-    if (_inertial_shutdown_debug)
-        LOG_F(1, "Date=%g. End of on_monitoring_stage", date);
-
-    // Now that the decisions have been made, let's compute the LLH again.
-    llh = EasyBackfillingPlotLiquidLoadHorizon::compute_liquid_load_horizon(_inertial_schedule,
-                                                                            _queue, date);
-    if (_write_output_file)
-    {
-        int first_job_size = -1;
-        const Job * first_job = _queue->first_job_or_nullptr();
-        if (first_job != nullptr)
-            first_job_size = first_job->nb_requested_resources;
-
-        write_output_file(date, _queue->nb_jobs(),
-                          first_job_size,
-                          (double) _queue->compute_load_estimation(),
-                          (double) llh);
-    }
-
-    machines_asleep_soon = (_asleep_machines + _switching_off_machines - _switching_on_machines)
-                           + _machines_to_sedate - _machines_to_awaken;
-    PPK_ASSERT_ERROR((int)machines_asleep_soon.size() == _nb_machines_sedated_by_inertia +
-                                                         _nb_machines_sedated_for_being_idle,
-                     "Asleep machines inconsistency. nb_asleep_soon=%d (%s). nb_sedated_inertia=%d. "
-                     "nb_sedated_idle=%d\n",
-                     (int)machines_asleep_soon.size(), machines_asleep_soon.to_string_brackets().c_str(),
-                     _nb_machines_sedated_by_inertia, _nb_machines_sedated_for_being_idle);
-
-    _last_llh_value = llh;
-    _last_llh_date = date;
-}
-
-void EnergyBackfillingMonitoringInertialShutdown::select_machines_to_sedate(int nb_machines,
-                                                                            const IntervalSet &sedatable_machines,
-                                                                            const IntervalSet &machines_that_can_be_used_by_the_priority_job,
-                                                                            IntervalSet &machines_to_sedate,
-                                                                            const Job *priority_job) const
-{
-    PPK_ASSERT_ERROR(nb_machines <= (int)sedatable_machines.size());
-    PPK_ASSERT_ERROR((sedatable_machines & (_awake_machines + _switching_on_machines)) == sedatable_machines);
-
-    if (_sedating_policy == SEDATE_FIRST_MACHINES)
-    {
-        select_first_machines_to_sedate(nb_machines, _inertial_schedule, sedatable_machines,
-                                        machines_that_can_be_used_by_the_priority_job, machines_to_sedate,
-                                        priority_job);
-    }
-    else
-        PPK_ASSERT_ERROR(false, "Unknown sedating policy");
-
-    PPK_ASSERT_ERROR(machines_to_sedate.size() == (unsigned int)nb_machines);
-    PPK_ASSERT_ERROR((machines_to_sedate & sedatable_machines) == machines_to_sedate);
-}
-
-void EnergyBackfillingMonitoringInertialShutdown::select_machines_to_awaken(int nb_machines,
-                                                                            const IntervalSet &awakable_machines,
-                                                                            IntervalSet &machines_to_awaken) const
-{
-    PPK_ASSERT_ERROR(nb_machines <= (int)awakable_machines.size());
-    PPK_ASSERT_ERROR((awakable_machines & (_asleep_machines + _switching_off_machines)) == awakable_machines,
-                     "awakable_machines should be a subset of union(_asleep_machines,_switching_off_machines).\n"
-                     "awakable_machines=%s\n_asleep_machines=%s\n_switching_off_machines=%s\n"
-                     "union(_asleep_machines,_switching_off_machines)=%s\n",
-                     awakable_machines.to_string_brackets().c_str(),
-                     _asleep_machines.to_string_brackets().c_str(),
-                     _switching_off_machines.to_string_brackets().c_str(),
-                     (_asleep_machines + _switching_off_machines).to_string_brackets().c_str());
-
-    if (_awakening_policy == AWAKEN_FIRST_MACHINES)
-        select_first_machines_to_awaken(nb_machines, _inertial_schedule, awakable_machines, machines_to_awaken);
-    else
-        PPK_ASSERT_ERROR(false, "Unknown awakening policy");
-
-    PPK_ASSERT_ERROR(machines_to_awaken.size() == (unsigned int) nb_machines);
-    PPK_ASSERT_ERROR((machines_to_awaken & awakable_machines) == machines_to_awaken);
-}
-
-void EnergyBackfillingMonitoringInertialShutdown::select_first_machines_to_sedate(int nb_machines, const Schedule & schedule,
-                                                                                  const IntervalSet & sedatable_machines,
-                                                                                  const IntervalSet & machines_that_can_be_used_by_the_priority_job,
-                                                                                  IntervalSet &machines_to_sedate,
-                                                                                  const Job * priority_job)
-{
-    machines_to_sedate.clear();
-
-    // If there is a priority job, in order to make sure we don't delay it, we can compute how many machines we can "steal"
-    // from the "hole" in which it is supposed to be executed
-    IntervalSet stolen_machines;
-    IntervalSet really_stolable_machines = sedatable_machines & machines_that_can_be_used_by_the_priority_job;
-    int priority_job_nb_requested_resources = 0;
-
-    if (priority_job != nullptr)
-        priority_job_nb_requested_resources = priority_job->nb_requested_resources;
-
-    int nb_machines_that_can_be_stolen_from_priority_job = max(0, (int)(really_stolable_machines.size() - priority_job_nb_requested_resources));
-
-    auto slice_it = schedule.begin();
-    while (slice_it != schedule.end())
-    {
-        const Schedule::TimeSlice & slice = *slice_it;
-        IntervalSet sedatable_machines_now = (slice.available_machines & sedatable_machines) - machines_to_sedate;
-
-        // The sedatable machines might annoy the priority job...
-        IntervalSet annoying_sedatable_machines = (sedatable_machines_now & (really_stolable_machines - stolen_machines));
-        if (annoying_sedatable_machines != IntervalSet::empty_interval_set())
-        {
-            // Let's see if we can "steal" some machines from the priority job.
-            int nb_machines_stolable_now = nb_machines_that_can_be_stolen_from_priority_job - stolen_machines.size();
-            if (nb_machines_stolable_now > 0)
-            {
-                IntervalSet stolable_machines = annoying_sedatable_machines.left(min(nb_machines_stolable_now, (int)annoying_sedatable_machines.size()));
-
-                int nb_machines_i_want_to_steal = min(stolable_machines.size(), nb_machines - machines_to_sedate.size());
-                IntervalSet stolen_machines_now = stolable_machines.left(nb_machines_i_want_to_steal);
-
-                stolen_machines += stolen_machines_now;
-                machines_to_sedate += stolen_machines_now;
-            }
-        }
-
-        sedatable_machines_now -= annoying_sedatable_machines;
-
-        if (sedatable_machines_now.size() + machines_to_sedate.size() >= (unsigned int)nb_machines)
-        {
-            machines_to_sedate += sedatable_machines_now.left(nb_machines - machines_to_sedate.size());
-            return;
-        }
-        else
-            machines_to_sedate += sedatable_machines_now;
-
-        slice_it++;
-    }
-
-    PPK_ASSERT_ERROR(false, "Couldn't select %d machines to sedate :(.\n"
-                     "sedatable_machines=%s.\n"
-                     "priority_job=%p.\n"
-                     "priority_job_nb_requested_resources=%d.\n"
-                     "machines_that_can_be_used_by_the_priority_job=%s.\n%s\n",
-                     nb_machines, sedatable_machines.to_string_brackets().c_str(),
-                     priority_job, priority_job_nb_requested_resources,
-                     machines_that_can_be_used_by_the_priority_job.to_string_brackets().c_str(),
-                     schedule.to_string().c_str());
-}
-
-void EnergyBackfillingMonitoringInertialShutdown::select_first_machines_to_awaken(int nb_machines, const Schedule & schedule,
-                                                                                  const IntervalSet &awakable_machines,
-                                                                                  IntervalSet &machines_to_awaken)
-{
-    machines_to_awaken.clear();
-
-    auto slice_it = schedule.begin();
-    while (slice_it != schedule.end())
-    {
-        const Schedule::TimeSlice & slice = *slice_it;
-        IntervalSet awakable_machines_now = (compute_potentially_awaken_machines(slice) & awakable_machines) - machines_to_awaken;
-
-        if (awakable_machines_now.size() + machines_to_awaken.size() >= (unsigned int)nb_machines)
-        {
-            machines_to_awaken += awakable_machines_now.left(nb_machines - machines_to_awaken.size());
-            return;
-        }
-        else
-            machines_to_awaken += awakable_machines_now;
-
-        slice_it++;
-    }
-
-    PPK_ASSERT_ERROR(false, "Couldn't select %d machines to awaken :(. %s\n", nb_machines, schedule.to_string().c_str());
-}
-
-void EnergyBackfillingMonitoringInertialShutdown::handle_queued_switches(Schedule & schedule,
-                                                                         const IntervalSet & machines_to_sedate,
-                                                                         const IntervalSet & machines_to_awaken,
-                                                                         IntervalSet & machines_sedated_now,
-                                                                         IntervalSet & machines_awakened_now)
-{
-    if (_inertial_shutdown_debug)
-    {
-        LOG_F(1, "handle_queued_switches, begin.\n"
-               "machines_to_awaken: %s\nmachines_to_sedate: %s\n"
-               "_awake_machines: %s\n_asleep_machines: %s\n"
-               "_wakable_asleep_machines: %s\n"
-               "_non_wakable_asleep_machines: %s\n%s",
-               machines_to_awaken.to_string_brackets().c_str(),
-               machines_to_sedate.to_string_brackets().c_str(),
-               _awake_machines.to_string_brackets().c_str(),
-               _asleep_machines.to_string_brackets().c_str(),
-               _wakable_asleep_machines.to_string_brackets().c_str(),
-               _non_wakable_asleep_machines.to_string_brackets().c_str(),
-               _inertial_schedule.to_string().c_str());
-        write_schedule_debug("_handle_queued_switches_begin");
-    }
-
-    // Let's sedate and awaken the desired machines into the _inertial_schedule
-    for (auto machine_it = machines_to_awaken.elements_begin(); machine_it != machines_to_awaken.elements_end(); machine_it++)
-    {
-        int machine_id = *machine_it;
-        Rational awakening_date = awaken_machine_as_soon_as_possible(schedule, machine_id);
-
-        if (awakening_date == schedule.first_slice_begin())
-            machines_awakened_now += machine_id;
-    }
-
-    if (_inertial_shutdown_debug)
-    {
-        LOG_F(1, "handle_queued_switches, after awakenings.\n"
-               "machines_to_sedate: %s\n%s",
-               machines_to_sedate.to_string_brackets().c_str(),
-               _inertial_schedule.to_string().c_str());
-        write_schedule_debug("_handle_queued_switches_after_awakenings");
-    }
-
-    for (auto machine_it = machines_to_sedate.elements_begin(); machine_it != machines_to_sedate.elements_end(); machine_it++)
-    {
-        int machine_id = *machine_it;
-
-        Rational sedating_date = sedate_machines_at_the_furthest_moment(schedule, machine_id);
-
-        if (sedating_date == schedule.first_slice_begin())
-            machines_sedated_now += machine_id;
-    }
-
-    if (_inertial_shutdown_debug)
-    {
-        LOG_F(1, "handle_queued_switches, end.\n"
-               "machines_sedated_now = %s\n"
-               "machines_awakened_now = %s\n%s",
-               machines_sedated_now.to_string_brackets().c_str(),
-               machines_awakened_now.to_string_brackets().c_str(),
-               _inertial_schedule.to_string().c_str());
-        write_schedule_debug("_handle_queued_switches_end");
-    }
-
-}
-
-void EnergyBackfillingMonitoringInertialShutdown::write_output_file(double date,
-                                                                    int nb_jobs_in_queue,
-                                                                    int first_job_size,
-                                                                    double load_in_queue,
-                                                                    double liquid_load_horizon)
-{
-    PPK_ASSERT_ERROR(_output_file.is_open());
-
-    const int buf_size = 256;
-    int nb_printed;
-    char * buf = (char*) malloc(sizeof(char) * buf_size);
-
-    if (first_job_size != -1)
-        nb_printed = snprintf(buf, buf_size, "%g,%d,%d,%g,%g,%g\n",
-                              date, nb_jobs_in_queue, first_job_size,
-                              (double)_priority_job_starting_time_expectancy - date,
-                              load_in_queue, liquid_load_horizon);
-    else
-        nb_printed = snprintf(buf, buf_size, "%g,%d,NA,NA,%g,%g\n",
-                              date, nb_jobs_in_queue,
-                              load_in_queue, liquid_load_horizon);
-    PPK_ASSERT_ERROR(nb_printed < buf_size - 1,
-                     "Buffer too small, some information might have been lost");
-
-    _output_file.write(buf, strlen(buf));
-
-    free(buf);
-}
-
-void EnergyBackfillingMonitoringInertialShutdown::write_schedule_debug(const string &filename_suffix)
-{
-    if (_really_write_svg_files)
-    {
-        char output_filename[256];
-        snprintf(output_filename, 256, "%s/inertial_schedule_%06d%s.svg",
-                 _output_dir.c_str(), _debug_output_id, filename_suffix.c_str());
-
-        _inertial_schedule.write_svg_to_file(output_filename);
-    }
-
-    ++_debug_output_id;
-}
-
-void EnergyBackfillingMonitoringInertialShutdown::compute_priority_job_and_related_stuff(Schedule &schedule,
-                                                                                         const Queue * queue,
-                                                                                         const Job *&priority_job,
-                                                                                         ResourceSelector * priority_job_selector,
-                                                                                         bool & priority_job_needs_awakenings,
-                                                                                         Schedule::JobAlloc &first_insertion_alloc,
-                                                                                         IntervalSet &priority_job_reserved_machines,
-                                                                                         IntervalSet &machines_that_can_be_used_by_the_priority_job)
-{
-    priority_job = nullptr;
-    first_insertion_alloc.has_been_inserted = false;
-    priority_job_reserved_machines.clear();
-    machines_that_can_be_used_by_the_priority_job.clear();
-
-    // Let's find in which time space the priority job should be executed
-    if (!queue->is_empty())
-    {
-        priority_job = queue->first_job();
-        // To do so, let's insert the priority job into the schedule.
-
-        if (schedule.contains_job(priority_job))
-            schedule.remove_job(priority_job);
-
-        first_insertion_alloc = schedule.add_job_first_fit(priority_job, priority_job_selector, false);
-
-        if (!first_insertion_alloc.has_been_inserted)
-        {
-            // The priority job has not been inserted. This is probably because some machines must be awakened first.
-            priority_job_needs_awakenings = true;
-        }
-        else
-        {
-            priority_job_reserved_machines = first_insertion_alloc.used_machines;
-
-            // Now we want to determine which machines the priority job can use at this period of time.
-            // To do so, let's remove it from the schedule then compute all available machines during
-            // this period of time.
-            PPK_ASSERT_ERROR(schedule.contains_job(priority_job));
-            schedule.remove_job(priority_job);
-            PPK_ASSERT_ERROR(!schedule.contains_job(priority_job));
-
-            machines_that_can_be_used_by_the_priority_job = schedule.available_machines_during_period(first_insertion_alloc.begin, first_insertion_alloc.end);
-            // Coherency checks: the previous allocation should be a subset of these machines
-            PPK_ASSERT_ERROR(((first_insertion_alloc.used_machines & machines_that_can_be_used_by_the_priority_job) == first_insertion_alloc.used_machines) &&
-                             ((first_insertion_alloc.used_machines + machines_that_can_be_used_by_the_priority_job) == machines_that_can_be_used_by_the_priority_job),
-                             "The priority job '%s' has been allocated in an invalid place. "
-                             "It should have been among %s, but it is in %s.\n%s",
-                             priority_job->id.c_str(), machines_that_can_be_used_by_the_priority_job.to_string_brackets().c_str(),
-                             first_insertion_alloc.used_machines.to_string_brackets().c_str(),
-                             schedule.to_string().c_str());
-        }
-    }
-}
-
-Rational EnergyBackfillingMonitoringInertialShutdown::compute_priority_job_starting_time_expectancy(const Schedule &schedule,
-                                                                                                    const Job *priority_job)
-{
-    if (priority_job == nullptr)
-        return -1;
-
-    Schedule copy = schedule;
-
-    // Let's remove the job from the schedule if it exists
-    copy.remove_job_if_exists(priority_job);
-
-    // Let's remove every sleeping machine from it
-    IntervalSet machines_asleep_soon = (_asleep_machines + _switching_off_machines - _switching_on_machines)
-                                        + _machines_to_sedate - _machines_to_awaken;
-
-    for (auto mit = machines_asleep_soon.elements_begin(); mit != machines_asleep_soon.elements_end(); ++mit)
-    {
-        int machine_id = *mit;
-        EnergyBackfilling::awaken_machine_as_soon_as_possible(copy, machine_id);
-    }
-
-    Schedule::JobAlloc alloc = copy.add_job_first_fit(priority_job, _selector, true);
-
-    PPK_ASSERT_ERROR(alloc.has_been_inserted);
-    return alloc.begin;
-}
diff --git a/src/algo/energy_bf_monitoring_inertial_shutdown.hpp b/src/algo/energy_bf_monitoring_inertial_shutdown.hpp
deleted file mode 100644
index 4efe12c6c76b772ca8a502c46323130c6c9bf3b1..0000000000000000000000000000000000000000
--- a/src/algo/energy_bf_monitoring_inertial_shutdown.hpp
+++ /dev/null
@@ -1,158 +0,0 @@
-#pragma once
-
-#include "energy_bf_monitoring_period.hpp"
-
-#include <fstream>
-
-class EnergyBackfillingMonitoringInertialShutdown : public EnergyBackfillingMonitoringPeriod
-{
-public:
-    enum DecisionType
-    {
-        SEDATE_MACHINES,
-        AWAKEN_MACHINES,
-    };
-
-    enum MachinesSedatingPolicy
-    {
-        SEDATE_FIRST_MACHINES
-    };
-
-    enum MachinesAwakeningPolicy
-    {
-        AWAKEN_FIRST_MACHINES
-    };
-
-    enum InertialAlterationType
-    {
-        SUM,
-        PRODUCT
-    };
-
-public:
-    EnergyBackfillingMonitoringInertialShutdown(Workload * workload,
-                                                SchedulingDecision * decision,
-                                                Queue * queue,
-                                                ResourceSelector * selector,
-                                                double rjms_delay,
-                                                rapidjson::Document * variant_options);
-
-    virtual void on_simulation_start(double date, const rapidjson::Value & batsim_config);
-
-    virtual void make_decisions(double date,
-                                SortableJobOrder::UpdateInformation * update_info,
-                                SortableJobOrder::CompareInformation * compare_info);
-
-    virtual void on_monitoring_stage(double date);
-
-
-    void select_machines_to_sedate(int nb_machines,
-                                   const IntervalSet & sedatable_machines,
-                                   const IntervalSet & machines_that_can_be_used_by_the_priority_job,
-                                   IntervalSet & machines_to_sedate,
-                                   const Job * priority_job) const;
-
-    void select_machines_to_awaken(int nb_machines,
-                                   const IntervalSet & awakable_machines,
-                                   IntervalSet & machines_to_awaken) const;
-
-    static void select_first_machines_to_sedate(int nb_machines,
-                                                const Schedule & schedule,
-                                                const IntervalSet & sedatable_machines,
-                                                const IntervalSet &machines_that_can_be_used_by_the_priority_job,
-                                                IntervalSet & machines_to_sedate,
-                                                const Job * priority_job = nullptr);
-
-    static void select_first_machines_to_awaken(int nb_machines,
-                                                const Schedule & schedule,
-                                                const IntervalSet & awakable_machines,
-                                                IntervalSet & machines_to_awaken);
-
-    void write_schedule_debug(const std::string & filename_suffix = "");
-
-    static void compute_priority_job_and_related_stuff(Schedule & schedule,
-                                                       const Queue * queue,
-                                                       const Job *& priority_job,
-                                                       ResourceSelector * priority_job_selector,
-                                                       bool & priority_job_needs_awakenings,
-                                                       Schedule::JobAlloc & first_insertion_alloc,
-                                                       IntervalSet & priority_job_reserved_machines,
-                                                       IntervalSet & machines_that_can_be_used_by_the_priority_job);
-
-    Rational compute_priority_job_starting_time_expectancy(const Schedule & schedule,
-                                                           const Job * priority_job);
-
-
-protected:
-    /**
-
-     * @details This method will add fake jobs into _inertial_schedule and update _machines_to_sedate
-     *          and _machines_to_awaken if the switches have been done in the first slice.
-     */
-
-    /**
-     * @brief Handles the switches ON/OFF that must be done but that couldn't be done earlier.
-     * @param[in,out] schedule The Schedule on which the modifications should be done
-     * @param[in] machines_to_sedate The machines that must be sedated as soon as possible
-     * @param[in] machines_to_awaken The machines that must be awakened as soon as possible
-     * @param[out] machines_sedated_now The machines that have been sedated in the first time slice
-     * @param[out] machines_awakened_now The machines that have been awakened in the first time slice
-     */
-    void handle_queued_switches(Schedule & schedule,
-                                const IntervalSet & machines_to_sedate,
-                                const IntervalSet & machines_to_awaken,
-                                IntervalSet & machines_sedated_now,
-                                IntervalSet & machines_awakened_now);
-
-    void write_output_file(double date,
-                           int nb_jobs_in_queue,
-                           int first_job_size,
-                           double load_in_queue,
-                           double liquid_load_horizon);
-
-protected:
-    Schedule _inertial_schedule;
-
-private:
-    std::ofstream _output_file;
-
-protected:
-    bool _inertial_shutdown_debug = false;
-    bool _really_write_svg_files = false;
-    bool _write_output_file = true;
-    int _debug_output_id = 0;
-
-    // Algorithm real (scientific) parameters:
-    bool _allow_future_switches = true;
-    Rational _upper_llh_threshold = 1e100;
-    InertialAlterationType _alteration_type = PRODUCT;
-    Rational _inertial_alteration_number = 2;
-
-    bool _sedate_idle_on_classical_events = false;
-    double _needed_amount_of_idle_time_to_be_sedated = 1e18;
-    int _nb_machines_sedated_for_being_idle = 0;
-    int _nb_machines_sedated_by_inertia = 0;
-    std::map<int, Rational> _machines_idle_start_date;
-    IntervalSet _idle_machines;
-
-    bool _first_monitoring_stage = true;
-
-    Rational _priority_job_starting_time_expectancy = 0;
-
-    DecisionType _last_decision;
-    int _inertial_number;
-    Rational _last_llh_value = 0; //!< The value of the latest computed Liquid Load Horizon
-    Rational _last_llh_date = 0; //!< The date at which the latest Liquid Load Horizon has been computed
-    Rational _llh_integral_since_last_monitoring_stage = 0; //!< The sum over time of the Liquid Load Horizon. This sum is computed by the sum of the areas of trapezoids.
-    Rational _llh_integral_of_preceding_monitoring_stage_slice = 0; //!< The precedent value of _llh_integral_since_last_monitoring_stage
-
-    MachinesSedatingPolicy _sedating_policy = SEDATE_FIRST_MACHINES;
-    MachinesAwakeningPolicy _awakening_policy = AWAKEN_FIRST_MACHINES;
-
-    IntervalSet _machines_to_sedate;
-    IntervalSet _machines_to_awaken;
-
-    // The pstates changes that were asked since the last monitoring stage
-    IntervalSet _machines_awakened_since_last_monitoring_stage_inertia;
-    IntervalSet _machines_sedated_since_last_monitoring_stage_inertia;
-};
diff --git a/src/algo/energy_bf_monitoring_period.cpp b/src/algo/energy_bf_monitoring_period.cpp
deleted file mode 100644
index 4da14adf48de917afedb271862ec50197b14cdd1..0000000000000000000000000000000000000000
--- a/src/algo/energy_bf_monitoring_period.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-#include "energy_bf_monitoring_period.hpp"
-
-#include <loguru.hpp>
-
-#include "../pempek_assert.hpp"
-
-using namespace std;
-
-EnergyBackfillingMonitoringPeriod::EnergyBackfillingMonitoringPeriod(Workload * workload,
-                                                                 SchedulingDecision * decision,
-                                                                 Queue * queue,
-                                                                 ResourceSelector * selector,
-                                                                 double rjms_delay,
-                                                                 rapidjson::Document * variant_options) :
-    EnergyBackfilling(workload, decision, queue, selector, rjms_delay, variant_options)
-{
-    PPK_ASSERT_ERROR(variant_options->HasMember("output_dir"), "Invalid options JSON object: Member 'output_dir' cannot be found");
-    PPK_ASSERT_ERROR((*variant_options)["output_dir"].IsString(), "Invalid options JSON object: Member 'output_dir' must be a string");
-    _output_dir = (*variant_options)["output_dir"].GetString();
-
-    PPK_ASSERT_ERROR(variant_options->HasMember("monitoring_period"), "Invalid options JSON object: Member 'monitoring_period' cannot be found");
-    PPK_ASSERT_ERROR((*variant_options)["monitoring_period"].IsNumber(), "Invalid options JSON object: Member 'monitoring_period' must be a number");
-    _period_between_monitoring_stages = (*variant_options)["monitoring_period"].GetDouble();
-}
-
-EnergyBackfillingMonitoringPeriod::~EnergyBackfillingMonitoringPeriod()
-{
-
-}
-
-void EnergyBackfillingMonitoringPeriod::on_simulation_end(double date)
-{
-    EnergyBackfilling::on_simulation_end(date);
-
-    PPK_ASSERT_ERROR(_simulation_finished == false);
-    _simulation_finished = true;
-
-    LOG_F(INFO, "EnergyBackfillingMonitoringPeriod: 'End of simulation' message received from Batsim. date=%g", date);
-}
-
-void EnergyBackfillingMonitoringPeriod::on_job_release(double date, const std::vector<string> &job_ids)
-{
-    if (!_monitoring_period_launched)
-    {
-        _next_monitoring_period_expected_date = date + _period_between_monitoring_stages;
-
-        LOG_F(INFO, "EnergyBackfillingMonitoringPeriod: First monitoring nop is expected to be at date=%g",
-               (double) _next_monitoring_period_expected_date);
-
-        _decision->add_call_me_later((double)(_next_monitoring_period_expected_date), date);
-        _nb_call_me_later_running++;
-        _monitoring_period_launched = true;
-    }
-
-    EnergyBackfilling::on_job_release(date, job_ids);
-}
-
-void EnergyBackfillingMonitoringPeriod::on_requested_call(double date)
-{
-    EnergyBackfilling::on_requested_call(date);
-    LOG_F(INFO, "on_requested_call, date = %g", date);
-
-    if (!_simulation_finished)
-    {
-        // Let's execute on_monitoring_stage
-        on_monitoring_stage(date);
-
-        if (!_stop_sending_call_me_later)
-        {
-            // Let's request a call for the next monitoring stage
-            _next_monitoring_period_expected_date = date + _period_between_monitoring_stages;
-            _decision->add_call_me_later((double)(_next_monitoring_period_expected_date), date);
-            _nb_call_me_later_running++;
-
-            LOG_F(INFO, "EnergyBackfillingMonitoringPeriod: 'Chose to launch a call_me_later at %g",
-                   (double)_next_monitoring_period_expected_date);
-        }
-    }
-}
-
-void EnergyBackfillingMonitoringPeriod::on_monitoring_stage(double date)
-{
-    LOG_F(INFO, "EnergyBackfillingMonitoringPeriod: Monitoring stage at date=%g", date);
-}
-
-Rational EnergyBackfillingMonitoringPeriod::period() const
-{
-    return _period_between_monitoring_stages;
-}
-
-Rational EnergyBackfillingMonitoringPeriod::next_monitoring_stage_date() const
-{
-    return _next_monitoring_period_expected_date;
-}
-
-bool EnergyBackfillingMonitoringPeriod::is_simulation_finished() const
-{
-    return _simulation_finished;
-}
-
-
diff --git a/src/algo/energy_bf_monitoring_period.hpp b/src/algo/energy_bf_monitoring_period.hpp
deleted file mode 100644
index 525e27fee3745e1b1afe4fd5b459e2fbef1a54e1..0000000000000000000000000000000000000000
--- a/src/algo/energy_bf_monitoring_period.hpp
+++ /dev/null
@@ -1,40 +0,0 @@
-#pragma once
-
-#include "energy_bf.hpp"
-
-class EnergyBackfillingMonitoringPeriod : public EnergyBackfilling
-{
-public:
-    EnergyBackfillingMonitoringPeriod(Workload * workload,
-                                      SchedulingDecision * decision,
-                                      Queue * queue,
-                                      ResourceSelector * selector,
-                                      double rjms_delay,
-                                      rapidjson::Document * variant_options);
-
-    virtual ~EnergyBackfillingMonitoringPeriod();
-
-    virtual void on_simulation_end(double date);
-
-    virtual void on_job_release(double date, const std::vector<std::string> & job_ids);
-
-    virtual void on_requested_call(double date);
-
-    virtual void on_monitoring_stage(double date);
-
-public:
-    Rational period() const;
-    Rational next_monitoring_stage_date() const;
-    bool is_simulation_finished() const;
-
-protected:
-    std::string _output_dir;
-    bool _stop_sending_call_me_later = false;
-
-private:
-    bool _monitoring_period_launched = false;
-    bool _simulation_finished = false;
-    Rational _period_between_monitoring_stages;
-    Rational _next_monitoring_period_expected_date;
-
-};
diff --git a/src/algo/energy_watcher.cpp b/src/algo/energy_watcher.cpp
deleted file mode 100644
index 0905f7899fec453db0cda714e7b36702d92385ae..0000000000000000000000000000000000000000
--- a/src/algo/energy_watcher.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-#include "energy_watcher.hpp"
-
-#include <loguru.hpp>
-
-#include "../pempek_assert.hpp"
-
-using namespace std;
-
-EnergyWatcher::EnergyWatcher(Workload * workload,
-               SchedulingDecision * decision,
-               Queue * queue,
-               ResourceSelector * selector,
-               double rjms_delay,
-               rapidjson::Document * variant_options) :
-    ISchedulingAlgorithm(workload, decision, queue, selector, rjms_delay, variant_options)
-{
-
-}
-
-EnergyWatcher::~EnergyWatcher()
-{
-
-}
-
-void EnergyWatcher::on_simulation_start(double date, const rapidjson::Value & batsim_config)
-{
-    (void) date;
-
-    _machines.insert(IntervalSet::ClosedInterval(0, _nb_machines - 1));
-    PPK_ASSERT_ERROR(_machines.size() == (unsigned int) _nb_machines);
-
-    // TODO: print warning if time sharing is disabled
-    (void) batsim_config;
-}
-
-void EnergyWatcher::on_simulation_end(double date)
-{
-    (void) date;
-}
-
-void EnergyWatcher::make_decisions(double date,
-                            SortableJobOrder::UpdateInformation *update_info,
-                            SortableJobOrder::CompareInformation *compare_info)
-{
-    (void) update_info;
-    (void) compare_info;
-
-    /* This algorithm execute the jobs in order in arrival in a sequence.
-       It queries about the energy consumption at each job arrival and checks
-       that it is non-decreasing. */
-
-    if (_consumed_joules_updated_recently)
-    {
-        if (_previous_energy < 0)
-            _previous_energy = _consumed_joules;
-
-        PPK_ASSERT_ERROR(_consumed_joules - _previous_energy >= -1e-6,
-                         "Energy consumption inconsistency: it should be non-decreasing. "
-                         "Received %g but previous value is %g.",
-                         _consumed_joules, _previous_energy);
-        LOG_F(INFO, "Updating consumed joules. Now=%g. Before=%g.",
-               _consumed_joules, _previous_energy);
-        _previous_energy = _consumed_joules;
-    }
-
-    PPK_ASSERT_ERROR(_jobs_killed_recently.size() == 0,
-                     "Jobs have been killed, which should not happen with this algorithm.");
-
-    if (_jobs_ended_recently.size() > 0)
-    {
-        PPK_ASSERT_ERROR(_is_machine_busy == true);
-        _is_machine_busy = false;
-    }
-
-    // Let's handle recently released jobs
-    for (const string & new_job_id : _jobs_released_recently)
-    {
-        const Job * new_job = (*_workload)[new_job_id];
-
-        if (new_job->nb_requested_resources > _nb_machines)
-        {
-            // The job is too big for the machine -> reject
-            _decision->add_reject_job(new_job_id, date);
-        }
-        else
-        {
-            // THe job fits in the machine -> added in queue
-            _queue->append_job(new_job, update_info);
-        }
-    }
-
-    // Query consumed energy if new jobs have been submitted
-    if (_jobs_released_recently.size() > 0)
-    {
-        _decision->add_query_energy_consumption(date);
-    }
-
-    // Execute a job if the machine is completely idle
-    execute_job_if_whole_machine_is_idle(date);
-}
-
-void EnergyWatcher::execute_job_if_whole_machine_is_idle(double date)
-{
-    const Job * job = _queue->first_job_or_nullptr();
-
-    // If all the machines are available and that there are jobs to compute
-    if (!_is_machine_busy && job != nullptr)
-    {
-        IntervalSet machines_to_use = _machines.left(job->nb_requested_resources);
-        _decision->add_execute_job(job->id, machines_to_use, date);
-
-        _is_machine_busy = true;
-        _queue->remove_job(job);
-    }
-}
-
diff --git a/src/algo/energy_watcher.hpp b/src/algo/energy_watcher.hpp
deleted file mode 100644
index a60fb66028ab6392be221d0dd33b7714a1239b5d..0000000000000000000000000000000000000000
--- a/src/algo/energy_watcher.hpp
+++ /dev/null
@@ -1,27 +0,0 @@
-#pragma once
-
-#include "../isalgorithm.hpp"
-
-class EnergyWatcher : public ISchedulingAlgorithm
-{
-public:
-    EnergyWatcher(Workload * workload, SchedulingDecision * decision, Queue * queue, ResourceSelector * selector,
-           double rjms_delay, rapidjson::Document * variant_options);
-
-    virtual ~EnergyWatcher();
-
-    virtual void on_simulation_start(double date, const rapidjson::Value & batsim_config);
-
-    virtual void on_simulation_end(double date);
-
-    virtual void make_decisions(double date,
-                                SortableJobOrder::UpdateInformation * update_info,
-                                SortableJobOrder::CompareInformation * compare_info);
-
-    void execute_job_if_whole_machine_is_idle(double date);
-
-private:
-    IntervalSet _machines;
-    bool _is_machine_busy = false;
-    double _previous_energy = -1;
-};
diff --git a/src/algo/fcfs_fast.cpp b/src/algo/fcfs_fast.cpp
deleted file mode 100644
index edac4dbcc217b404e6ebbb05a954137a8fc3f694..0000000000000000000000000000000000000000
--- a/src/algo/fcfs_fast.cpp
+++ /dev/null
@@ -1,134 +0,0 @@
-#include "fcfs_fast.hpp"
-
-#include "../pempek_assert.hpp"
-
-FCFSFast::FCFSFast(Workload *workload,
-    SchedulingDecision *decision, Queue *queue, ResourceSelector *selector,
-    double rjms_delay, rapidjson::Document *variant_options) :
-    ISchedulingAlgorithm(workload, decision, queue, selector, rjms_delay,
-        variant_options)
-{}
-
-FCFSFast::~FCFSFast()
-{}
-
-void FCFSFast::on_simulation_start(double date,
-    const rapidjson::Value &batsim_config)
-{
-    (void) date;
-    (void) batsim_config;
-
-    _available_machines.insert(IntervalSet::ClosedInterval(0, _nb_machines - 1));
-    _nb_available_machines = _nb_machines;
-    PPK_ASSERT_ERROR(_available_machines.size() == (unsigned int) _nb_machines);
-}
-
-void FCFSFast::on_simulation_end(double date)
-{
-    (void) date;
-}
-
-void FCFSFast::make_decisions(double date,
-    SortableJobOrder::UpdateInformation *update_info,
-    SortableJobOrder::CompareInformation *compare_info)
-{
-    (void) update_info;
-    (void) compare_info;
-
-    // This algorithm is a fast version of FCFS without backfilling.
-    // It is meant to be fast in the usual case, not to handle corner cases.
-    // It is not meant to be easily readable or hackable ;).
-
-    // This fast FCFS variant in a few words:
-    // - only handles the FCFS queue order
-    // - only handles the basic resource selection policy
-    // - only handles finite jobs (no switchoff)
-    // - only handles time as floating-point (-> precision errors).
-
-    bool job_ended = false;
-
-    // Handle newly finished jobs
-    for (const std::string & ended_job_id : _jobs_ended_recently)
-    {
-        job_ended = true;
-
-        Job * finished_job = (*_workload)[ended_job_id];
-
-        // Update data structures
-        _available_machines.insert(_current_allocations[ended_job_id]);
-        _nb_available_machines += finished_job->nb_requested_resources;
-        _current_allocations.erase(ended_job_id);
-    }
-
-    // If jobs have finished, execute jobs as long as they fit
-    if (job_ended)
-    {
-        for (auto job_it = _pending_jobs.begin();
-             job_it != _pending_jobs.end(); )
-        {
-            Job * pending_job = *job_it;
-            if (pending_job->nb_requested_resources <= _nb_available_machines)
-            {
-                IntervalSet machines = _available_machines.left(
-                    pending_job->nb_requested_resources);
-                _decision->add_execute_job(pending_job->id,
-                    machines, date);
-
-                // Update data structures
-                _available_machines -= machines;
-                _nb_available_machines -= pending_job->nb_requested_resources;
-                _current_allocations[pending_job->id] = machines;
-                job_it = _pending_jobs.erase(job_it);
-            }
-            else
-            {
-                // The job becomes priority!
-                // As there is no backfilling, we can simply leave this loop.
-                break;
-            }
-        }
-    }
-
-    // Handle newly released jobs
-    for (const std::string & new_job_id : _jobs_released_recently)
-    {
-        Job * new_job = (*_workload)[new_job_id];
-
-        // Is this job valid?
-        if (new_job->nb_requested_resources > _nb_machines)
-        {
-            // Invalid!
-            _decision->add_reject_job(new_job_id, date);
-            continue;
-        }
-
-        // Is there a waiting job?
-        if (!_pending_jobs.empty())
-        {
-            // Yes. The new job is queued up.
-            _pending_jobs.push_back(new_job);
-        }
-        else
-        {
-            // No, the queue is empty.
-            // Can the new job be executed now?
-            if (new_job->nb_requested_resources <= _nb_available_machines)
-            {
-                // Yes, the job can be executed right away!
-                IntervalSet machines = _available_machines.left(
-                    new_job->nb_requested_resources);
-                _decision->add_execute_job(new_job_id, machines, date);
-
-                // Update data structures
-                _available_machines -= machines;
-                _nb_available_machines -= new_job->nb_requested_resources;
-                _current_allocations[new_job_id] = machines;
-            }
-            else
-            {
-                // No. The job is queued up.
-                _pending_jobs.push_back(new_job);
-            }
-        }
-    }
-}
diff --git a/src/algo/fcfs_fast.hpp b/src/algo/fcfs_fast.hpp
deleted file mode 100644
index 9c287ea7d5f49ed3f461570686e75e179a4b32fe..0000000000000000000000000000000000000000
--- a/src/algo/fcfs_fast.hpp
+++ /dev/null
@@ -1,38 +0,0 @@
-#pragma once
-
-#include <unordered_map>
-#include <list>
-
-#include "../isalgorithm.hpp"
-#include "../json_workload.hpp"
-#include "../locality.hpp"
-
-class FCFSFast : public ISchedulingAlgorithm
-{
-public:
-    FCFSFast(Workload * workload, SchedulingDecision * decision,
-        Queue * queue, ResourceSelector * selector,
-        double rjms_delay,
-        rapidjson::Document * variant_options);
-    virtual ~FCFSFast();
-
-    virtual void on_simulation_start(double date,
-        const rapidjson::Value & batsim_config);
-
-    virtual void on_simulation_end(double date);
-
-    virtual void make_decisions(double date,
-        SortableJobOrder::UpdateInformation * update_info,
-        SortableJobOrder::CompareInformation * compare_info);
-
-private:
-    // Machines currently available
-    IntervalSet _available_machines;
-    int _nb_available_machines = -1;
-
-    // Pending jobs (queue)
-    std::list<Job *> _pending_jobs;
-
-    // Allocations of running jobs
-    std::unordered_map<std::string, IntervalSet> _current_allocations;
-};
diff --git a/src/algo/filler.cpp b/src/algo/filler.cpp
deleted file mode 100644
index ecffb7887d7a907ba211760cdbba4ed497f1424c..0000000000000000000000000000000000000000
--- a/src/algo/filler.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-#include "filler.hpp"
-
-#include <loguru.hpp>
-
-#include "../json_workload.hpp"
-#include "../decision.hpp"
-#include "../pempek_assert.hpp"
-
-using namespace std;
-
-Filler::Filler(Workload *workload, SchedulingDecision * decision, Queue * queue,
-               ResourceSelector *selector, double rjms_delay, rapidjson::Document *variant_options) :
-    ISchedulingAlgorithm(workload, decision, queue, selector, rjms_delay, variant_options)
-{
-    if (variant_options->HasMember("fraction_of_machines_to_use"))
-    {
-        PPK_ASSERT_ERROR((*variant_options)["fraction_of_machines_to_use"].IsNumber(),
-                "Invalid options: 'fraction_of_machines_to_use' should be a number");
-        fraction_of_machines_to_use = (*variant_options)["fraction_of_machines_to_use"].GetDouble();
-        PPK_ASSERT_ERROR(fraction_of_machines_to_use > 0 && fraction_of_machines_to_use <= 1,
-                         "Invalid options: 'fraction_of_machines_to_use' should be in ]0,1] "
-                         "but got value=%g", fraction_of_machines_to_use);
-    }
-
-    if (variant_options->HasMember("custom_mapping"))
-    {
-        PPK_ASSERT_ERROR((*variant_options)["custom_mapping"].IsBool(),
-                "Invalid options: 'custom_mapping' should be a boolean");
-        custom_mapping = (*variant_options)["custom_mapping"].GetBool();
-    }
-
-    if (variant_options->HasMember("set_job_metadata"))
-    {
-        PPK_ASSERT_ERROR((*variant_options)["set_job_metadata"].IsBool(),
-                "Invalid options: 'set_job_metadata' should be a boolean");
-        set_job_metadata = (*variant_options)["set_job_metadata"].GetBool();
-    }
-
-    LOG_SCOPE_FUNCTION(INFO);
-    LOG_F(INFO, "custom_mapping: %s", custom_mapping?"true":"false");
-    LOG_F(INFO, "fraction_of_machines_to_use: %g", fraction_of_machines_to_use);
-    LOG_F(INFO, "set_job_metadata: %d", set_job_metadata);
-}
-
-Filler::~Filler()
-{
-
-}
-
-void Filler::on_simulation_start(double date, const rapidjson::Value & batsim_config)
-{
-    (void) date;
-    (void) batsim_config;
-
-    available_machines.insert(IntervalSet::ClosedInterval(0, _nb_machines - 1));
-    PPK_ASSERT_ERROR(available_machines.size() == (unsigned int) _nb_machines);
-}
-
-void Filler::on_simulation_end(double date)
-{
-    (void) date;
-}
-
-void Filler::make_decisions(double date,
-                            SortableJobOrder::UpdateInformation *update_info,
-                            SortableJobOrder::CompareInformation *compare_info)
-{
-    // Let's update available machines
-    for (const string & ended_job_id : _jobs_ended_recently)
-    {
-        available_machines.insert(current_allocations[ended_job_id]);
-        current_allocations.erase(ended_job_id);
-    }
-
-    // Handle machine (un)availability from user events
-    unavailable_machines -= _machines_that_became_available_recently;
-    unavailable_machines += _machines_that_became_unavailable_recently;
-
-    // Let's handle recently released jobs
-    for (const string & new_job_id : _jobs_released_recently)
-    {
-        const Job * new_job = (*_workload)[new_job_id];
-
-        if (new_job->nb_requested_resources > _nb_machines)
-            _decision->add_reject_job(new_job_id, date);
-        else
-            _queue->append_job(new_job, update_info);
-    }
-
-    // Queue sorting
-    _queue->sort_queue(update_info, compare_info);
-
-    fill(date);
-}
-
-void Filler::fill(double date)
-{
-    IntervalSet usable_machines = available_machines - unavailable_machines;
-    if (_debug)
-        LOG_F(1, "fill, usable_machines=%s", usable_machines.to_string_hyphen().c_str());
-
-    int nb_usable = usable_machines.size();
-    for (auto job_it = _queue->begin(); job_it != _queue->end() && nb_usable > 0; )
-    {
-        const Job * job = (*job_it)->job;
-
-        // If it fits I sits (http://knowyourmeme.com/memes/if-it-fits-i-sits)
-        IntervalSet used_machines;
-
-        if (_selector->fit(job, usable_machines, used_machines))
-        {
-            // Fewer machines might be used that those selected by the fitting algorithm
-            int nb_machines_to_allocate = ceil(fraction_of_machines_to_use * job->nb_requested_resources);
-            PPK_ASSERT_ERROR(nb_machines_to_allocate > 0 && nb_machines_to_allocate <= job->nb_requested_resources);
-            used_machines = used_machines.left(nb_machines_to_allocate);
-
-            if (custom_mapping)
-            {
-                vector<int> executor_to_allocated_resource_mapping;
-                executor_to_allocated_resource_mapping.resize(job->nb_requested_resources);
-                for (int i = 0; i < job->nb_requested_resources; ++i)
-                    executor_to_allocated_resource_mapping[i] = i % nb_machines_to_allocate;
-                _decision->add_execute_job(job->id, used_machines, date, executor_to_allocated_resource_mapping);
-            }
-            else
-            {
-                _decision->add_execute_job(job->id, used_machines, date);
-            }
-
-            current_allocations[job->id] = used_machines;
-
-            usable_machines.remove(used_machines);
-            available_machines.remove(used_machines);
-            nb_usable -= used_machines.size();
-
-            if (set_job_metadata)
-                _decision->add_set_job_metadata(job->id,
-                                                "just some metadata for job " + job->id,
-                                                date);
-
-            job_it = _queue->remove_job(job);
-        }
-        else
-            job_it++;
-    }
-}
diff --git a/src/algo/filler.hpp b/src/algo/filler.hpp
deleted file mode 100644
index 2aa15d94e50a442f02b220e44a984fda3fb613a4..0000000000000000000000000000000000000000
--- a/src/algo/filler.hpp
+++ /dev/null
@@ -1,43 +0,0 @@
-#pragma once
-
-#include "../isalgorithm.hpp"
-
-#include <vector>
-#include <set>
-#include <list>
-#include <map>
-
-#include "../locality.hpp"
-#include <intervalset.hpp>
-
-class Workload;
-class SchedulingDecision;
-
-class Filler : public ISchedulingAlgorithm
-{
-public:
-    Filler(Workload * workload, SchedulingDecision * decision, Queue * queue, ResourceSelector * selector,
-           double rjms_delay, rapidjson::Document * variant_options);
-
-    virtual ~Filler();
-
-    virtual void on_simulation_start(double date, const rapidjson::Value & batsim_config);
-
-    virtual void on_simulation_end(double date);
-
-    virtual void make_decisions(double date,
-                                SortableJobOrder::UpdateInformation * update_info,
-                                SortableJobOrder::CompareInformation * compare_info);
-private:
-    void fill(double date);
-
-private:
-    double fraction_of_machines_to_use = 1; //! In ]0,1]. If job requests 42 machines, the scheduler will allocate ceil(42*rho) machines.
-    bool set_job_metadata = false; //! If set to true, metadata will be associated to jobs when they are started.
-    bool custom_mapping = true;
-
-    IntervalSet available_machines; // Corresponds to classical availability: no job is running on those machines.
-    IntervalSet unavailable_machines; // This is NOT the complement of available_machines! This correspond to user-supplied events, that may overlap strangely with job executions as I write these lines.
-    std::map<std::string, IntervalSet> current_allocations;
-    bool _debug = true;
-};
diff --git a/src/algo/killer.cpp b/src/algo/killer.cpp
deleted file mode 100644
index e0ce47b7243f7b58100bc8acdf5f075b76740bdb..0000000000000000000000000000000000000000
--- a/src/algo/killer.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-#include "killer.hpp"
-
-#include <loguru.hpp>
-
-#include "../pempek_assert.hpp"
-
-using namespace std;
-
-Killer::Killer(Workload *workload,
-               SchedulingDecision *decision,
-               Queue *queue,
-               ResourceSelector *selector,
-               double rjms_delay,
-               rapidjson::Document *variant_options) :
-    ISchedulingAlgorithm(workload, decision, queue, selector, rjms_delay, variant_options)
-{
-    if (variant_options->HasMember("nb_kills_per_job"))
-    {
-        PPK_ASSERT_ERROR((*variant_options)["nb_kills_per_job"].IsInt(),
-                "Bad algo options: nb_kills_per_job should be an integer");
-        nb_kills_per_job = (*variant_options)["nb_kills_per_job"].GetInt();
-        PPK_ASSERT_ERROR(nb_kills_per_job >= 0,
-                         "Bad algo options: nb_kills_per_job should be positive (got %d)",
-                         nb_kills_per_job);
-    }
-
-    if (variant_options->HasMember("delay_before_kill"))
-    {
-        PPK_ASSERT_ERROR((*variant_options)["delay_before_kill"].IsNumber(),
-                "Bad algo options: delay_before_kill should be an integer");
-        delay_before_kill = (*variant_options)["delay_before_kill"].GetDouble();
-        PPK_ASSERT_ERROR(delay_before_kill >= 0,
-                         "Bad algo options: delay_before_kill should be positive (got %g)",
-                         delay_before_kill);
-    }
-
-    LOG_SCOPE_FUNCTION(INFO);
-    LOG_F(INFO, "nb_kills_per_job: %d", nb_kills_per_job);
-    LOG_F(INFO, "delay_before_kill: %g", delay_before_kill);
-}
-
-Killer::~Killer()
-{
-
-}
-
-void Killer::on_simulation_start(double date, const rapidjson::Value & batsim_config)
-{
-    (void) date;
-    (void) batsim_config;
-
-    available_machines.insert(IntervalSet::ClosedInterval(0, _nb_machines - 1));
-    PPK_ASSERT_ERROR(available_machines.size() == (unsigned int) _nb_machines);
-}
-
-void Killer::on_simulation_end(double date)
-{
-    (void) date;
-}
-
-void Killer::make_decisions(double date,
-                            SortableJobOrder::UpdateInformation *update_info,
-                            SortableJobOrder::CompareInformation *compare_info)
-{
-    LOG_F(1, "Date: %g. Available machines: %s", date, available_machines.to_string_brackets().c_str());
-
-    // Let's update available machines
-    for (const string & ended_job_id : _jobs_ended_recently)
-    {
-        int nb_available_before = available_machines.size();
-        available_machines.insert(current_allocations[ended_job_id]);
-        PPK_ASSERT_ERROR(nb_available_before + (*_workload)[ended_job_id]->nb_requested_resources == (int)available_machines.size());
-        current_allocations.erase(ended_job_id);
-    }
-
-    LOG_F(1, "Date: %g. Available machines: %s", date, available_machines.to_string_brackets().c_str());
-
-    // Let's handle recently released jobs
-    for (const string & new_job_id : _jobs_released_recently)
-    {
-        const Job * new_job = (*_workload)[new_job_id];
-
-        if (new_job->nb_requested_resources > _nb_machines)
-            _decision->add_reject_job(new_job_id, date);
-        else
-            _queue->append_job(new_job, update_info);
-    }
-
-    // Queue sorting
-    _queue->sort_queue(update_info, compare_info);
-
-    // Let's now do a scheduling pass.
-    // This algorithm can only execute one job by call, the priority one.
-    // It is executed if it there are enough available resources.
-    // The job kill is then queued 10 secondes after its starting.
-
-    if (!_queue->is_empty())
-    {
-        const Job * job = _queue->first_job();
-
-        if (job->nb_requested_resources <= (int)available_machines.size())
-        {
-            IntervalSet used_machines;
-            if (_selector->fit(job, available_machines, used_machines))
-            {
-                _decision->add_execute_job(job->id, used_machines, date);
-                current_allocations[job->id] = used_machines;
-                available_machines.remove(used_machines);
-                _queue->remove_job(job);
-
-                for (int i = 0; i < nb_kills_per_job; ++i)
-                {
-                    date += delay_before_kill;
-                    _decision->add_kill_job({job->id}, date);
-                }
-            }
-        }
-    }
-
-    LOG_F(1, "Date: %g. Available machines: %s", date, available_machines.to_string_brackets().c_str());
-}
diff --git a/src/algo/killer.hpp b/src/algo/killer.hpp
deleted file mode 100644
index 70c77748d8128c633733f977aca3f2fdbc9ef635..0000000000000000000000000000000000000000
--- a/src/algo/killer.hpp
+++ /dev/null
@@ -1,37 +0,0 @@
-#pragma once
-
-#include "../isalgorithm.hpp"
-
-#include <vector>
-#include <set>
-#include <list>
-#include <map>
-
-#include "../locality.hpp"
-#include <intervalset.hpp>
-
-class Workload;
-class SchedulingDecision;
-
-class Killer : public ISchedulingAlgorithm
-{
-public:
-    Killer(Workload * workload, SchedulingDecision * decision, Queue * queue, ResourceSelector * selector,
-           double rjms_delay, rapidjson::Document * variant_options);
-
-    virtual ~Killer();
-
-    virtual void on_simulation_start(double date, const rapidjson::Value & batsim_config);
-
-    virtual void on_simulation_end(double date);
-
-    virtual void make_decisions(double date,
-                                SortableJobOrder::UpdateInformation * update_info,
-                                SortableJobOrder::CompareInformation * compare_info);
-
-private:
-    IntervalSet available_machines;
-    std::map<std::string, IntervalSet> current_allocations;
-    int nb_kills_per_job = 1;
-    double delay_before_kill = 10;
-};
diff --git a/src/algo/killer2.cpp b/src/algo/killer2.cpp
deleted file mode 100644
index 66f7bc693e9daccb0079566e4f6b8b5a1998758a..0000000000000000000000000000000000000000
--- a/src/algo/killer2.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-#include "killer2.hpp"
-
-#include <loguru.hpp>
-
-#include "../pempek_assert.hpp"
-
-using namespace std;
-
-Killer2::Killer2(Workload *workload,
-               SchedulingDecision *decision,
-               Queue *queue,
-               ResourceSelector *selector,
-               double rjms_delay,
-               rapidjson::Document *variant_options) :
-    ISchedulingAlgorithm(workload, decision, queue, selector, rjms_delay, variant_options)
-{
-
-}
-
-Killer2::~Killer2()
-{
-
-}
-
-void Killer2::on_simulation_start(double date, const rapidjson::Value & batsim_config)
-{
-    (void) date;
-    (void) batsim_config;
-
-    available_machines.insert(IntervalSet::ClosedInterval(0, _nb_machines - 1));
-    PPK_ASSERT_ERROR(available_machines.size() == (unsigned int) _nb_machines);
-}
-
-void Killer2::on_simulation_end(double date)
-{
-    (void) date;
-}
-
-void Killer2::make_decisions(double date,
-                            SortableJobOrder::UpdateInformation *update_info,
-                            SortableJobOrder::CompareInformation *compare_info)
-{
-    LOG_F(1, "Date: %g. Available machines: %s", date, available_machines.to_string_brackets().c_str());
-
-    // Let's update available machines
-    for (const string & ended_job_id : _jobs_ended_recently)
-    {
-        int nb_available_before = available_machines.size();
-        available_machines.insert(current_allocations[ended_job_id]);
-        PPK_ASSERT_ERROR(nb_available_before + (int)current_allocations[ended_job_id].size() == (int)available_machines.size());
-        current_allocations.erase(ended_job_id);
-    }
-
-    LOG_F(1, "Date: %g. Available machines: %s", date, available_machines.to_string_brackets().c_str());
-
-    // Let's handle recently released jobs
-    for (const string & new_job_id : _jobs_released_recently)
-    {
-        const Job * new_job = (*_workload)[new_job_id];
-
-        if (new_job->nb_requested_resources > _nb_machines)
-            _decision->add_reject_job(new_job_id, date);
-        else
-            _queue->append_job(new_job, update_info);
-    }
-
-    // Queue sorting
-    _queue->sort_queue(update_info, compare_info);
-
-    if (!_queue->is_empty())
-    {
-        const Job * job = _queue->first_job();
-
-        // Kill the job if it is running
-        if (current_allocations.size() > 0)
-        {
-            PPK_ASSERT_ERROR(current_allocations.size() == 1);
-            string running_job = current_allocations.begin()->first;
-
-            _decision->add_kill_job({running_job}, date);
-            available_machines.insert(current_allocations[running_job]);
-            current_allocations.erase(running_job);
-            date += 5; // The execution will be 5 seconds after the kill
-        }
-
-        // Run the priority job
-        IntervalSet used_machines;
-        bool fitted = _selector->fit(job, available_machines, used_machines);
-        PPK_ASSERT_ERROR(fitted);
-
-        _decision->add_execute_job(job->id, used_machines, date);
-        current_allocations[job->id] = used_machines;
-
-        available_machines.remove(used_machines);
-        _queue->remove_job(job);
-    }
-
-    LOG_F(1, "Date: %g. Available machines: %s", date, available_machines.to_string_brackets().c_str());
-}
diff --git a/src/algo/killer2.hpp b/src/algo/killer2.hpp
deleted file mode 100644
index 9242b46b64ce6472660b3b576d54328343eb079e..0000000000000000000000000000000000000000
--- a/src/algo/killer2.hpp
+++ /dev/null
@@ -1,35 +0,0 @@
-#pragma once
-
-#include "../isalgorithm.hpp"
-
-#include <vector>
-#include <set>
-#include <list>
-#include <map>
-
-#include "../locality.hpp"
-#include <intervalset.hpp>
-
-class Workload;
-class SchedulingDecision;
-
-class Killer2 : public ISchedulingAlgorithm
-{
-public:
-    Killer2(Workload * workload, SchedulingDecision * decision, Queue * queue, ResourceSelector * selector,
-           double rjms_delay, rapidjson::Document * variant_options);
-
-    virtual ~Killer2();
-
-    virtual void on_simulation_start(double date, const rapidjson::Value & batsim_config);
-
-    virtual void on_simulation_end(double date);
-
-    virtual void make_decisions(double date,
-                                SortableJobOrder::UpdateInformation * update_info,
-                                SortableJobOrder::CompareInformation * compare_info);
-
-private:
-    IntervalSet available_machines;
-    std::map<std::string, IntervalSet> current_allocations;
-};
diff --git a/src/algo/random.cpp b/src/algo/random.cpp
deleted file mode 100644
index 2377e20fffd99dbd7072204ae5658b977f290d5b..0000000000000000000000000000000000000000
--- a/src/algo/random.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-#include "random.hpp"
-
-#include "../pempek_assert.hpp"
-
-using namespace std;
-
-Random::Random(Workload * workload,
-               SchedulingDecision * decision,
-               Queue * queue,
-               ResourceSelector * selector,
-               double rjms_delay,
-               rapidjson::Document * variant_options) :
-    ISchedulingAlgorithm(workload, decision, queue, selector, rjms_delay, variant_options)
-{
-
-}
-
-Random::~Random()
-{
-
-}
-
-void Random::on_simulation_start(double date, const rapidjson::Value & batsim_config)
-{
-    (void) date;
-
-    machines.insert(IntervalSet::ClosedInterval(0, _nb_machines - 1));
-    PPK_ASSERT_ERROR(machines.size() == (unsigned int) _nb_machines);
-
-    // TODO: print warning if time sharing is disabled
-    (void) batsim_config;
-}
-
-void Random::on_simulation_end(double date)
-{
-    (void) date;
-}
-
-void Random::make_decisions(double date,
-                            SortableJobOrder::UpdateInformation *update_info,
-                            SortableJobOrder::CompareInformation *compare_info)
-{
-    (void) update_info;
-    (void) compare_info;
-
-    /* This algorithm does not care whether machines are in use, it does not even store it.
-     * Jobs are allocated to random machines as soon as they are submitted. */
-
-    PPK_ASSERT_ERROR(_jobs_killed_recently.size() == 0,
-                     "Jobs have been killed, which should not happen with this algorithm.");
-
-    // Let's handle recently released jobs
-    for (const string & new_job_id : _jobs_released_recently)
-    {
-        const Job * new_job = (*_workload)[new_job_id];
-
-        if (new_job->nb_requested_resources > _nb_machines)
-        {
-            // The job is too big for the machine -> reject
-            _decision->add_reject_job(new_job_id, date);
-        }
-        else
-        {
-            // THe job fits in the machine -> executed right now
-            _decision->add_execute_job(new_job->id,
-                                       machines.random_pick(new_job->nb_requested_resources),
-                                       date);
-        }
-    }
-}
-
diff --git a/src/algo/random.hpp b/src/algo/random.hpp
deleted file mode 100644
index dda59207fb6407f5ad87732286dffd7df34858bb..0000000000000000000000000000000000000000
--- a/src/algo/random.hpp
+++ /dev/null
@@ -1,23 +0,0 @@
-#pragma once
-
-#include "../isalgorithm.hpp"
-
-class Random : public ISchedulingAlgorithm
-{
-public:
-    Random(Workload * workload, SchedulingDecision * decision, Queue * queue, ResourceSelector * selector,
-           double rjms_delay, rapidjson::Document * variant_options);
-
-    virtual ~Random();
-
-    virtual void on_simulation_start(double date, const rapidjson::Value & batsim_config);
-
-    virtual void on_simulation_end(double date);
-
-    virtual void make_decisions(double date,
-                                SortableJobOrder::UpdateInformation * update_info,
-                                SortableJobOrder::CompareInformation * compare_info);
-
-private:
-    IntervalSet machines;
-};
diff --git a/src/algo/sequencer_dvfs.cpp b/src/algo/sequencer_dvfs.cpp
deleted file mode 100644
index d4a21c721bf7c7bc338c39c6745f471b33a32cbd..0000000000000000000000000000000000000000
--- a/src/algo/sequencer_dvfs.cpp
+++ /dev/null
@@ -1,118 +0,0 @@
-#include "sequencer_dvfs.hpp"
-
-#include <loguru.hpp>
-
-#include "../pempek_assert.hpp"
-
-SequencerDVFS::SequencerDVFS(Workload *workload,
-                   SchedulingDecision *decision,
-                   Queue *queue,
-                   ResourceSelector *selector,
-                   double rjms_delay,
-                   rapidjson::Document *variant_options) :
-    ISchedulingAlgorithm(workload, decision, queue, selector, rjms_delay, variant_options)
-{
-    PPK_ASSERT_ERROR(variant_options->HasMember("monitoring_period"), "invalid options: 'monitoring_period' is missing");
-    PPK_ASSERT_ERROR((*variant_options)["monitoring_period"].IsNumber(), "invalid options: 'monitoring_period' is not a number");
-    _monitoring_period = (*variant_options)["monitoring_period"].GetDouble();
-    PPK_ASSERT_ERROR(_monitoring_period > 0, "invalid options: 'monitoring period' should be strictly positive but got %g", _monitoring_period);
-
-    PPK_ASSERT_ERROR(variant_options->HasMember("pstate_compute_fast"), "invalid options: 'pstate_compute_fast' is missing");
-    PPK_ASSERT_ERROR((*variant_options)["pstate_compute_fast"].IsNumber(), "invalid options: 'pstate_compute_fast' is not a number");
-    _pstate_compute_fast = (*variant_options)["pstate_compute_fast"].GetInt();
-    PPK_ASSERT_ERROR(_pstate_compute_fast >= 0, "invalid options: 'pstate_compute_fast period' should be positive but got %d", _pstate_compute_fast);
-
-    PPK_ASSERT_ERROR(variant_options->HasMember("pstate_compute_slow"), "invalid options: 'pstate_compute_slow' is missing");
-    PPK_ASSERT_ERROR((*variant_options)["pstate_compute_slow"].IsNumber(), "invalid options: 'pstate_compute_slow' is not a number");
-    _pstate_compute_slow = (*variant_options)["pstate_compute_slow"].GetInt();
-    PPK_ASSERT_ERROR(_pstate_compute_slow >= 0, "invalid options: 'pstate_compute_slow period' should be positive but got %d", _pstate_compute_slow);
-
-    PPK_ASSERT_ERROR(_pstate_compute_fast != _pstate_compute_slow, "invalid options: 'pstate_compute_fast' and 'pstate_compute_slow' should be different but both have value %d", _pstate_compute_fast);
-
-    LOG_SCOPE_FUNCTION(INFO);
-    LOG_F(INFO, "monitoring_period: %g", _monitoring_period);
-    LOG_F(INFO, "pstate_compute_fast: %d", _pstate_compute_fast);
-    LOG_F(INFO, "pstate_compute_slow: %d", _pstate_compute_slow);
-}
-
-SequencerDVFS::~SequencerDVFS()
-{
-
-}
-
-void SequencerDVFS::on_simulation_start(double date, const rapidjson::Value &batsim_config)
-{
-    (void) date;
-    (void) batsim_config;
-
-    _machines.insert(IntervalSet::ClosedInterval(0, _nb_machines - 1));
-    PPK_ASSERT_ERROR(_machines.size() == (unsigned int) _nb_machines);
-
-    // Request the initial future call. Future ones will be requested in the on_requested_call function.
-    _decision->add_call_me_later(date + _monitoring_period, date);
-}
-
-void SequencerDVFS::on_simulation_end(double date)
-{
-}
-
-void SequencerDVFS::on_requested_call(double date)
-{
-    LOG_SCOPE_FUNCTION(INFO);
-    LOG_F(INFO, "requested call received!");
-
-    // Request a future call at current date + period (unless simulation is about to finish)
-    if (!_no_more_static_job_to_submit_received || _is_job_running)
-    {
-        _decision->add_call_me_later(date + _monitoring_period, date);
-    }
-
-    // Toggle DVFS state of allocated machines if a job is being run
-    if (_is_job_running)
-    {
-        int new_pstate = _currently_fast ? _pstate_compute_slow : _pstate_compute_fast;
-        _decision->add_set_resource_state(_allocated_machines, new_pstate, date);
-        _currently_fast = !_currently_fast;
-    }
-}
-
-void SequencerDVFS::make_decisions(double date,
-                              SortableJobOrder::UpdateInformation *update_info,
-                              SortableJobOrder::CompareInformation *compare_info)
-{
-    // This algorithm executes all the jobs, one after the other.
-    // At any time, either 0 or 1 job is running on the platform.
-    // The order of the sequence depends on the queue order.
-
-    // Up to one job finished since last call.
-    PPK_ASSERT_ERROR(_jobs_ended_recently.size() <= 1);
-    if (!_jobs_ended_recently.empty())
-    {
-        PPK_ASSERT_ERROR(_is_job_running);
-        _is_job_running = false;
-    }
-
-    // Add valid jobs into the queue
-    for (const std::string & job_id : _jobs_released_recently)
-    {
-        const Job * job = (*_workload)[job_id];
-
-        if (job->nb_requested_resources <= _nb_machines)
-            _queue->append_job(job, update_info);
-        else
-            _decision->add_reject_job(job->id, date);
-    }
-
-    // Sort queue if needed
-    _queue->sort_queue(update_info, compare_info);
-
-    // Execute the first job if the machine is empty
-    const Job * job = _queue->first_job_or_nullptr();
-    if (job != nullptr && !_is_job_running)
-    {
-        _allocated_machines = _machines.left(job->nb_requested_resources);
-        _decision->add_execute_job(job->id, _allocated_machines, date);
-        _is_job_running = true;
-        _queue->remove_job(job);
-    }
-}
diff --git a/src/algo/sequencer_dvfs.hpp b/src/algo/sequencer_dvfs.hpp
deleted file mode 100644
index 018f2495dcaf22e05774341faa49cb999bd9a2b6..0000000000000000000000000000000000000000
--- a/src/algo/sequencer_dvfs.hpp
+++ /dev/null
@@ -1,38 +0,0 @@
-#pragma once
-
-#include "../isalgorithm.hpp"
-
-#include "../locality.hpp"
-#include <intervalset.hpp>
-
-class Workload;
-class SchedulingDecision;
-
-class SequencerDVFS : public ISchedulingAlgorithm
-{
-public:
-    SequencerDVFS(Workload * workload, SchedulingDecision * decision, Queue * queue, ResourceSelector * selector,
-             double rjms_delay, rapidjson::Document * variant_options);
-
-    virtual ~SequencerDVFS();
-
-    virtual void on_simulation_start(double date, const rapidjson::Value & batsim_config);
-
-    virtual void on_simulation_end(double date);
-
-    virtual void on_requested_call(double date);
-
-    virtual void make_decisions(double date,
-                                SortableJobOrder::UpdateInformation * update_info,
-                                SortableJobOrder::CompareInformation * compare_info);
-
-private:
-    IntervalSet _machines;
-    IntervalSet _allocated_machines;
-    bool _is_job_running = false;
-    double _monitoring_period = -1;
-
-    int _pstate_compute_fast = -1;
-    int _pstate_compute_slow = -1;
-    bool _currently_fast = true;
-};
diff --git a/src/algo/sleeper.cpp b/src/algo/sleeper.cpp
deleted file mode 100644
index 04bd771f8700136827c6b7f57e3705abb09c7a94..0000000000000000000000000000000000000000
--- a/src/algo/sleeper.cpp
+++ /dev/null
@@ -1,192 +0,0 @@
-#include "sleeper.hpp"
-
-#include <iostream>
-
-#include "../pempek_assert.hpp"
-
-using namespace std;
-
-Sleeper::Sleeper(Workload * workload, SchedulingDecision * decision, Queue * queue, ResourceSelector * selector,
-                 double rjms_delay, rapidjson::Document * variant_options) :
-    ISchedulingAlgorithm(workload, decision, queue, selector, rjms_delay, variant_options)
-{
-    PPK_ASSERT_ERROR(variant_options->HasMember("pstate_compute"), "Invalid options JSON object: Member 'pstate_compute' cannot be found");
-    PPK_ASSERT_ERROR((*variant_options)["pstate_compute"].IsInt(), "Invalid options JSON object: Member 'pstate_compute' must be integral");
-    int pstate_compute = (*variant_options)["pstate_compute"].GetInt();
-    PPK_ASSERT_ERROR(pstate_compute >= 0, "Invalid options JSON object: Member 'pstate_compute' value must be positive (got %d)", pstate_compute);
-    compute_pstate = pstate_compute;
-
-    PPK_ASSERT_ERROR(variant_options->HasMember("pstate_sleep"), "Invalid options JSON object: Member 'pstate_sleep' cannot be found");
-    PPK_ASSERT_ERROR((*variant_options)["pstate_sleep"].IsInt(), "Invalid options JSON object: Member 'pstate_sleep' must be integral");
-    int pstate_sleep = (*variant_options)["pstate_sleep"].GetInt();
-    PPK_ASSERT_ERROR(pstate_sleep >= 0, "Invalid options JSON object: Member 'pstate_sleep' value must be positive (got %d)", pstate_sleep);
-    sleep_pstate = pstate_sleep;
-}
-
-Sleeper::~Sleeper()
-{
-
-}
-
-void Sleeper::on_simulation_start(double date, const rapidjson::Value &batsim_config)
-{
-    (void) date;
-    (void) batsim_config;
-
-    all_machines.insert(IntervalSet::ClosedInterval(0, _nb_machines - 1));
-    available_machines = all_machines;
-}
-
-void Sleeper::on_simulation_end(double date)
-{
-    (void) date;
-
-    simulation_finished = true;
-}
-
-void Sleeper::make_decisions(double date, SortableJobOrder::UpdateInformation *update_info, SortableJobOrder::CompareInformation *compare_info)
-{
-    // Let's handle recently ended jobs
-    PPK_ASSERT_ERROR(_jobs_ended_recently.size() == 0 || _jobs_ended_recently.size() == 1);
-    if (_jobs_ended_recently.size() > 0)
-    {
-        string ended_job_id = _jobs_ended_recently[0];
-        const Job * finished_job = (*_workload)[ended_job_id];
-        PPK_ASSERT_ERROR(job_being_computed == ended_job_id);
-
-        job_being_computed = "";
-
-        PPK_ASSERT_ERROR(finished_job->nb_requested_resources == (int) computing_machines.size());
-        available_machines.insert(computing_machines);
-        computing_machines.clear();
-    }
-
-    // Let's handle recently released jobs
-    for (const string & new_job_id : _jobs_released_recently)
-    {
-        const Job * new_job = (*_workload)[new_job_id];
-
-        if (new_job->nb_requested_resources > _nb_machines)
-            _decision->add_reject_job(new_job_id, date);
-        else
-            _queue->append_job(new_job, update_info);
-    }
-
-    // Let's handle machine power state alterations
-    for (auto mit : _machines_whose_pstate_changed_recently)
-    {
-        const int & new_pstate = mit.first;
-        const IntervalSet & machines = mit.second;
-
-        PPK_ASSERT_ERROR(new_pstate == compute_pstate || new_pstate == sleep_pstate);
-
-        if (new_pstate == compute_pstate)
-        {
-            PPK_ASSERT_ERROR(machines == (machines & machines_being_switched_on));
-
-            machines_being_switched_on.remove(machines);
-            available_machines.insert(machines);
-        }
-        else if (new_pstate == sleep_pstate)
-        {
-            PPK_ASSERT_ERROR(machines == (machines & machines_being_switched_off));
-
-            machines_being_switched_off.remove(machines);
-            sleeping_machines.insert(machines);
-        }
-    }
-
-    // Queue sorting
-    _queue->sort_queue(update_info, compare_info);
-
-    /* This algorithm will ensure that 0 or 1 job is being computed at any given time.
-     * Only the first job of the queue can be computed.
-     *
-     * Unneeded resources will be put to sleep.
-     * Resources can be awakened in order to run a job.
-     */
-
-    if (!_queue->is_empty())
-    {
-        // There are jobs to compute
-        const Job * job = _queue->first_job();
-
-        if (job_being_computed == "")
-        {
-            PPK_ASSERT_ERROR(computing_machines.size() == 0);
-            // No job is being computed now. We should then run the job!
-            if ((int)available_machines.size() >= job->nb_requested_resources)
-            {
-                // The job can be executed right now
-                IntervalSet alloc = available_machines.left(job->nb_requested_resources);
-                _decision->add_execute_job(job->id, alloc, date);
-
-                // Let's update machine states
-                available_machines.remove(alloc);
-                computing_machines.insert(alloc);
-
-                // Let's put unused machines into sleep
-                if (available_machines.size() > 0)
-                {
-                    _decision->add_set_resource_state(available_machines, sleep_pstate, date);
-                    machines_being_switched_off.insert(available_machines);
-                    available_machines.clear();
-                }
-
-                job_being_computed = job->id;
-                _queue->remove_job(job);
-            }
-            else
-            {
-                // There are not enough available machine now to run the job
-                int future_nb_avail = available_machines.size() + machines_being_switched_on.size();
-
-                if (future_nb_avail < job->nb_requested_resources)
-                {
-                    // Some machines must be ordered to wake up so the job can run.
-                    int nb_machines_to_wake_up = job->nb_requested_resources - future_nb_avail;
-                    int nb_machines_to_order_to_wake_up = std::min((int)sleeping_machines.size(), nb_machines_to_wake_up);
-
-                    if (nb_machines_to_order_to_wake_up > 0)
-                    {
-                        // Decision
-                        IntervalSet machines_to_order_to_wake_up = sleeping_machines.left(nb_machines_to_order_to_wake_up);
-                        _decision->add_set_resource_state(machines_to_order_to_wake_up, compute_pstate, date);
-
-                        // Machines state update
-                        sleeping_machines.remove(machines_to_order_to_wake_up);
-                        machines_being_switched_on.insert(machines_to_order_to_wake_up);
-                    }
-                }
-                else
-                {
-                    // Machines are already being waken up, there is nothing to do.
-                }
-            }
-        }
-        else
-        {
-            // A job is already being computed, there is nothing to do but to put as much machines as possible to sleep
-
-            // Let's put unused machines into sleep
-            if (available_machines.size() > 0)
-            {
-                _decision->add_set_resource_state(available_machines, sleep_pstate, date);
-                machines_being_switched_off.insert(available_machines);
-                available_machines.clear();
-            }
-        }
-    }
-    else if (!simulation_finished)
-    {
-        // There are no jobs to compute at the moment.
-
-        // Let's put unused machines into sleep
-        if (available_machines.size() > 0)
-        {
-            _decision->add_set_resource_state(available_machines, sleep_pstate, date);
-            machines_being_switched_off.insert(available_machines);
-            available_machines.clear();
-        }
-    }
-}
diff --git a/src/algo/sleeper.hpp b/src/algo/sleeper.hpp
deleted file mode 100644
index 71346adc497cb56b0ff28f3c49b28ddb59579ea2..0000000000000000000000000000000000000000
--- a/src/algo/sleeper.hpp
+++ /dev/null
@@ -1,40 +0,0 @@
-#pragma once
-
-#include <list>
-
-#include "../isalgorithm.hpp"
-#include "../json_workload.hpp"
-#include "../locality.hpp"
-
-class Sleeper : public ISchedulingAlgorithm
-{
-public:
-    Sleeper(Workload * workload, SchedulingDecision * decision, Queue * queue, ResourceSelector * selector,
-            double rjms_delay, rapidjson::Document * variant_options);
-
-    virtual ~Sleeper();
-
-    virtual void on_simulation_start(double date, const rapidjson::Value & batsim_config);
-
-    virtual void on_simulation_end(double date);
-
-    void make_decisions(double date,
-                        SortableJobOrder::UpdateInformation * update_info,
-                        SortableJobOrder::CompareInformation * compare_info);
-
-
-private:
-    IntervalSet all_machines;
-
-    IntervalSet available_machines;
-    IntervalSet computing_machines;
-    IntervalSet sleeping_machines;
-    IntervalSet machines_being_switched_on;
-    IntervalSet machines_being_switched_off;
-
-    std::string job_being_computed = "";
-
-    int compute_pstate;
-    int sleep_pstate;
-    bool simulation_finished = false;
-};
diff --git a/src/algo/submitter.cpp b/src/algo/submitter.cpp
deleted file mode 100644
index 3d5735d656d73418593a615c5c20d2f24a9b2fe9..0000000000000000000000000000000000000000
--- a/src/algo/submitter.cpp
+++ /dev/null
@@ -1,230 +0,0 @@
-#include "submitter.hpp"
-
-#include <loguru.hpp>
-
-#include "../pempek_assert.hpp"
-
-using namespace std;
-
-Submitter::Submitter(Workload *workload, SchedulingDecision *decision, Queue *queue,
-                     ResourceSelector *selector, double rjms_delay,
-                     rapidjson::Document *variant_options) :
-    ISchedulingAlgorithm(workload, decision, queue, selector, rjms_delay, variant_options)
-{
-
-    if (variant_options->HasMember("nb_jobs_to_submit"))
-    {
-        PPK_ASSERT_ERROR((*variant_options)["nb_jobs_to_submit"].IsInt(),
-                         "Bad algo options: nb_jobs_to_submit is not integral");
-        nb_jobs_to_submit = (*variant_options)["nb_jobs_to_submit"].GetInt();
-        PPK_ASSERT_ERROR(nb_jobs_to_submit >= 0,
-                         "Bad algo options: nb_jobs_to_submit is negative (%d)", nb_jobs_to_submit);
-    }
-
-    if (variant_options->HasMember("increase_jobs_duration"))
-    {
-        PPK_ASSERT_ERROR((*variant_options)["increase_jobs_duration"].IsBool(),
-                         "Bad algo options: increase_jobs_duration is not a boolean");
-        increase_jobs_duration = (*variant_options)["increase_jobs_duration"].GetBool();
-    }
-
-    if (variant_options->HasMember("send_profile_if_already_sent"))
-    {
-        PPK_ASSERT_ERROR((*variant_options)["send_profile_if_already_sent"].IsBool(),
-                         "Bad algo options: send_profile_if_already_sent is not a boolean");
-        send_profile_if_already_sent = (*variant_options)["send_profile_if_already_sent"].GetBool();
-    }
-
-    if (variant_options->HasMember("send_profiles_in_separate_event"))
-    {
-        PPK_ASSERT_ERROR((*variant_options)["send_profiles_in_separate_event"].IsBool(),
-                         "Bad algo options: send_profiles_in_separate_event is not a boolean");
-        send_profiles_in_separate_event = (*variant_options)["send_profiles_in_separate_event"].GetBool();
-    }
-
-    if (variant_options->HasMember("set_job_metadata"))
-    {
-        PPK_ASSERT_ERROR((*variant_options)["set_job_metadata"].IsBool(),
-                "Invalid options: 'set_job_metadata' should be a boolean");
-        set_job_metadata = (*variant_options)["set_job_metadata"].GetBool();
-    }
-
-    LOG_SCOPE_FUNCTION(INFO);
-    LOG_F(INFO, "nb_jobs_to_submit: %d", nb_jobs_to_submit);
-    LOG_F(INFO, "increase_jobs_duration: %d", increase_jobs_duration);
-    LOG_F(INFO, "send_profile_if_already_sent: %d", send_profile_if_already_sent);
-    LOG_F(INFO, "send_profiles_in_separate_event: %d", send_profiles_in_separate_event);
-    LOG_F(INFO, "set_job_metadata: %d", set_job_metadata);
-}
-
-Submitter::~Submitter()
-{
-
-}
-
-void Submitter::on_simulation_start(double date, const rapidjson::Value & batsim_config)
-{
-    (void) date;
-
-    available_machines.insert(IntervalSet::ClosedInterval(0, _nb_machines - 1));
-    PPK_ASSERT_ERROR(available_machines.size() == (unsigned int) _nb_machines);
-
-    PPK_ASSERT_ERROR(batsim_config["dynamic-jobs-enabled"].GetBool(),
-            "This algorithm only works if dynamic job are enabled!");
-    dyn_submit_ack = batsim_config["dynamic-jobs-acknowledged"].GetBool();
-}
-
-void Submitter::on_simulation_end(double date)
-{
-    (void) date;
-}
-
-void Submitter::make_decisions(double date,
-                               SortableJobOrder::UpdateInformation *update_info,
-                               SortableJobOrder::CompareInformation *compare_info)
-{
-    // Let's update available machines
-    if (_jobs_ended_recently.size() > 0)
-    {
-        for (const string & ended_job_id : _jobs_ended_recently)
-        {
-            int nb_available_before = available_machines.size();
-            available_machines.insert(current_allocations[ended_job_id]);
-            PPK_ASSERT_ERROR(nb_available_before + (*_workload)[ended_job_id]->nb_requested_resources == (int)available_machines.size());
-            current_allocations.erase(ended_job_id);
-        }
-    }
-
-    // Let's handle recently released jobs
-    for (const string & new_job_id : _jobs_released_recently)
-    {
-        const Job * new_job = (*_workload)[new_job_id];
-
-        if (set_job_metadata)
-        {
-            _decision->add_set_job_metadata(new_job_id,
-                                            "just some metadata for job " + new_job_id,
-                                            date);
-        }
-
-        if (new_job->nb_requested_resources > _nb_machines)
-            _decision->add_reject_job(new_job_id, date);
-        else
-            _queue->append_job(new_job, update_info);
-    }
-
-    // Queue sorting
-    _queue->sort_queue(update_info, compare_info);
-
-    // Trying to execute the priority job if possible
-    if (!_queue->is_empty())
-    {
-        const Job * job = _queue->first_job();
-
-        if (job->nb_requested_resources <= (int)available_machines.size())
-        {
-            IntervalSet used_machines;
-            if (_selector->fit(job, available_machines, used_machines))
-            {
-                _decision->add_execute_job(job->id, used_machines, date);
-                current_allocations[job->id] = used_machines;
-
-                available_machines.remove(used_machines);
-                _queue->remove_job(job);
-            }
-        }
-    }
-
-    // If the queue is empty, dynamic jobs are submitted if possible
-    if (_queue->is_empty() && available_machines.size() >= 1)
-    {
-        if (nb_submitted_jobs < nb_jobs_to_submit)
-        {
-            double new_job_duration = 1;
-            if (increase_jobs_duration)
-                new_job_duration += nb_submitted_jobs*10;
-
-            submit_delay_job(new_job_duration, date);
-
-            // If dynamic submissions acknowledgements are disabled, the job is directly executed
-            if (!dyn_submit_ack)
-            {
-                // The execution is done 10 seconds after submitting the job
-                date = date + 10;
-
-                IntervalSet used_machines = available_machines.left(1);
-
-                string job_id = "dynamic!" + to_string(nb_submitted_jobs);
-                _decision->add_execute_job(job_id, used_machines, date);
-                current_allocations[job_id] = used_machines;
-
-                available_machines.remove(used_machines);
-            }
-
-            ++nb_submitted_jobs;
-        }
-    }
-
-    // Sending the "end of dynamic submissions" to Batsim if needed
-    if ((nb_submitted_jobs >= nb_jobs_to_submit) && !finished_submitting_sent)
-    {
-        _decision->add_scheduler_finished_submitting_jobs(date);
-        finished_submitting_sent = true;
-    }
-}
-
-void Submitter::submit_delay_job(double delay, double date)
-{
-    string workload_name = "dynamic";
-
-    double submit_time = date;
-    double walltime = delay + 5;
-    int res = 1;
-    string profile = "delay_" + std::to_string(delay);
-
-    int buf_size = 128;
-
-    string job_id = to_string(nb_submitted_jobs);
-    string unique_job_id = workload_name + "!" + job_id;
-
-    char * buf_job = new char[buf_size];
-    int nb_chars = snprintf(buf_job, buf_size,
-             R"foo({"id":"%s", "subtime":%g, "walltime":%g, "res":%d, "profile":"%s"})foo",
-             job_id.c_str(), submit_time, walltime, res, profile.c_str());
-    PPK_ASSERT_ERROR(nb_chars < buf_size - 1);
-
-    char * buf_profile = new char[buf_size];
-    nb_chars = snprintf(buf_profile, buf_size,
-            R"foo({"type": "delay", "delay": %g})foo", delay);
-    PPK_ASSERT_ERROR(nb_chars < buf_size - 1);
-
-    bool already_sent_profile = profiles_already_sent.count(profile) == 1;
-
-    bool send_profile = !already_sent_profile || send_profile_if_already_sent;
-
-    if (send_profile && send_profiles_in_separate_event)
-        _decision->add_submit_profile(workload_name, profile, buf_profile, date);
-
-    _decision->add_submit_job(workload_name, job_id, profile,
-                              buf_job, buf_profile, date,
-                              send_profile && !send_profiles_in_separate_event);
-
-    if (set_job_metadata)
-    {
-        string job_id_str = workload_name + "!" + job_id;
-        _decision->add_set_job_metadata(job_id_str,
-                                        "just some metadata for job " + job_id_str,
-                                        date);
-    }
-
-    profiles_already_sent.insert(profile);
-
-    // If dynamic submisions ack is disabled, we must add the job in the workload now
-    if (!dyn_submit_ack)
-    {
-        _workload->add_job_from_json_description_string(buf_job, unique_job_id, date);
-    }
-
-    delete[] buf_job;
-    delete[] buf_profile;
-}
diff --git a/src/algo/submitter.hpp b/src/algo/submitter.hpp
deleted file mode 100644
index 89aeef02d87dd70aad0026f03bda81b4f7f88094..0000000000000000000000000000000000000000
--- a/src/algo/submitter.hpp
+++ /dev/null
@@ -1,50 +0,0 @@
-#pragma once
-
-#include "../isalgorithm.hpp"
-
-#include <vector>
-#include <set>
-#include <list>
-#include <map>
-
-#include "../locality.hpp"
-#include <intervalset.hpp>
-
-class Workload;
-class SchedulingDecision;
-
-class Submitter : public ISchedulingAlgorithm
-{
-public:
-    Submitter(Workload * workload, SchedulingDecision * decision, Queue * queue,
-              ResourceSelector * selector, double rjms_delay,
-              rapidjson::Document * variant_options);
-
-    virtual ~Submitter();
-
-    virtual void on_simulation_start(double date, const rapidjson::Value & batsim_config);
-
-    virtual void on_simulation_end(double date);
-
-    virtual void make_decisions(double date,
-                                SortableJobOrder::UpdateInformation * update_info,
-                                SortableJobOrder::CompareInformation * compare_info);
-
-protected:
-    void submit_delay_job(double delay, double date);
-
-private:
-    IntervalSet available_machines;
-    std::map<std::string, IntervalSet> current_allocations;
-    int nb_submitted_jobs = 0; //!< The number of jobs submitted from this algorithm
-    int nb_jobs_to_submit = 10; //!< The number of jobs to submit
-    bool increase_jobs_duration = true; //!< Whether the duration of the submitted jobs increases or not. If false, the same profile will be used by all the submitted jobs.
-    bool send_profile_if_already_sent = false; //!< Whether already transmitted profiles should be sent again to Batsim or not.
-    bool send_profiles_in_separate_event = true; //!< Whether profiles should be sent in a separate message or not
-    bool set_job_metadata = false; //! If set to true, metadata will be associated to jobs when they are submitted.
-
-    bool dyn_submit_ack;
-    bool finished_submitting_sent = false;
-
-    std::set<std::string> profiles_already_sent;
-};
diff --git a/src/algo/wt_estimator.cpp b/src/algo/wt_estimator.cpp
deleted file mode 100644
index 615d6beaac18ae1222821973df11d479cca98b51..0000000000000000000000000000000000000000
--- a/src/algo/wt_estimator.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-#include "wt_estimator.hpp"
-
-WaitingTimeEstimator::WaitingTimeEstimator(Workload *workload,
-                   SchedulingDecision *decision,
-                   Queue *queue,
-                   ResourceSelector *selector,
-                   double rjms_delay,
-                   rapidjson::Document *variant_options) :
-    ISchedulingAlgorithm(workload, decision, queue, selector, rjms_delay, variant_options)
-{
-
-}
-
-WaitingTimeEstimator::~WaitingTimeEstimator()
-{
-
-}
-
-void WaitingTimeEstimator::on_simulation_start(double date, const rapidjson::Value &batsim_config)
-{
-    (void) date;
-    (void) batsim_config;
-}
-
-void WaitingTimeEstimator::on_simulation_end(double date)
-{
-    (void) date;
-}
-
-void WaitingTimeEstimator::make_decisions(double date,
-                                          SortableJobOrder::UpdateInformation *update_info,
-                                          SortableJobOrder::CompareInformation *compare_info)
-{
-    (void) update_info;
-    (void) compare_info;
-
-    /* Another stupid algorithm.
-     * This one rejects all jobs.
-     * It also estimates a negative waiting time for all jobs, as they will never be launched.
-     */
-
-    for (const std::string & job_id : _jobs_whose_waiting_time_estimation_has_been_requested_recently)
-        _decision->add_answer_estimate_waiting_time(job_id, -1, date);
-
-    for (const std::string & job_id : _jobs_released_recently)
-        _decision->add_reject_job(job_id, date);
-}
diff --git a/src/algo/wt_estimator.hpp b/src/algo/wt_estimator.hpp
deleted file mode 100644
index b10bd7bc21a12eae09f96b3f3eb8009c1351d945..0000000000000000000000000000000000000000
--- a/src/algo/wt_estimator.hpp
+++ /dev/null
@@ -1,26 +0,0 @@
-#pragma once
-
-#include "../isalgorithm.hpp"
-
-#include "../locality.hpp"
-#include <intervalset.hpp>
-
-class Workload;
-class SchedulingDecision;
-
-class WaitingTimeEstimator : public ISchedulingAlgorithm
-{
-public:
-    WaitingTimeEstimator(Workload * workload, SchedulingDecision * decision, Queue * queue, ResourceSelector * selector,
-                         double rjms_delay, rapidjson::Document * variant_options);
-
-    virtual ~WaitingTimeEstimator();
-
-    void on_simulation_start(double date, const rapidjson::Value & batsim_config);
-
-    void on_simulation_end(double date);
-
-    virtual void make_decisions(double date,
-                                SortableJobOrder::UpdateInformation * update_info,
-                                SortableJobOrder::CompareInformation * compare_info);
-};
diff --git a/src/main.cpp b/src/main.cpp
index 56b245fc710e419831778b3c785b870bc589924c..76b20efe7c87c9e5547e8121ea12419fbae1af4d 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -19,30 +19,10 @@
 #include "json_workload.hpp"
 #include "pempek_assert.hpp"
 
-#include "algo/conservative_bf.hpp"
-#include "algo/crasher.hpp"
 #include "algo/easy_bf.hpp"
-#include "algo/easy_bf_fast.hpp"
-#include "algo/easy_bf_plot_liquid_load_horizon.hpp"
-#include "algo/energy_bf.hpp"
-#include "algo/energy_bf_dicho.hpp"
-#include "algo/energy_bf_idle_sleeper.hpp"
-#include "algo/energy_bf_monitoring_period.hpp"
-#include "algo/energy_bf_monitoring_inertial_shutdown.hpp"
-#include "algo/energy_bf_machine_subpart_sleeper.hpp"
-#include "algo/energy_watcher.hpp"
-#include "algo/filler.hpp"
 #include "algo/fcfs.hpp"
-#include "algo/fcfs_fast.hpp"
-#include "algo/killer.hpp"
-#include "algo/killer2.hpp"
-#include "algo/random.hpp"
 #include "algo/rejecter.hpp"
-#include "algo/sleeper.hpp"
 #include "algo/sequencer.hpp"
-#include "algo/sequencer_dvfs.hpp"
-#include "algo/submitter.hpp"
-#include "algo/wt_estimator.hpp"
 
 using namespace std;
 using namespace boost;
@@ -74,14 +54,7 @@ void run(Network & n, ISchedulingAlgorithm * algo, SchedulingDecision &d,
 
 int main(int argc, char ** argv)
 {
-    const set<string> variants_set = {"conservative_bf", "crasher", "easy_bf", "easy_bf_fast",
-                                      "easy_bf_plot_liquid_load_horizon",
-                                      "energy_bf", "energy_bf_dicho", "energy_bf_idle_sleeper",
-                                      "energy_bf_monitoring",
-                                      "energy_bf_monitoring_inertial", "energy_bf_subpart_sleeper",
-                                      "energy_watcher", "fcfs", "fcfs_fast",
-                                      "filler", "killer", "killer2", "random", "rejecter",
-                                      "sequencer", "sequencer_dvfs", "sleeper", "submitter", "waiting_time_estimator"};
+    const set<string> variants_set = {"easy_bf", "fcfs", "rejecter", "sequencer" };
     const set<string> policies_set = {"basic", "contiguous"};
     const set<string> queue_orders_set = {"fcfs", "lcfs", "desc_bounded_slowdown", "desc_slowdown",
                                           "asc_size", "desc_size", "asc_walltime", "desc_walltime"};
@@ -104,7 +77,7 @@ int main(int argc, char ** argv)
     args::ValueFlag<double> flag_rjms_delay(parser, "delay", "Sets the expected time that the RJMS takes to do some things like killing a job", {'d', "rjms_delay"}, 5.0);
     args::ValueFlag<string> flag_selection_policy(parser, "policy", "Sets the resource selection policy. Available values are " + policies_string, {'p', "policy"}, "basic");
     args::ValueFlag<string> flag_socket_endpoint(parser, "endpoint", "Sets the socket endpoint.", {'s', "socket-endpoint"}, "tcp://*:28000");
-    args::ValueFlag<string> flag_scheduling_variant(parser, "variant", "Sets the scheduling variant. Available values are " + variants_string, {'v', "variant"}, "filler");
+    args::ValueFlag<string> flag_scheduling_variant(parser, "variant", "Sets the scheduling variant. Available values are " + variants_string, {'v', "variant"}, "rejecter");
     args::ValueFlag<string> flag_variant_options(parser, "options", "Sets the scheduling variant options. Must be formatted as a JSON object.", {"variant_options"}, "{}");
     args::ValueFlag<string> flag_variant_options_filepath(parser, "options-filepath", "Sets the scheduling variant options as the content of the given filepath. Overrides the variant_options options.", {"variant_options_filepath"}, "");
     args::ValueFlag<string> flag_queue_order(parser, "order", "Sets the queue order. Available values are " + queue_orders_string, {'o', "queue_order"}, "fcfs");
@@ -259,54 +232,14 @@ int main(int argc, char ** argv)
         LOG_F(1, "variant_options = '%s'", variant_options.c_str());
 
         // Scheduling variant
-        if (scheduling_variant == "filler")
-            algo = new Filler(&w, &decision, queue, selector, rjms_delay, &json_doc_variant_options);
-        else if (scheduling_variant == "conservative_bf")
-            algo = new ConservativeBackfilling(&w, &decision, queue, selector, rjms_delay, &json_doc_variant_options);
-        else if (scheduling_variant == "crasher")
-            algo = new Crasher(&w, &decision, queue, selector, rjms_delay, &json_doc_variant_options);
-        else if (scheduling_variant == "easy_bf")
+        if (scheduling_variant == "easy_bf")
             algo = new EasyBackfilling(&w, &decision, queue, selector, rjms_delay, &json_doc_variant_options);
-        else if (scheduling_variant == "easy_bf_fast")
-            algo = new EasyBackfillingFast(&w, &decision, queue, selector, rjms_delay, &json_doc_variant_options);
-        else if (scheduling_variant == "easy_bf_plot_liquid_load_horizon")
-            algo = new EasyBackfillingPlotLiquidLoadHorizon(&w, &decision, queue, selector, rjms_delay, &json_doc_variant_options);
-        else if (scheduling_variant == "energy_bf")
-            algo = new EnergyBackfilling(&w, &decision, queue, selector, rjms_delay, &json_doc_variant_options);
-        else if (scheduling_variant == "energy_bf_dicho")
-            algo = new EnergyBackfillingDichotomy(&w, &decision, queue, selector, rjms_delay, &json_doc_variant_options);
-        else if (scheduling_variant == "energy_bf_idle_sleeper")
-            algo = new EnergyBackfillingIdleSleeper(&w, &decision, queue, selector, rjms_delay, &json_doc_variant_options);
-        else if (scheduling_variant == "energy_bf_monitoring")
-            algo = new EnergyBackfillingMonitoringPeriod(&w, &decision, queue, selector, rjms_delay, &json_doc_variant_options);
-        else if (scheduling_variant == "energy_bf_monitoring_inertial")
-            algo = new EnergyBackfillingMonitoringInertialShutdown(&w, &decision, queue, selector, rjms_delay, &json_doc_variant_options);
-        else if (scheduling_variant == "energy_bf_subpart_sleeper")
-            algo = new EnergyBackfillingMachineSubpartSleeper(&w, &decision, queue, selector, rjms_delay, &json_doc_variant_options);
-        else if (scheduling_variant == "energy_watcher")
-            algo = new EnergyWatcher(&w, &decision, queue, selector, rjms_delay, &json_doc_variant_options);
         else if (scheduling_variant == "fcfs")
             algo = new FCFS(&w, &decision, queue, selector, rjms_delay, &json_doc_variant_options);
-        else if (scheduling_variant == "fcfs_fast")
-            algo = new FCFSFast(&w, &decision, queue, selector, rjms_delay, &json_doc_variant_options);
-        else if (scheduling_variant == "killer")
-            algo = new Killer(&w, &decision, queue, selector, rjms_delay, &json_doc_variant_options);
-        else if (scheduling_variant == "killer2")
-            algo = new Killer2(&w, &decision, queue, selector, rjms_delay, &json_doc_variant_options);
-        else if (scheduling_variant == "random")
-            algo = new Random(&w, &decision, queue, selector, rjms_delay, &json_doc_variant_options);
         else if (scheduling_variant == "rejecter")
             algo = new Rejecter(&w, &decision, queue, selector, rjms_delay, &json_doc_variant_options);
         else if (scheduling_variant == "sequencer")
             algo = new Sequencer(&w, &decision, queue, selector, rjms_delay, &json_doc_variant_options);
-        else if (scheduling_variant == "sequencer_dvfs")
-            algo = new SequencerDVFS(&w, &decision, queue, selector, rjms_delay, &json_doc_variant_options);
-        else if (scheduling_variant == "sleeper")
-            algo = new Sleeper(&w, &decision, queue, selector, rjms_delay, &json_doc_variant_options);
-        else if (scheduling_variant == "submitter")
-            algo = new Submitter(&w, &decision, queue, selector, rjms_delay, &json_doc_variant_options);
-        else if (scheduling_variant == "waiting_time_estimator")
-            algo = new WaitingTimeEstimator(&w, &decision, queue, selector, rjms_delay, &json_doc_variant_options);
 
         // Network
         Network n;