diff --git a/test/gtest/IndividualTest.cpp b/test/gtest/IndividualTest.cpp
index 98af55791e74a8961a1f37251209fd5d5246671a..9de91e96d1b78e964cc963e12e5979daa4657499 100644
--- a/test/gtest/IndividualTest.cpp
+++ b/test/gtest/IndividualTest.cpp
@@ -39,13 +39,15 @@
 
 #include <gtest/gtest.h>
 
-#include "legacy/population/Individual.h"
-#include "macros.h"
-#include "GeneticUnit.h"
+#include "ExpManager_7.h"
+#include "ExpSetup.h"
+#include "fuzzy/FuzzyFactory_7.h"
+#include "Individual_7.h"
 #include "legacy/biochemistry/Rna.h"
 #include "legacy/biochemistry/Protein.h"
+#include "macros.h"
 #include "MutationParams.h"
-#include "ExpSetup.h"
+#include "Strand.h"
 
 using namespace aevol;
 
@@ -61,17 +63,16 @@ class IndividualTest : public testing::Test
   virtual void TearDown(void);
 
   // We have an version of each individual for each fuzzy set flavor
-  std::vector<Individual*> indivs1;
-  std::vector<Individual*> indivs2;
-  std::vector<Individual*> indivs3;
-  std::vector<Individual*> indivs4;
+  std::vector<Individual_7*> indivs1;
+  std::vector<Individual_7*> indivs2;
+  std::vector<Individual_7*> indivs3;
+  std::vector<Individual_7*> indivs4;
 };
 
 // ===========================================================================
 //                                 Public Methods
 // ===========================================================================
-void IndividualTest::SetUp(void)
-{
+void IndividualTest::SetUp(void) {
   // Build ad-hoc genomes
   // (and reverse to test the same things on the lagging strand.):
   //
@@ -84,33 +85,30 @@ void IndividualTest::SetUp(void)
   // AG = Arbitrary Gene
   // Do not modify the sequences !
 
-  // Define a few arbitrary sequences
-  char as[5][10] = {
-    "0011",
-    "11101",
-    "110011",
-    "11000",
-    "000101"
+  // Define arbitrary sequences
+  std::array<std::string, 5> as = {
+      "0011",
+      "11101",
+      "110011",
+      "11000",
+      "000101"
   };
 
   // Define an arbitrary gene
-  char gene[255];
-  sprintf(gene, "%s0011000100110110010001", SHINE_DAL_SEQ);
+  std::string gene = std::string(SHINE_DAL_SEQ) + "0011000100110110010001";
 
   // Define an arbitrary terminator
-  char term[TERM_SIZE+1] = "01000001101";
+  std::string term = "01000001101";
 
   // Define a few arbitrary promoters
-  char prom[2][23] = {
-    "0101010001110110010110", // dist from consensus: 2 => basal level: 0.6
-    "0101011001110010010010"  // dist from consensus: 1 => basal level: 0.8
+  std::array<std::string, 2> prom = {
+      "0101010001110110010110", // dist from consensus: 2 => basal level: 0.6
+      "0101011001110010010010"  // dist from consensus: 1 => basal level: 0.8
   };
 
-
-  // Initialize the experimental setup and fuzzy set factory.
+  // Initialize the experimental setup.
   // These are needed in the GeneticUnit constructors.
-  ExpSetup* exp_s = new ExpSetup(nullptr);
-  FuzzyFactory::fuzzyFactory = new FuzzyFactory();
+  ExpSetup exp_s(nullptr);
   MutationParams params_mut;
 
 
@@ -135,96 +133,77 @@ void IndividualTest::SetUp(void)
   }
 #endif
 
-  // We initialize a version of each individual for each fuzzy set
-  // implementation 
-  for (int fuzzyFlavor = 0 ; fuzzyFlavor <= 1 ; ++fuzzyFlavor) {
 
-    // Update fuzzy flavor and fuzzy factory
-    exp_s->set_fuzzy_flavor(fuzzyFlavor);
+  // We initialize a version of each individual for each fuzzy set implementation
+  for (FuzzyFlavor fuzzyFlavor : {FuzzyFlavor::VECTOR, FuzzyFlavor::DISCRETE_DOUBLE_TABLE}) {
+    // Update fuzzy factory // TODO<dpa> Still needed/useful?
+    exp_s.set_fuzzy_flavor(fuzzyFlavor);
 
-    if (FuzzyFactory::fuzzyFactory == NULL) {
-      FuzzyFactory::fuzzyFactory = new FuzzyFactory();
-    } else {
-      delete FuzzyFactory::fuzzyFactory;
-      FuzzyFactory::fuzzyFactory = new FuzzyFactory();
-    }
+    FuzzyFactory_7* fuzzy_factory = new FuzzyFactory_7(fuzzyFlavor, 16, 300, 16);
 
     // Build indiv1
-    // Construct a genome with these arbitrary sequences
-    char* genome = new char[1024];
-    sprintf(genome, "%s%s%s%s%s%s%s%s%s", as[0], prom[0], as[1], gene, as[2],
-            term, as[3], prom[1], as[4]);
-
-    Individual* indiv1 = new Individual(
-        nullptr, nullptr, nullptr, std::make_shared<MutationParams>(params_mut),
-        1.0, 10, 1000, false, 1, "anon-strain-1", 0);
-    indiv1->add_GU(genome, strlen(genome));
-    genome = NULL;
+    auto genome1 = as[0] + prom[0] + as[1] + gene + as[2] + term + as[3] + prom[1] + as[4];
+    auto indiv1 = Individual_7::make_from_sequence(1.0, fuzzy_factory, genome1.c_str(), genome1.size());
 
     // Do transcription and translation
-    indiv1->do_transcription();
-    indiv1->do_translation();
+    indiv1->start_stop_RNA();
+    indiv1->prom_compute_RNA(exp_s);
+    indiv1->start_protein();
+    indiv1->compute_protein();
+    indiv1->translate_protein(exp_s, 1.0);
 
     indivs1.push_back(indiv1);
 
-
-    // Build indiv2
-    // Reverse the whole genome
-    genome = indiv1->genetic_unit(0).dna()->subsequence(0, 0, LAGGING);
-    Individual* indiv2 = new Individual(nullptr, nullptr, nullptr,
-                            std::make_shared<MutationParams>(params_mut), 1.0,
-                            10, 1000, false, 1, "anon-strain-2", 0);
-    indiv2->add_GU(genome, strlen(genome));
-    genome = NULL;
+    // Build indiv2 (reverse the whole genome of indiv1)
+    auto genome2 = indiv1->annotated_chromosome_->dna_->subseq(indiv1->annotated_chromosome_->dna_->length() - 1,
+                                                               indiv1->annotated_chromosome_->dna_->length(),
+                                                               Strand::LAGGING);
+    auto indiv2 = Individual_7::make_from_sequence(1.0, fuzzy_factory, genome2.c_str(), genome2.size());
 
     // Do transcription and translation
-    indiv2->do_transcription();
-    indiv2->do_translation();
+    indiv2->start_stop_RNA();
+    indiv2->prom_compute_RNA(exp_s);
+    indiv2->start_protein();
+    indiv2->compute_protein();
+    indiv2->translate_protein(exp_s, 1.0);
 
     indivs2.push_back(indiv2);
 
-
     // Build indiv3
-    genome = new char[1024];
-    sprintf(genome, "%s%s%s%s%s%s%s", as[0], gene, as[1], term, as[2], prom[1],
-            as[3]);
-    Individual* indiv3 = new Individual(nullptr, nullptr, nullptr,
-                            std::make_shared<MutationParams>(params_mut), 1.0,
-                            10, 1000, false, 1, "anon-strain-3", 0);
-    indiv3->add_GU(genome, strlen(genome));
-    genome = NULL;
+    auto genome3 = as[0] + gene + as[1] + term + as[2] + prom[1] + as[3];
+    auto indiv3 = Individual_7::make_from_sequence(1.0, fuzzy_factory, genome3.c_str(), genome3.size());
 
     // Do transcription and translation
-    indiv3->do_transcription();
-    indiv3->do_translation();
+    indiv3->start_stop_RNA();
+    indiv3->prom_compute_RNA(exp_s);
+    indiv3->start_protein();
+    indiv3->compute_protein();
+    indiv3->translate_protein(exp_s, 1.0);
 
     indivs3.push_back(indiv3);
 
-
-    // Build indiv4
-    genome = indiv3->genetic_unit(0).dna()->subsequence(0, 0,
-                                                                    LAGGING);
-    Individual* indiv4 = new Individual(nullptr, nullptr, nullptr,
-                            std::make_shared<MutationParams>(params_mut), 1.0,
-                            10, 1000, false, 1, "anon-strain-4", 0);
-    indiv4->add_GU(genome, strlen(genome));
-    genome = NULL;
+    // Build indiv4 (reverse the whole genome of indiv3)
+    auto genome4 = indiv3->annotated_chromosome_->dna_->subseq(indiv3->annotated_chromosome_->dna_->length() - 1,
+                                                               indiv3->annotated_chromosome_->dna_->length(),
+                                                               Strand::LAGGING);
+    auto indiv4 = Individual_7::make_from_sequence(1.0, fuzzy_factory, genome4.c_str(), genome4.size());
 
     // Do transcription and translation
-    indiv4->do_transcription();
-    indiv4->do_translation();
+    indiv4->start_stop_RNA();
+    indiv4->prom_compute_RNA(exp_s);
+    indiv4->start_protein();
+    indiv4->compute_protein();
+    indiv4->translate_protein(exp_s, 1.0);
 
     indivs4.push_back(indiv4);
+
+    delete fuzzy_factory;
   }
 }
 
-void IndividualTest::TearDown(void)
-{
-  for (int fuzzyFlavor = 0 ; fuzzyFlavor <= 1 ; ++fuzzyFlavor) {
-    delete indivs1[fuzzyFlavor];
-    delete indivs2[fuzzyFlavor];
-    delete indivs3[fuzzyFlavor];
-    delete indivs4[fuzzyFlavor];
+void IndividualTest::TearDown() {
+  for (auto indiv : indivs1) {
+    delete indiv;
   }
 }
 
@@ -234,142 +213,152 @@ void IndividualTest::TearDown(void)
 // experimental setup again because it's only used at transcription and
 // translation time.
 
-TEST_F(IndividualTest, TestIndiv1)
-{
+TEST_F(IndividualTest, TestIndiv1) {
   // Check that we have the right number of promoters, terminators etc
   // and at the right positions
   // "right" means those values we have computed by hand
 
-  for (int fuzzyFlavor = 0 ; fuzzyFlavor <= 1 ; ++fuzzyFlavor) {
-    Individual* indiv1 = indivs1[fuzzyFlavor];
+  for (auto fuzzyFlavor = 0 ; fuzzyFlavor <= 1 ; ++fuzzyFlavor) {
+    auto indiv = indivs1[fuzzyFlavor];
 
     // Check genome size
-    EXPECT_EQ(109, indiv1->amount_of_dna());
-    EXPECT_EQ(109, indiv1->genetic_unit_seq_length(0));
+    EXPECT_EQ(109, indiv->annotated_chromosome_->dna_->length());
 
-    // Check RNA list
-    std::list<const Rna*> rna_list = indiv1->rna_list();
+    // Check RNA list
+    auto rna_list = indiv->annotated_chromosome_->rnas();
     EXPECT_EQ(2, rna_list.size());
-    const Rna* rna = rna_list.front();
-    EXPECT_EQ(LEADING, rna->strand());
-    EXPECT_EQ(4, rna->promoter_pos());
-    EXPECT_FLOAT_EQ(0.6, rna->basal_level());
-    EXPECT_EQ(50, rna->transcript_length());
+    const auto* rna = rna_list.front();
+    EXPECT_EQ(Strand::LEADING, rna->strand_);
+    EXPECT_EQ(4, rna->prom->pos);
+    EXPECT_FLOAT_EQ(0.6, rna->e);
+    EXPECT_EQ(50, rna->length);
     rna = rna_list.back();
-    EXPECT_EQ(LEADING, rna->strand());
-    EXPECT_EQ(81, rna->promoter_pos());
-    EXPECT_FLOAT_EQ(0.8, rna->basal_level());
-    EXPECT_EQ(82, rna->transcript_length());
+    EXPECT_EQ(Strand::LEADING, rna->strand_);
+    EXPECT_EQ(81, rna->prom->pos);
+    EXPECT_FLOAT_EQ(0.8, rna->e);
+    EXPECT_EQ(82, rna->length);
 
     // Check protein list
-    std::list<Protein*> prot_list = indiv1->protein_list();
-    EXPECT_EQ(1, prot_list.size());
-    Protein* prot = prot_list.front();
-    EXPECT_EQ(LEADING, prot->strand());
-    EXPECT_EQ(31, prot->shine_dal_pos());
-    EXPECT_EQ(4, prot->length());
-    EXPECT_FLOAT_EQ(1.4, prot->concentration());
-    EXPECT_EQ(2, prot->rna_list().size());
+    auto prot_list = indiv->annotated_chromosome_->proteins();
+    EXPECT_EQ(2, prot_list.size());
+
+    const auto* prot = prot_list.front();
+    EXPECT_EQ(Strand::LEADING, prot->strand_);
+    EXPECT_EQ(44, prot->protein_start);
+    EXPECT_EQ(4, prot->protein_length);
+    EXPECT_FLOAT_EQ(1.4, prot->e);
+    EXPECT_EQ(true, prot->is_init_);
+    EXPECT_EQ(2, prot->rna_list_.size());
+
+    prot = prot_list.back();
+    EXPECT_EQ(Strand::LEADING, prot->strand_);
+    EXPECT_EQ(44, prot->protein_start);
+    EXPECT_EQ(4, prot->protein_length);
+    EXPECT_FLOAT_EQ(0.6, prot->e);
+    EXPECT_EQ(false, prot->is_init_);
+    EXPECT_EQ(1, prot->rna_list_.size());
   }
 }
 
-TEST_F(IndividualTest, TestIndiv2)
-{
-  for (int fuzzyFlavor = 0; fuzzyFlavor <= 1; ++fuzzyFlavor) {
-    Individual* indiv2 = indivs2[fuzzyFlavor];
+TEST_F(IndividualTest, TestIndiv2) {
+  for (auto fuzzyFlavor = 0 ; fuzzyFlavor <= 1 ; ++fuzzyFlavor) {
+    auto indiv = indivs2[fuzzyFlavor];
 
     // Check genome size
-    EXPECT_EQ(109, indiv2->amount_of_dna());
-    EXPECT_EQ(109, indiv2->genetic_unit_seq_length(0));
+    EXPECT_EQ(109, indiv->annotated_chromosome_->dna_->length());
 
-    // Check RNA list
-    std::list<const Rna*> rna_list = indiv2->rna_list();
+    // Check RNA list
+    auto rna_list = indiv->annotated_chromosome_->rnas();
     EXPECT_EQ(2, rna_list.size());
-    const Rna* rna = rna_list.front();
-    EXPECT_EQ(LAGGING, rna->strand());
-    EXPECT_EQ(104, rna->promoter_pos());
-    EXPECT_FLOAT_EQ(0.6, rna->basal_level());
-    EXPECT_EQ(50, rna->transcript_length());
+    const auto* rna = rna_list.front();
+    EXPECT_EQ(Strand::LAGGING, rna->strand_);
+    EXPECT_EQ(104, rna->prom->pos);
+    EXPECT_FLOAT_EQ(0.6, rna->e);
+    EXPECT_EQ(50, rna->length);
     rna = rna_list.back();
-    EXPECT_EQ(LAGGING, rna->strand());
-    EXPECT_EQ(27, rna->promoter_pos());
-    EXPECT_FLOAT_EQ(0.8, rna->basal_level());
-    EXPECT_EQ(82, rna->transcript_length());
+    EXPECT_EQ(Strand::LAGGING, rna->strand_);
+    EXPECT_EQ(27, rna->prom->pos);
+    EXPECT_FLOAT_EQ(0.8, rna->e);
+    EXPECT_EQ(82, rna->length);
 
     // Check protein list
-    std::list<Protein*> prot_list = indiv2->protein_list();
-    EXPECT_EQ(1, prot_list.size());
-    Protein* prot = prot_list.front();
-    EXPECT_EQ(LAGGING, prot->strand());
-    EXPECT_EQ(77, prot->shine_dal_pos());
-    EXPECT_EQ(4, prot->length());
-    EXPECT_FLOAT_EQ(1.4, prot->concentration());
-    EXPECT_EQ(2, prot->rna_list().size());
+    auto prot_list = indiv->annotated_chromosome_->proteins();
+    EXPECT_EQ(2, prot_list.size());
+
+    const auto* prot = prot_list.front();
+    EXPECT_EQ(Strand::LAGGING, prot->strand_);
+    EXPECT_EQ(64, prot->protein_start);
+    EXPECT_EQ(4, prot->protein_length);
+    EXPECT_FLOAT_EQ(1.4, prot->e);
+    EXPECT_EQ(true, prot->is_init_);
+    EXPECT_EQ(2, prot->rna_list_.size());
+
+    prot = prot_list.back();
+    EXPECT_EQ(Strand::LAGGING, prot->strand_);
+    EXPECT_EQ(64, prot->protein_start);
+    EXPECT_EQ(4, prot->protein_length);
+    EXPECT_FLOAT_EQ(0.6, prot->e);
+    EXPECT_EQ(false, prot->is_init_);
+    EXPECT_EQ(1, prot->rna_list_.size());
   }
 }
 
-TEST_F(IndividualTest, TestIndiv3)
-{
-  for (int fuzzyFlavor = 0 ; fuzzyFlavor <= 1 ; ++fuzzyFlavor) {
-    Individual* indiv3 = indivs3[fuzzyFlavor];
+TEST_F(IndividualTest, TestIndiv3) {
+  for (auto fuzzyFlavor = 0 ; fuzzyFlavor <= 1 ; ++fuzzyFlavor) {
+    auto indiv = indivs3[fuzzyFlavor];
+
     // Check genome size
-    EXPECT_EQ(81, indiv3->amount_of_dna());
-    EXPECT_EQ(81, indiv3->genetic_unit_seq_length(0));
+    EXPECT_EQ(81, indiv->annotated_chromosome_->dna_->length());
 
-    // Check RNA list
-    std::list<const Rna*> rna_list = indiv3->rna_list();
+    // Check RNA list
+    auto rna_list = indiv->annotated_chromosome_->rnas();
     EXPECT_EQ(1, rna_list.size());
-    const Rna* rna = rna_list.front();
-    EXPECT_EQ(LEADING, rna->strand());
-    EXPECT_EQ(54, rna->promoter_pos());
-    EXPECT_FLOAT_EQ(0.8, rna->basal_level());
-    EXPECT_EQ(42, rna->transcript_length());
+    const auto* rna = rna_list.front();
+    EXPECT_EQ(Strand::LEADING, rna->strand_);
+    EXPECT_EQ(54, rna->prom->pos);
+    EXPECT_FLOAT_EQ(0.8, rna->e);
+    EXPECT_EQ(42, rna->length);
 
     // Check protein list
-    std::list<Protein*> prot_list = indiv3->protein_list();
+    auto prot_list = indiv->annotated_chromosome_->proteins();
     EXPECT_EQ(1, prot_list.size());
-    Protein* prot = prot_list.front();
-    EXPECT_EQ(LEADING, prot->strand());
-    EXPECT_EQ(4, prot->shine_dal_pos());
-    EXPECT_EQ(4, prot->length());
-    EXPECT_FLOAT_EQ(0.8, prot->concentration());
-    EXPECT_EQ(1, prot->rna_list().size());
+
+    const auto* prot = prot_list.front();
+    EXPECT_EQ(Strand::LEADING, prot->strand_);
+    EXPECT_EQ(17, prot->protein_start);
+    EXPECT_EQ(4, prot->protein_length);
+    EXPECT_FLOAT_EQ(0.8, prot->e);
+    EXPECT_EQ(true, prot->is_init_);
+    EXPECT_EQ(1, prot->rna_list_.size());
   }
 }
 
-TEST_F(IndividualTest, TestIndiv4)
-{
-  for (int fuzzyFlavor = 0 ; fuzzyFlavor <= 1 ; ++fuzzyFlavor) {
-    Individual* indiv4 = indivs4[fuzzyFlavor];
+TEST_F(IndividualTest, TestIndiv4) {
+  for (auto fuzzyFlavor = 0 ; fuzzyFlavor <= 1 ; ++fuzzyFlavor) {
+    auto indiv = indivs4[fuzzyFlavor];
+
     // Check genome size
-    EXPECT_EQ(81, indiv4->amount_of_dna());
-    EXPECT_EQ(81, indiv4->genetic_unit_seq_length(0));
+    EXPECT_EQ(81, indiv->annotated_chromosome_->dna_->length());
 
-    // Check RNA list
-    std::list<const Rna*> rna_list = indiv4->rna_list();
+    // Check RNA list
+    auto rna_list = indiv->annotated_chromosome_->rnas();
     EXPECT_EQ(1, rna_list.size());
-    const Rna* rna = rna_list.front();
-    EXPECT_EQ(LAGGING, rna->strand());
-    EXPECT_EQ(26, rna->promoter_pos());
-    EXPECT_FLOAT_EQ(0.8, rna->basal_level());
-    EXPECT_EQ(42, rna->transcript_length());
+    const auto* rna = rna_list.front();
+    EXPECT_EQ(Strand::LAGGING, rna->strand_);
+    EXPECT_EQ(26, rna->prom->pos);
+    EXPECT_FLOAT_EQ(0.8, rna->e);
+    EXPECT_EQ(42, rna->length);
 
     // Check protein list
-    std::list<Protein*> prot_list = indiv4->protein_list();
+    auto prot_list = indiv->annotated_chromosome_->proteins();
     EXPECT_EQ(1, prot_list.size());
-    Protein* prot = prot_list.front();
-    EXPECT_EQ(LAGGING, prot->strand());
-    EXPECT_EQ(76, prot->shine_dal_pos());
-    EXPECT_EQ(4, prot->length());
-    EXPECT_FLOAT_EQ(0.8, prot->concentration());
-    EXPECT_EQ(1, prot->rna_list().size());
+
+    const auto* prot = prot_list.front();
+    EXPECT_EQ(Strand::LAGGING, prot->strand_);
+    EXPECT_EQ(63, prot->protein_start);
+    EXPECT_EQ(4, prot->protein_length);
+    EXPECT_FLOAT_EQ(0.8, prot->e);
+    EXPECT_EQ(true, prot->is_init_);
+    EXPECT_EQ(1, prot->rna_list_.size());
   }
 }
-
-// ===========================================================================
-//                                Protected Methods
-// ===========================================================================
-
-// ===========================================================================
-//                              Non inline accessors
-// ===========================================================================