diff --git a/application/Makefile b/application/Makefile
index 0c4f96858db660a80cd0601d67b9a7f163ef39bc..63a2de68b175d87f02cfb4647781032780b46b89 100644
--- a/application/Makefile
+++ b/application/Makefile
@@ -1,17 +1,24 @@
 #cflags pour tout compiler
 CXXFLAGS=`otawa-config otawa/display --cflags`
-LDLIBS2=`otawa-config otawa/display otawa/classic_ecb otawa/ucb_otawa --libs`
+LDLIBS2=`otawa-config otawa/display otawa/classic_ecb otawa/ucb_otawa otawa/etime --libs`   -Wl,-rpath,"/home/fabien/cristal/otawa/lib/otawa/otawa/"
+
 CXXFLAGS += -std=c++11 -O0 -g -I ../include             
 
 ARMCC=arm-none-eabi-gcc
 
-all: application  basic big_function
+all: application  basic big_function application_task
 
 application: application.o
-	$(CXX) -o application application.o $(LDLIBS2)
+	$(CXX) -o application application.o $(LDLIBS2) $(CXXFLAGS)
 
 application.o: application.cpp application.h
 
+
+application_task: application_task.o
+	$(CXX) -o application_task application_task.o $(LDLIBS2) $(CXXFLAGS)
+
+application_task.o: application_task.cpp application.h
+
 basic: basic_f_l_c.c
 	$(ARMCC) -nostdlib -nostdinc -static -o basic basic_f_l_c.c
 
diff --git a/application/application.cpp b/application/application.cpp
index 0d0665b64e733dd7e6c9654aeb5c5d7e77b14c46..f02785d7974cf3feb65a0f6b548636b6993bbd7e 100644
--- a/application/application.cpp
+++ b/application/application.cpp
@@ -14,9 +14,12 @@
 #include <otawa/display/CFGOutput.h>
 #include <otawa/cache/features.h>
 #include <otawa/cache/cat2/CAT2Builder.h>
+// edge time processors
+#include <otawa/etime/features.h>
+
 #include <elm/io/OutFileStream.h>
 #include <otawa/flowfact/features.h>
-#include <multiset.h>
+//#include <multiset.h>
 #include "../classic_ecb/include/classic_ecb.h"
 #include "../ucb_otawa/include/ucb_otawa.h"
 #include "application.h"
@@ -29,7 +32,27 @@ using namespace Mathset;
 
 
 int main(int argc, char **argv) {
-        
+  if (argc < 5) {
+    fprintf(stderr, "usage: %s <binary> <cache> <flow facts> <sortie>\n", argv[0]);
+    exit(1);
+  }
+
+  // //----------------------------- TRIVIAL
+  WorkSpace *ws_trivial = NULL;
+  PropList conf_trivial;
+  Manager manager_trivial;
+  NO_SYSTEM(conf_trivial) = true;
+  TASK_ENTRY(conf_trivial) = "main";
+  VERBOSE(conf_trivial) = true;
+  FLOW_FACTS_PATH(conf_trivial) = argv[3];
+  
+  ws_trivial = manager_trivial.load(argv[1], conf_trivial);
+  ws_trivial->run("otawa::Virtualizer", conf_trivial);
+
+  ws_trivial->require(otawa::ipet::WCET_FEATURE, conf_trivial);
+  long wcet_trivial = ipet::WCET(ws_trivial);
+  
+  // //-------------------------------------------------------------
   WorkSpace *ws = NULL;
   PropList conf;
   Manager manager;
@@ -37,35 +60,50 @@ int main(int argc, char **argv) {
   TASK_ENTRY(conf) = "main";
   VERBOSE(conf) = true;
 
-  if (argc < 5) {
-    fprintf(stderr, "usage: %s <binary> <cache> <flow facts> <sortie>\n", argv[0]);
-    exit(1);
-  }
+  
         
   CACHE_CONFIG_PATH(conf) = argv[2];
   FLOW_FACTS_PATH(conf) = argv[3];
-	
-  ws = manager.load(argv[1], conf);
+  PROCESSOR_PATH(conf)  = "/home/fabien/cristal/otawa-plugins/application/hardware/pipeline/lpc2138.xml";
+  MEMORY_PATH(conf)  = "/home/fabien/cristal/otawa-plugins/application/hardware/memory/lpc2138.xml";
+  otawa::etime::RECORD_TIME(conf) = true;
 
+  // Platform description
+  //CACHE_CONFIG_PATH(conf) = "/home/fabien/cristal/otawa-plugins/application/xmc4500/cache.xml";
+  //PROCESSOR_PATH(conf)  = "/home/fabien/cristal/otawa-plugins/application/xmc4500/pipeline.xml";
+  
+  ws = manager.load(argv[1], conf);
+  ws->run("otawa::Virtualizer", conf);
+  ws->require(otawa::ICACHE_CONSTRAINT2_FEATURE, conf);
+  //ws->require(otawa::ICACHE_ONLY_CONSTRAINT2_FEATURE, conf);
+  ws->require(otawa::etime::EDGE_TIME_FEATURE, conf);
+  ws->require(otawa::ipet::WCET_FEATURE, conf);
+   
   ws->require(DynFeature("otawa::ucb_otawa::UCB_OTAWA_FEATURE"), conf);
   ws->require(DynFeature("otawa::classic_ecb::CLASSIC_ECB_PROCESSOR"), conf);
   //ws->require(otawa::ipet::ILP_SYSTEM_FEATURE, conf);
-  ws->require(otawa::ICACHE_CONSTRAINT2_FEATURE, conf);
-  ws->require(otawa::ipet::WCET_FEATURE, conf);
-	
-  long wcet = ipet::WCET(ws);
+  
+ 
+  long wcet = ipet::WCET(ws) - wcet_trivial;
   Multiset<int> ucbs = TOTAL_UCB(ws);
   Multiset<int> *ecbs = ECBS(ws);
 
-
+  if(wcet > 1000000) {
+    return 0;
+  }
 
   std::ofstream f(argv[4], std::ofstream::app);
-  f <<"(" << wcet << ", 10, 10 ," << std::endl << "{";
+  
+   
+  f <<"(" << argv[1] << "," << wcet << ", 10, 10 ," << std::endl << "{";
   ecbs->to_string(f);
+
+   
   f << "}," << std::endl << "{";
   ucbs.to_string(f);
   f << "}," << std::endl << "{";
-	
+
+  
   const CFGCollection *coll = INVOLVED_CFGS(ws);
 
   Mathset::Multiset<Mathset::Multiset<int>> ucb_list = UCB_OTAWA(ws);
@@ -78,7 +116,6 @@ int main(int argc, char **argv) {
   f << "})" << endl;
 	
   f.close();
-
   const otawa::hard::CacheConfiguration *cf = otawa::hard::CACHE_CONFIGURATION_FEATURE.get(ws); 
   const otawa::hard::Cache* cache = cf->instCache();
 
diff --git a/application/bin/Makefile b/application/bin/Makefile
index ef9274e1f0d7ce1f83fa3e3b2c1f7c12713212b0..77363746b57be87c236a8fc4d9b64503e288e44a 100644
--- a/application/bin/Makefile
+++ b/application/bin/Makefile
@@ -1,11 +1,11 @@
 
-ARMCC=arm-none-eabi-gcc
+ARMCC=arm-linux-gnueabi-gcc
 
-all: bs.exe cover.exe crc.exe fdct.exe fibcall.exe insertsort.exe janne_complex.exe jfdctint.exe lcdnum.exe matmult.exe ndes.exe nsichneu.exe
+all: bs.elf cover.elf crc.elf fdct.elf fibcall.elf insertsort.elf janne_complex.elf jfdctint.elf lcdnum.elf matmult.elf ndes.elf nsichneu.elf
 
 
-%.exe: %.c
-	$(ARMCC) -nostdlib -nostdinc -static -g -O0 -o $@ $<
+%.elf: %.c
+	$(ARMCC) -nostdlib -nostdinc -static -g3 -O0 -o $@ $<
 	orange --auto $< main -o $*.backup.ffx
 
 
@@ -20,5 +20,5 @@ clean-backup:
 	rm -f *.backup.ffx
 
 clean-binary:
-	rm -f *.exe
+	rm -f *.elf
 
diff --git a/application/bin/fdct.ffx b/application/bin/fdct.ffx
index 5831b7b3049c396cfb12fce199627245e9b7420a..ef90b8ffbe1605c4eca21de13e117a2ed3b6d8f0 100644
--- a/application/bin/fdct.ffx
+++ b/application/bin/fdct.ffx
@@ -8,7 +8,7 @@ WARNING: otawa::FlowFactLoader 1.4.0:no flow fact file for fdct.exe
 	<function  label="fdct"> <!-- 0x00008000 (fdct.c:68) -->
 		<loop label="fdct" offset="0x45c" maxcount="8" totalcount="8"> <!-- 0x0000845c (fdct.c:83) -->
 		</loop>
-		<loop label="fdct" offset="0xa28"  maxcount="8" totalcount="8"> <!-- 0x00008a28 (fdct.c:161) -->
+		<loop label="fdct" offset="0xa10"  maxcount="8" totalcount="8"> <!-- 0x00008a28 (fdct.c:161) -->
 		</loop>
 	</function>
 
diff --git a/explo/application.cpp b/explo/application.cpp
index dab9dff7f04a680ff6fca62920ef01fbc9865104..e3183e8bb7a4e65dd0f991f33761efd9f12afc56 100644
--- a/explo/application.cpp
+++ b/explo/application.cpp
@@ -39,15 +39,23 @@ int main(int argc, char **argv) {
   
   
   WorkSpace *ws = NULL;
+  //WorkSpace *ws_trivial = NULL;
   PropList conf;
+  //PropList conf_trivial;
   Manager manager;
+  //Manager manager_trivial;
   NO_SYSTEM(conf) = true;
   TASK_ENTRY(conf) = "main";
   VERBOSE(conf) = true;
 
+  // NO_SYSTEM(conf_trivial) = true;
+  // TASK_ENTRY(conf_trivial) = "main";
+  // VERBOSE(conf_trivial) = true;
+
   // Flow fact
   std::cout << "-------------------- Configuration paths ----------------------" << std::endl;
   FLOW_FACTS_PATH(conf) = argv[2];
+  //FLOW_FACTS_PATH(conf_trivial) = argv[2];
   
   // Platform description
   CACHE_CONFIG_PATH(conf) = "xmc4500/cache.xml";
@@ -59,23 +67,29 @@ int main(int argc, char **argv) {
   
   std::cout << "----------------------------Workspace building----------------------------------" << std::endl;
   ws = manager.load(argv[1], conf);
-
+  //ws_trivial = manager_trivial.load(argv[1], conf_trivial);
   // CFG Building
   std::cout << "----------------------------run virtualizer--------------------------------------" << std::endl;
    ws->run("otawa::Virtualizer", conf);
+   //ws_trivial->run("otawa::Virtualizer", conf_trivial);
   std::cout << "-------------------------------cache configuration-----------------------------------------" << std::endl;
-  ws->require(otawa::ICACHE_ONLY_CONSTRAINT2_FEATURE , conf);
+  // ws->require(otawa::ICACHE_ONLY_CONSTRAINT2_FEATURE , conf);
   std::cout << "-------------------------------edge time-----------------------------------------" << std::endl;
   otawa::etime::RECORD_TIME(conf) = true;
-  // ws->require(otawa::ICACHE_CONSTRAINT2_FEATURE , conf);
-  ws->require(otawa::ICACHE_ONLY_CONSTRAINT2_FEATURE, conf);
+  
+  //ws->require(otawa::ICACHE_ONLY_CONSTRAINT2_FEATURE, conf);
+  //ws->require(otawa::ICACHE_CONSTRAINT2_FEATURE , conf);
   ws->require(otawa::etime::EDGE_TIME_FEATURE, conf);
-
+  
   std::cout << "-------------------------------wcet----------------------------------------------" << std::endl;
   ws->require(otawa::ipet::WCET_FEATURE, conf);
   
   ws->require(DynFeature("otawa::explo::EXPLO_FEATURE"), conf);
   
+ 
+
+  //ws_trivial->require(otawa::ipet::WCET_FEATURE, conf_trivial);
   std::cout << "WCET:" << ipet::WCET(ws) << std::endl;
+  // std::cout << "WCET:" << ipet::WCET(ws_trivial) << std::endl;
   return 0;
 }
diff --git a/explo/explo.cpp b/explo/explo.cpp
index f00e6c08c535ee2f8d505e2a6b7aab4b1ca2d749..caf24618597264b3543a904efe5261628cc6d360 100644
--- a/explo/explo.cpp
+++ b/explo/explo.cpp
@@ -261,12 +261,6 @@ namespace otawa {
       for(CFGCollection::Iter cfg_iter(*coll); cfg_iter(); cfg_iter++) {
 	CFG* tmp = *cfg_iter;
 	explo_cfg(tmp);
-	/*std::cout << "EXIT: ";
-	  std::vector<Block*> vector_blocks = get_last_blocks(tmp);
-	  for(int i = 0; i < vector_blocks.size(); i++) {
-	  std::cout << vector_blocks[i]->id() << " ";
-	  }
-	*/
 	std::cout << std::endl;
       }
     }
diff --git a/vulnerability/Makefile b/vulnerability/Makefile
index a6319fd28ee676c7e340c190a8dc7be5f9649564..578818c9304b43f0e68275f24a4b95ab46f54a6e 100644
--- a/vulnerability/Makefile
+++ b/vulnerability/Makefile
@@ -26,8 +26,8 @@ application: application.o
 
 application.o: application.cpp
 
-vulnerability.so: vulnerability.cpp include/vulnerability.h
-	$(CXX) -fPIC -shared $(CXXFLAGS) -o vulnerability.so vulnerability.cpp $(LDLIBS)
+vulnerability.so: vulnerability.cpp  include/vulnerability.h include/type.h
+	$(CXX) -fPIC -shared $(CXXFLAGS) -o vulnerability.so vulnerability.cpp  $(LDLIBS)
 
 ##fin
 
diff --git a/vulnerability/application b/vulnerability/application
index 785d2bbca25dadf861edea64957c6bd70470e25f..f9dde2cd4aa23b1d5518fa96a02c63235db93c8d 100755
Binary files a/vulnerability/application and b/vulnerability/application differ
diff --git a/vulnerability/application.cpp b/vulnerability/application.cpp
index e4c27cf273ad93d46bf749c5dd34d8c5a0be2220..cd97c8b7a7ca1c71f5cc21917d6cc98d6d518b5b 100644
--- a/vulnerability/application.cpp
+++ b/vulnerability/application.cpp
@@ -40,7 +40,7 @@ int main(int argc, char **argv) {
   
   ws->run("otawa::Virtualizer", conf);
   ws->require(otawa::ICACHE_CONSTRAINT2_FEATURE, conf);
-   ws->require(otawa::etime::EDGE_TIME_FEATURE, conf);
+  ws->require(otawa::etime::EDGE_TIME_FEATURE, conf);
   ws->require(otawa::ipet::WCET_FEATURE, conf);
   ws->require(DynFeature("otawa::vulnerability::VULNERABILITY_FEATURE"), conf);
   std::cout << "vulnerability:" << VUL(ws) << " WCET:" << ipet::WCET(ws) << std::endl;
diff --git a/vulnerability/application.o b/vulnerability/application.o
index 1a25d082a1fdee7d674f304d87033911ce58a4ab..1e8f90bd0399e1d996bdaa88b1a1902d44858669 100644
Binary files a/vulnerability/application.o and b/vulnerability/application.o differ
diff --git a/vulnerability/include/vulnerability.h b/vulnerability/include/vulnerability.h
index d609b6def5757f63e4f905792a8be38433cbccad..282efde6f4c56e41612a574ea0bafca32a0b92c2 100644
--- a/vulnerability/include/vulnerability.h
+++ b/vulnerability/include/vulnerability.h
@@ -14,6 +14,9 @@
 #include <otawa/proc/ProcessorPlugin.h>
 #include <otawa/cfg/Dominance.h>
 #include <otawa/otawa.h>
+
+#include "type.h"
+
 namespace otawa { namespace vulnerability {
 class VulnerabilityProcessor : public Processor {
 public:
@@ -35,5 +38,9 @@ extern Identifier<DAGHNode*> DAG_HNODE;
     extern Identifier<unsigned long> VUL;
     extern Identifier<std::vector<Address>*> UCB_IN;
     extern Identifier<std::vector<Address>*> UCB_OUT;
-} }
+
+    void start_rmb_lmb_computation(WorkSpace *ws);
+    extern Identifier<struct Memory_block *> MB_STRUCT;
+  }
+}
 #endif
diff --git a/vulnerability/vulnerability.cpp b/vulnerability/vulnerability.cpp
index 06a1089fc12cec117c0823767a25c23c5b3bedfb..8d291871e82b9b6e334213e09434af70ccdfcd8c 100644
--- a/vulnerability/vulnerability.cpp
+++ b/vulnerability/vulnerability.cpp
@@ -1,4 +1,3 @@
-#include "../initialize_RMB_LMB/include/initialize_RMB_LMB.h"
 #include "include/vulnerability.h"
 #include <cmath>
 #include <otawa/proc/DynFeature.h>
@@ -18,412 +17,1216 @@
 #include <otawa/flowfact/features.h>
 #include <otawa/cfg/Loop.h>
 #include <otawa/etime/features.h>
-using namespace otawa::initialize_RMB_LMB;
+
+#include <otawa/cache/LBlock.h>
+
+using namespace otawa::vulnerability;
 using namespace otawa::lblock_time;
 namespace otawa {
-  namespace vulnerability {
-
-    // Declaration du plugin
-
-    class Plugin : public ProcessorPlugin { 
-    public:
-      Plugin() : ProcessorPlugin("otawa::vulnerability", Version(1, 0, 0), OTAWA_PROC_VERSION) {}
-    };
-
-    otawa::vulnerability::Plugin vulnerability_plugin;
-    ELM_PLUGIN(vulnerability_plugin, OTAWA_PROC_HOOK);
-
-    p::declare VulnerabilityProcessor::reg = p::init("otawa::vulnerability::VulnerabilityProcessor", Version(1, 0, 0))
-      .require(COLLECTED_CFG_FEATURE)
-      .require(LOOP_INFO_FEATURE)
-      .require(ICACHE_CONSTRAINT2_FEATURE)
-      .require(etime::EDGE_TIME_FEATURE)
-      .require(INITIALIZE_RMB_LMB_FEATURE)
-      .require(otawa::lblock_time::LBLOCK_TIME_FEATURE)
-      .require(ipet::ILP_SYSTEM_FEATURE)
-      .require(ipet::WCET_FEATURE)
-      .provide(VULNERABILITY_FEATURE);
-    //.require(otawa::lblock_time::LBLOCK_TIME_FEATURE)
-    //INITIALIZE_RMB_LMB_FEATURE
+    namespace vulnerability {
+
+	// Declaration du plugin
+
+	class Plugin : public ProcessorPlugin { 
+	public:
+	    Plugin() : ProcessorPlugin("otawa::vulnerability", Version(1, 0, 0), OTAWA_PROC_VERSION) {}
+	};
+
+	otawa::vulnerability::Plugin vulnerability_plugin;
+	ELM_PLUGIN(vulnerability_plugin, OTAWA_PROC_HOOK);
+
+	p::declare VulnerabilityProcessor::reg = p::init("otawa::vulnerability::VulnerabilityProcessor", Version(1, 0, 0))
+	    .require(COLLECTED_CFG_FEATURE)
+	    .require(LOOP_INFO_FEATURE)
+	    .require(ICACHE_CONSTRAINT2_FEATURE)
+	    .require(etime::EDGE_TIME_FEATURE)
+	    .require(otawa::lblock_time::LBLOCK_TIME_FEATURE)
+	    .require(ipet::ILP_SYSTEM_FEATURE)
+	    .require(ipet::WCET_FEATURE)
+	    .provide(VULNERABILITY_FEATURE);
+	//.require(otawa::lblock_time::LBLOCK_TIME_FEATURE)
+	//INITIALIZE_RMB_LMB_FEATURE
       
-    // definition feature
-    p::feature VULNERABILITY_FEATURE("otawa::vulnerability::VULNERABILITY_FEATURE", new Maker<VulnerabilityProcessor>());
+	// definition feature
+	p::feature VULNERABILITY_FEATURE("otawa::vulnerability::VULNERABILITY_FEATURE", new Maker<VulnerabilityProcessor>());
 
-    VulnerabilityProcessor::VulnerabilityProcessor(p::declare &r) : Processor(r) {}
+	VulnerabilityProcessor::VulnerabilityProcessor(p::declare &r) : Processor(r) {}
 
-    void VulnerabilityProcessor::configure(const PropList &props) {
-      Processor::configure(props);
-    }
+	void VulnerabilityProcessor::configure(const PropList &props) {
+	    Processor::configure(props);
+	}
 
-    void print_mb(std::vector<std::vector<Address>> *multi, int nb_index) {
-      //std::cout << "{";
-      for(int i = 0; i < nb_index; i++) {
+    
+	void print_mb(std::vector<std::vector<Address>> *multi, int nb_index) {
+	    //std::cout << "{";
+	    for(int i = 0; i < nb_index; i++) {
 
-	std::vector<std::vector<Address>> tmp = multi[i];
-	std::cout << "[" << i << "]";
+		std::vector<std::vector<Address>> tmp = multi[i];
+		std::cout << "[" << i << "]";
 
-	for(int j = 0; j < tmp.size(); j++) {
-	  std::cout << " {";
-	  for(int k = 0; k < tmp[j].size(); k++) {
-	    std::cout << tmp[j][k].page() << ":" << tmp[j][k].offset() << " ";
-	  }
-	  std::cout << "}";
+		for(int j = 0; j < tmp.size(); j++) {
+		    std::cout << " {";
+		    for(int k = 0; k < tmp[j].size(); k++) {
+			std::cout << tmp[j][k].page() << ":" << tmp[j][k].offset() << " ";
+		    }
+		    std::cout << "}";
       
+		}
+		std::cout << std::endl;
+	    }
+	    // std::cout << "}";
 	}
-	std::cout << std::endl;
-      }
-      // std::cout << "}";
-    }
     
 
-    // vector are modified 
-    std::vector<Address> lru_cache_sim(std::vector<Address> rmb, std::vector<Address> lmb, int nb_way) {
-      std::vector<Address> ucb;
-      for(int i = 0; i < lmb.size(); i++) {
-	// check if a hit ?
-	bool hit = false;
-	for(int j = 0; j < rmb.size(); j++) {
-	  if(rmb[j] == lmb[i]) {
-	    hit = true;
-	    // remove block from the cache to add it at the back
-	    rmb.erase(rmb.begin() + j);
-	    rmb.push_back(lmb[i]);
-	    break;
-	  }
-	}
-	// add block to ucb if hit
-	if(hit) {
-	  ucb.push_back(lmb[i]);
-	} else {
-	  rmb.push_back(lmb[i]);
-	  if(rmb.size() > nb_way) {
-	    rmb.erase(rmb.begin());
-	  }
+	// vector are modified 
+	std::vector<Address> lru_cache_sim(std::vector<Address> rmb, std::vector<Address> lmb, int nb_way) {
+	    std::vector<Address> ucb;
+	    for(int i = 0; i < lmb.size(); i++) {
+		// check if a hit ?
+		bool hit = false;
+		for(int j = 0; j < rmb.size(); j++) {
+		    if(rmb[j] == lmb[i]) {
+			hit = true;
+			// remove block from the cache to add it at the back
+			rmb.erase(rmb.begin() + j);
+			rmb.push_back(lmb[i]);
+			break;
+		    }
+		}
+		// add block to ucb if hit
+		if(hit) {
+		    ucb.push_back(lmb[i]);
+		} else {
+		    rmb.push_back(lmb[i]);
+		    if(rmb.size() > nb_way) {
+			rmb.erase(rmb.begin());
+		    }
+		}
+	    }
+	    return ucb;
 	}
-      }
-      return ucb;
-    }
     
-    std::vector<Address> compute_ucb(std::vector<std::vector<Address>> rmb, std::vector<std::vector<Address>> lmb, int nb_way) {
-      std::vector<Address> ucb;
-      for(int i = 0; i < rmb.size(); i++) {
-	for(int j = 0; j < lmb.size(); j++) {
-	  std::vector<Address> tmp_ucb = lru_cache_sim(rmb[i], lmb[j], nb_way);
-	  for(int k = 0; k < tmp_ucb.size(); k++) {
-	    if(find(ucb.begin(), ucb.end(), tmp_ucb[k]) == ucb.end()) {
-	      ucb.push_back(tmp_ucb[k]);
-	    }
-	  }
+	std::vector<Address> compute_ucb(std::vector<std::vector<Address>> rmb, std::vector<std::vector<Address>> lmb, int nb_way) {
+	    std::vector<Address> ucb;
+	    for(int i = 0; i < rmb.size(); i++) {
+		for(int j = 0; j < lmb.size(); j++) {
+		    std::vector<Address> tmp_ucb = lru_cache_sim(rmb[i], lmb[j], nb_way);
+		    for(int k = 0; k < tmp_ucb.size(); k++) {
+			if(find(ucb.begin(), ucb.end(), tmp_ucb[k]) == ucb.end()) {
+			    ucb.push_back(tmp_ucb[k]);
+			}
+		    }
+		}
+	    }
+	    return ucb;
 	}
-      }
-      return ucb;
-    }
 
-    unsigned long compute_total_iteration(Block *b) {
-      // if the loop header exist return the nb of iteration
-      Block *bh = Loop::of(b)->header();
-      if(bh->isBasic()) {
-	return TOTAL_ITERATION(bh->toBasic()->first());
-      }
+	unsigned long compute_total_iteration(Block *b) {
+	    // if the loop header exist return the nb of iteration
+	    Block *bh = Loop::of(b)->header();
+	    if(bh->isBasic()) {
+		return TOTAL_ITERATION(bh->toBasic()->first());
+	    }
 
-      // if the CFG is the main function
-      if(b->cfg()->callers().count() == 0) {
-	return 1;
-      }
+	    // if the CFG is the main function
+	    if(b->cfg()->callers().count() == 0) {
+		return 1;
+	    }
 
-      // if the CFG is a function then we sum the nb of iteration from all of synth block that call it
-      unsigned int total = 0;
-      for(int i = 0; i < b->cfg()->callers().count(); i++) {
-        total += compute_total_iteration(b->cfg()->callers()[i]);
-      }
-      return total;
-    }
+	    // if the CFG is a function then we sum the nb of iteration from all of synth block that call it
+	    unsigned int total = 0;
+	    for(int i = 0; i < b->cfg()->callers().count(); i++) {
+		total += compute_total_iteration(b->cfg()->callers()[i]);
+	    }
+	    return total;
+	}
 
     
-    unsigned long compute_vul_block_out(BasicBlock *bb, std::vector<Address> ucb_out, const otawa::hard::Cache* cache, std::vector<unsigned long> lblock_time_array) {
-
-      AllocArray<LBlock *> *lblock_array = BB_LBLOCKS(bb);
-      double vul = 0;
-      for(int i = 0; i < ucb_out.size(); i++) {
-	bool found = false;
-	for (int j = 0; j < lblock_array->count(); j++) {
-	  LBlock *lb = (*lblock_array)[j];
-	  if(found) {
-	    vul += lblock_time_array[j];
-	  }
-	  if(cache->round(lb->address()) == ucb_out[i]) {
-	    found = true;
-	  }
-	}
-      }
+	unsigned long compute_vul_block_out(BasicBlock *bb, std::vector<Address> ucb_out, const otawa::hard::Cache* cache, std::vector<unsigned long> lblock_time_array) {
 
-      return vul * cache->blockSize();
-    }
+	    AllocArray<LBlock *> *lblock_array = BB_LBLOCKS(bb);
+	    double vul = 0;
+	    for(int i = 0; i < ucb_out.size(); i++) {
+		bool found = false;
+		for (int j = 0; j < lblock_array->count(); j++) {
+		    LBlock *lb = (*lblock_array)[j];
+		    if(found) {
+			vul += lblock_time_array[j];
+		    }
+		    if(cache->round(lb->address()) == ucb_out[i]) {
+			found = true;
+		    }
+		}
+	    }
 
-    unsigned long compute_vul_block_in(BasicBlock *bb, std::vector<Address> ucb_in, const otawa::hard::Cache* cache, std::vector<unsigned long> lblock_time_array) {
-
-      AllocArray<LBlock *> *lblock_array = BB_LBLOCKS(bb);
-      double vul = 0;
-      for(int i = 0; i < ucb_in.size(); i++) {
-	for (int j = 0; j < lblock_array->count(); j++) {
-	  LBlock *lb = (*lblock_array)[j];
-	  if(cache->round(lb->address()) == ucb_in[i]) {
-	    break;
-	  }
-	  vul += lblock_time_array[j];
+	    return vul * cache->blockSize();
 	}
-      }
 
-      return vul * cache->blockSize();
-    }
+	unsigned long compute_vul_block_in(BasicBlock *bb, std::vector<Address> ucb_in, const otawa::hard::Cache* cache, std::vector<unsigned long> lblock_time_array) {
+
+	    AllocArray<LBlock *> *lblock_array = BB_LBLOCKS(bb);
+	    double vul = 0;
+	    for(int i = 0; i < ucb_in.size(); i++) {
+		for (int j = 0; j < lblock_array->count(); j++) {
+		    LBlock *lb = (*lblock_array)[j];
+		    if(cache->round(lb->address()) == ucb_in[i]) {
+			break;
+		    }
+		    vul += lblock_time_array[j];
+		}
+	    }
+
+	    return vul * cache->blockSize();
+	}
 
 
-    unsigned long compute_vul_block(BasicBlock *bb, std::vector<Address> ucb_in, std::vector<Address> ucb_out, const otawa::hard::Cache* cache, ilp::System* sys) {
+	unsigned long compute_vul_block(BasicBlock *bb, std::vector<Address> ucb_in, std::vector<Address> ucb_out, const otawa::hard::Cache* cache, ilp::System* sys) {
      
-      // Compute average instruction time
+	    // Compute average instruction time
       
-      unsigned long bb_time = ipet::TIME(bb);
-      unsigned long instr_time = ceil(bb_time / bb->count());
+	    unsigned long bb_time = ipet::TIME(bb);
+	    unsigned long instr_time = ceil(bb_time / bb->count());
       
-      // --- compute vulnerability during execution ---
+	    // --- compute vulnerability during execution ---
       
-      unsigned long vul = 0;
-      auto iter = bb->begin();
-      AllocArray<LBlock *> *lblock_array = BB_LBLOCKS(bb);
-      std::vector<unsigned long> lblock_time_array;
-      for (int i = 0; i < lblock_array->count(); i++) {
-      	LBlock *lb = (*lblock_array)[i];
-	unsigned long time_lblock = 0;
-      	for(int j = 0; j < lb->countInsts(); j++) {
-	  time_lblock += instr_time;
-      	  iter++;
-      	}
-        lblock_time_array.push_back(time_lblock);
-	vul += time_lblock * lb->size();
-      }
+	    unsigned long vul = 0;
+	    auto iter = bb->begin();
+	    AllocArray<LBlock *> *lblock_array = BB_LBLOCKS(bb);
+	    std::vector<unsigned long> lblock_time_array;
+	    for (int i = 0; i < lblock_array->count(); i++) {
+		LBlock *lb = (*lblock_array)[i];
+		unsigned long time_lblock = 0;
+		for(int j = 0; j < lb->countInsts(); j++) {
+		    time_lblock += instr_time;
+		    iter++;
+		}
+		lblock_time_array.push_back(time_lblock);
+		vul += time_lblock * lb->size();
+	    }
      
-      // compute vulnerability ucb_in bb
-      vul += compute_vul_block_in(bb, ucb_in, cache, lblock_time_array);
-      //compute vulnerability ucb_out bb
-      vul += compute_vul_block_out(bb, ucb_out, cache, lblock_time_array);
-
-      unsigned long head_iteration = 0;
-      if(Loop::isHeader(bb)) {
-	head_iteration = 1;
-      }
-      vul *= WEIGHT(bb) + head_iteration;
+	    // compute vulnerability ucb_in bb
+	    vul += compute_vul_block_in(bb, ucb_in, cache, lblock_time_array);
+	    //compute vulnerability ucb_out bb
+	    vul += compute_vul_block_out(bb, ucb_out, cache, lblock_time_array);
+
+	    unsigned long head_iteration = 0;
+	    if(Loop::isHeader(bb)) {
+		head_iteration = 1;
+	    }
+	    vul *= WEIGHT(bb) + head_iteration;
 
       
-      // --- compute vulnerability during miss ---
+	    // --- compute vulnerability during miss ---
       
-      std::vector<unsigned long> lblock_miss_time_array;
-      double miss_cost = 0;
-      for (int i = 0; i < lblock_array->count(); i++) {
-      	LBlock *lb = (*lblock_array)[i];
-	lblock_miss_time_array.push_back(sys->valueOf(MISS_VAR(lb)) * cache->missPenalty());
-      }
+	    std::vector<unsigned long> lblock_miss_time_array;
+	    double miss_cost = 0;
+	    for (int i = 0; i < lblock_array->count(); i++) {
+		LBlock *lb = (*lblock_array)[i];
+		lblock_miss_time_array.push_back(sys->valueOf(MISS_VAR(lb)) * cache->missPenalty());
+	    }
 
-      // compute vulnerability ucb_in bb
-      vul += compute_vul_block_in(bb, ucb_in, cache, lblock_miss_time_array);
-      //compute vulnerability ucb_out bb
-      vul += compute_vul_block_out(bb, ucb_out, cache, lblock_miss_time_array);
+	    // compute vulnerability ucb_in bb
+	    vul += compute_vul_block_in(bb, ucb_in, cache, lblock_miss_time_array);
+	    //compute vulnerability ucb_out bb
+	    vul += compute_vul_block_out(bb, ucb_out, cache, lblock_miss_time_array);
 
-      return vul;
-    }
+	    return vul;
+	}
 
-    unsigned long compute_edge_time(Edge *edge, ilp::System* sys) {
-      unsigned long time_edge = etime::LTS_TIME(edge);
+       	// unsigned long compute_edge_time(Edge *edge, ilp::System* sys) {
+	//   unsigned long time_edge = etime::LTS_TIME(edge);
        
-      elm::Pair<long int, otawa::ilp::Var*> p_s = etime::HTS_CONFIG(edge);
-      if(p_s.snd != NULL) {
-	time_edge += p_s.fst *  sys->valueOf(p_s.snd);
-      }
-      return time_edge;
-    }
+	//   elm::Pair<long int, otawa::ilp::Var*> p_s = etime::HTS_CONFIG(edge);
+	//   if(p_s.snd != NULL) {
+	// 	time_edge += p_s.fst *  sys->valueOf(p_s.snd);
+	//   }
+	//   return time_edge;
+	// }
 
-    unsigned long compute_edge_between(Block* bb_in, Block* bb_out, ilp::System* sys, bool &found) {
-      found = false;
-      
-      for(Block::EdgeIter iter_suc(bb_in->outs()); iter_suc(); iter_suc++) {
-	Edge *edge = *iter_suc;
+	    std::pair<unsigned long, unsigned long> compute_edge_time(Edge *edge, ilp::System* sys)
+	    {
+		std::pair<unsigned long, unsigned long> time_edge;
+		time_edge.first = etime::LTS_TIME(edge);
+		time_edge.second = 0;
+		elm::Pair<long int, otawa::ilp::Var*> p_s = etime::HTS_CONFIG(edge);
+		if(p_s.snd != NULL) {
+		    time_edge.second += p_s.fst *  sys->valueOf(p_s.snd);
+		}
+		return time_edge;
+	    }
+	// //------------------------------------
+	// // Function compute_edge_between
+	// // compute the value of a set of edge between two basic block separates by synth blocks.
+	// //------------------------------------
+	// unsigned long compute_edge_between(Block* bb_in, Block* bb_out, ilp::System* sys, bool &found) {
+	//   found = false;
+	//   // for all edge to a block child of bb_in 
+	//   for(Block::EdgeIter iter_suc(bb_in->outs()); iter_suc(); iter_suc++) {
+	// 	Edge *edge = *iter_suc;
 
-	unsigned long time_edge = compute_edge_time(edge, sys);
-	if(time_edge < 0) {
-	  time_edge = 0;
-	}
-	
-	Block *target = edge->target();
+	// 	// compute time on edge
+	// 	unsigned long time_edge = compute_edge_time(edge, sys);
+	// 	if(time_edge < 0) {
+	// 	  time_edge = 0;
+	// 	}
 	
-	if(target == bb_out) {
-	  found = true;
-	  return time_edge;
-	}
+	// 	Block *target = edge->target();
+	// 	// if the target is corresponding to basic block bb_out
+	// 	if(target == bb_out) {
+	// 	  found = true;
+	// 	  return time_edge;
+	// 	}
 
-	if(target->isBasic()) {
-	  return 0;
-	}
+	// 	// if the block is another basic block then wrong way
+	// 	if(target->isBasic()) {
+	// 	  return 0;
+	// 	}
+
+	// 	// If the block si synth we are looking for the next one
+	// 	unsigned long tmp_time = compute_edge_between(target, bb_out, sys, found);
+	// 	if(found) {
+	// 	  return tmp_time + time_edge;
+	// 	}
 	
-	unsigned long tmp_time = compute_edge_between(target, bb_out, sys, found);
-	if(found) {
-	  return tmp_time + time_edge;
-	}
+	//   }
+      
+	//   return 0;
+	// }
+
+      //------------------------------------
+	// Function compute_edge_between
+	// compute the value of a set of edge between two basic block separates by synth blocks.
+	// first BB time and second edge additional value
+	//------------------------------------
+	// std::pair<unsigned long, unsigned long> compute_edge_between(Block* bb_in, Block* bb_out, ilp::System* sys, bool &found)
+	// {
+	//     found = false;
+	//     // for all edge to a block child of bb_in 
+	//     for(Block::EdgeIter iter_suc(bb_in->outs()); iter_suc(); iter_suc++) {
+	// 	Edge *edge = *iter_suc;
+
+	// 	// compute time on edge
+	// 	std::pair<unsigned long, unsigned long> time_edge = compute_edge_time(edge, sys);
+	// 	if(time_edge.first < 0) {
+	// 	    time_edge.first = 0;
+	// 	}
+	// 	if(time_edge.second < 0) {
+	// 	    time_edge.second = 0;
+	// 	}
 	
-      }
+	// 	Block *target = edge->target();
+	// 	// if the target is corresponding to basic block bb_out
+	// 	if(target == bb_out) {
+	// 	    found = true;
+	// 	    return time_edge;
+	// 	}
 
-      return 0;
-    }
+	// 	// if the block is another basic block then wrong way
+	// 	if(target->isBasic()) {
+	// 	  std::pair<unsigned long, unsigned long> tmp_return;
+	// 	  tmp_return.first = 0;
+	// 	  tmp_return.second = 0;
+	// 	  return tmp_return;
+	// 	}
+
+	// 	// If the block si synth we are looking for the next one
+	// 	std::pair<unsigned long, unsigned long> tmp_time = compute_edge_between(target, bb_out, sys, found);
+	// 	if(found) {
+	// 	    std::pair<unsigned long, unsigned long> tmp_return;
+	// 	    tmp_return.first = tmp_time.first + time_edge.first;
+	// 	    tmp_return.second = tmp_time.second + time_edge.second;
+	// 	    return tmp_return;
+	// 	}
+	
+	//     }
+	//     std::pair<unsigned long, unsigned long> tmp_return;
+	//     tmp_return.first = 0;
+	//     tmp_return.second = 0;
+	//     return tmp_return;
+	// }
     
-    unsigned long compute_vul_edge(BasicBlock* bb_in, BasicBlock* bb_out, std::vector<Address> ucb_in, std::vector<Address> ucb_out, const otawa::hard::Cache* cache, ilp::System* sys) {
-      bool found = false;
-      unsigned long vul_edge = compute_edge_between((Block*)bb_in, (Block*)bb_out, sys, found);
+	// unsigned long compute_vul_edge(BasicBlock* bb_in, BasicBlock* bb_out, std::vector<Address> ucb_in, std::vector<Address> ucb_out, const otawa::hard::Cache* cache, ilp::System* sys) {
+	//     bool found = false;
+	//     unsigned long vul_edge = compute_edge_between((Block*)bb_in, (Block*)bb_out, sys, found);
 
-      vul_edge *= std::min(ucb_in.size(), ucb_out.size()) * cache->blockSize();
-      return vul_edge;
+	//     vul_edge *= std::min(ucb_in.size(), ucb_out.size()) * cache->blockSize();
+	//     return vul_edge;
 	
-    }
-    // long compute_vul_block(BasicBlock *bb, std::vector<Address> ucb_in, std::vector<Address> ucb_out, const otawa::hard::Cache* cache) {
-
-    //   long vul = 0;
-
-    //   // get LBlocks from bb
-    //   AllocArray<LBlock *> *lblock_array = BB_LBLOCKS(bb);
-    //   for (int i = 0; i < lblock_array->count(); i++) {
-    // 	LBlock *lb = (*lblock_array)[i];
-    // 	otawa::Address lb_id = cache->round(lb->address());
-    // 	// for all the lb not in ucb in and out
-    // 	if(find(ucb_out.begin(), ucb_out.end(), lb_id) == ucb_out.end() &&
-    // 	   find(ucb_in.begin(), ucb_in.end(), lb_id) == ucb_in.end()) {
-    // 	  vul += (LBLOCK_TIME(lb) * lb->size());
-    // 	  category_t status = cache::CATEGORY(lb);
-    // 	  if(status != ALWAYS_MISS) {
-    // 	    std::cout << "Strange category, classed as always miss by may analysis and hit by otawa analysis" << std::endl;
-    // 	    vul += cache->missPenalty() * WEIGHT(bb);
-    // 	  } else {
+	// }
+
+	// long compute_vul_block(BasicBlock *bb, std::vector<Address> ucb_in, std::vector<Address> ucb_out, const otawa::hard::Cache* cache) {
+
+	//   long vul = 0;
+
+	//   // get LBlocks from bb
+	//   AllocArray<LBlock *> *lblock_array = BB_LBLOCKS(bb);
+	//   for (int i = 0; i < lblock_array->count(); i++) {
+	// 	LBlock *lb = (*lblock_array)[i];
+	// 	otawa::Address lb_id = cache->round(lb->address());
+	// 	// for all the lb not in ucb in and out
+	// 	if(find(ucb_out.begin(), ucb_out.end(), lb_id) == ucb_out.end() &&
+	// 	   find(ucb_in.begin(), ucb_in.end(), lb_id) == ucb_in.end()) {
+	// 	  vul += (LBLOCK_TIME(lb) * lb->size());
+	// 	  category_t status = cache::CATEGORY(lb);
+	// 	  if(status != ALWAYS_MISS) {
+	// 	    std::cout << "Strange category, classed as always miss by may analysis and hit by otawa analysis" << std::endl;
+	// 	    vul += cache->missPenalty() * WEIGHT(bb);
+	// 	  } else {
 	    
-    // 	  }
-    // 	}
-    //   }
+	// 	  }
+	// 	}
+	//   }
 
      
-    //   for(int i = 0; i < ucb_in.size(); i++) {
-    // 	// In UCB IN  only?
-    // 	if(find(ucb_out.begin(), ucb_out.end(), ucb_in[i]) == ucb_out.end()) {
-    // 	  bool found = false;
-    // 	  // for each lblocks
-    // 	  for (int j = 0; j < lblock_array->count(); j++) {
-    // 	    LBlock *lb = (*lblock_array)[j];
-    // 	    // we consider as vulnerable during lblock execution if we have not found yet the cache block
-    // 	    if(!found) {
-    // 	      vul += (LBLOCK_TIME(lb) * cache->blockSize());
-    // 	      category_t status = cache::CATEGORY(lb);
-    // 	      if(status != ALWAYS_MISS) {
-    // 		vul += cache->missPenalty() * WEIGHT(bb);
-    // 	      }
-    // 	    }
-    // 	    otawa::Address lb_id = cache->round(lb->address());
-    // 	    if(lb_id == ucb_in[i]) {
-    // 	      found = true;
-    // 	    }
-    // 	  }
-    // 	} else {
-    // 	  // In UCB IN  and UCB out?
-    // 	  vul += (ipet::TIME(bb) * cache->blockSize());
-    // 	  category_t status = cache::CATEGORY(lb);
-    // 	  if(status != ALWAYS_MISS) {
-    // 	    vul += cache->missPenalty() * WEIGHT(bb);
-    // 	  }
-    // 	}
-    //   }
+	//   for(int i = 0; i < ucb_in.size(); i++) {
+	// 	// In UCB IN  only?
+	// 	if(find(ucb_out.begin(), ucb_out.end(), ucb_in[i]) == ucb_out.end()) {
+	// 	  bool found = false;
+	// 	  // for each lblocks
+	// 	  for (int j = 0; j < lblock_array->count(); j++) {
+	// 	    LBlock *lb = (*lblock_array)[j];
+	// 	    // we consider as vulnerable during lblock execution if we have not found yet the cache block
+	// 	    if(!found) {
+	// 	      vul += (LBLOCK_TIME(lb) * cache->blockSize());
+	// 	      category_t status = cache::CATEGORY(lb);
+	// 	      if(status != ALWAYS_MISS) {
+	// 		vul += cache->missPenalty() * WEIGHT(bb);
+	// 	      }
+	// 	    }
+	// 	    otawa::Address lb_id = cache->round(lb->address());
+	// 	    if(lb_id == ucb_in[i]) {
+	// 	      found = true;
+	// 	    }
+	// 	  }
+	// 	} else {
+	// 	  // In UCB IN  and UCB out?
+	// 	  vul += (ipet::TIME(bb) * cache->blockSize());
+	// 	  category_t status = cache::CATEGORY(lb);
+	// 	  if(status != ALWAYS_MISS) {
+	// 	    vul += cache->missPenalty() * WEIGHT(bb);
+	// 	  }
+	// 	}
+	//   }
       
-    //   // In UCB OUT  only?
-    //   // For each UCB only in UCB out
-    //   for(int i = 0; i < ucb_out.size(); i++) {
-    // 	if(find(ucb_in.begin(), ucb_in.end(), ucb_out[i]) == ucb_in.end()) {
-    // 	  bool found = false;
-    // 	  // for each lblocks
-    // 	  for (int j = 0; j < lblock_array->count(); j++) {
-    // 	    LBlock *lb = (*lblock_array)[j];
-    // 	    otawa::Address lb_id = cache->round(lb->address());
-    // 	    if(lb_id == ucb_out[i]) {
-    // 	      found = true;
-    // 	    }
-    // 	    // we consider as vulnerable during lblock execution if we have found the cache block
-    // 	    if(found) {
-    // 	      vul += (LBLOCK_TIME(lb) * cache->blockSize());
-    // 	      category_t status = cache::CATEGORY(lb);
-    // 	      if(status != ALWAYS_MISS) {
-    // 		vul += cache->missPenalty() * WEIGHT(bb);
-    // 	      }
-    // 	    }
-    // 	  }
+	//   // In UCB OUT  only?
+	//   // For each UCB only in UCB out
+	//   for(int i = 0; i < ucb_out.size(); i++) {
+	// 	if(find(ucb_in.begin(), ucb_in.end(), ucb_out[i]) == ucb_in.end()) {
+	// 	  bool found = false;
+	// 	  // for each lblocks
+	// 	  for (int j = 0; j < lblock_array->count(); j++) {
+	// 	    LBlock *lb = (*lblock_array)[j];
+	// 	    otawa::Address lb_id = cache->round(lb->address());
+	// 	    if(lb_id == ucb_out[i]) {
+	// 	      found = true;
+	// 	    }
+	// 	    // we consider as vulnerable during lblock execution if we have found the cache block
+	// 	    if(found) {
+	// 	      vul += (LBLOCK_TIME(lb) * cache->blockSize());
+	// 	      category_t status = cache::CATEGORY(lb);
+	// 	      if(status != ALWAYS_MISS) {
+	// 		vul += cache->missPenalty() * WEIGHT(bb);
+	// 	      }
+	// 	    }
+	// 	  }
 	  
-    // 	}
-    //   }
+	// 	}
+	//   }
       
-    //   vul *= compute_total_iteration(bb);
-    //   return vul;
-    // }
+	//   vul *= compute_total_iteration(bb);
+	//   return vul;
+	// }
+
+
+	//-------------------------------------------------------------
+	//OLD Initialize RMB LMB plugin
+	//-------------------------------------------------------------
+
+	bool not_present_in_vect(std::vector<Block *> visited, Block *b)
+	{
+	    for (int i = 0; i < visited.size(); i++)
+	    {
+		if (visited[i] == b)
+		{
+		    return false;
+		}
+	    }
+	    return true;
+	}
+
+	int get_exit_id_of_cfg(CFG *cfg)
+	{
+	    for (CFG::BlockIter block_iter = cfg->blocks(); block_iter(); block_iter++)
+	    {
+		Block *b = *block_iter;
+		bool found = true;
+		for (
+		    Block::EdgeIter iter_suc(b->outs());
+		    iter_suc();
+		    iter_suc++)
+		{
+		    found = false;
+		    break;
+		}
+		if (found)
+		{
+		    return b->id();
+		}
+	    }
+	    return -1;
+	}
+
+	std::vector<Block *> get_last_blocks(CFG *cfg)
+	{
+	    std::vector<Block *> tmp_v;
+	    int id_last = get_exit_id_of_cfg(cfg);
+	    if (id_last == -1)
+	    {
+		return tmp_v;
+	    }
+	    for (CFG::BlockIter block_iter = cfg->blocks(); block_iter(); block_iter++)
+	    {
+		Block *b = *block_iter;
+
+		for (
+		    Block::EdgeIter iter_suc(b->outs());
+		    iter_suc();
+		    iter_suc++)
+		{
+		    Edge *edge = *iter_suc;
+		    Block *target = edge->target();
+		    if (target->id() == id_last)
+		    {
+			tmp_v.push_back(b);
+			break;
+		    }
+		}
+	    }
+	    return tmp_v;
+	}
+
+    
+	void mark_first_bb(Block *b_fct_entry, struct Memory_block *mb, std::vector<Block *> visited)
+	{
+	    visited.push_back(b_fct_entry);
+	    if (b_fct_entry->isBasic())
+	    {
+		struct Memory_block *mb_suc = MB_STRUCT(b_fct_entry);
+		mb->suc.push_back(mb_suc);
+		mb_suc->pred.push_back(mb);
+	    }
+	    else
+	    {
+
+		if (b_fct_entry->isSynth())
+		{
+		    std::vector<Block *> v_tmp;
+		    mark_first_bb(b_fct_entry->toSynth()->callee()->entry(), mb, v_tmp);
+		}
+		else
+		{
+
+		    for (Block::EdgeIter iter_suc(b_fct_entry->outs());
+			 iter_suc();
+			 iter_suc++)
+		    {
+
+			Edge *edge = *iter_suc;
+			Block *target = edge->target();
+			if (not_present_in_vect(visited, target))
+			{
+			    mark_first_bb(target, mb, visited);
+			}
+		    }
+		}
+	    }
+	}
+
+	void mark_last_bb_bis(Block *b_fct_exit, struct Memory_block *mb, std::vector<Block *> visited)
+	{
+	    visited.push_back(b_fct_exit);
+	    //std::cout << "Block: " << b_fct_exit->id() << std::endl;
+	    if (b_fct_exit->isBasic())
+	    {
+		struct Memory_block *mb_pred = MB_STRUCT(b_fct_exit);
+		//std::cout << "----------------------------- FOUND pred" << std::endl;
+		mb_pred->suc.push_back(mb);
+		mb->pred.push_back(mb_pred);
+	    }
+	    else
+	    {
+		if (b_fct_exit->isSynth())
+		{
+		    //std::cout << "is synth" << std::endl;
+		    std::vector<Block *> v_tmp;
+		    mark_last_bb_bis(b_fct_exit->toSynth()->callee()->exit(), mb, v_tmp);
+		}
+		else
+		{
+
+		    for (Block::EdgeIter iter_pred(b_fct_exit->ins());
+			 iter_pred();
+			 iter_pred++)
+		    {
+			//std::cout << "here" << std::endl;
+			Edge *edge = *iter_pred;
+			Block *target = edge->source();
+			//std::cout << "Block: " << target->id() << std::endl;
+			if (not_present_in_vect(visited, target))
+			{
+			    //std::cout << "not present" << std::endl;
+			    mark_last_bb_bis(target, mb, visited);
+			}
+			else
+			{
+			    //std::cout << "present in list" << std::endl;
+			}
+		    }
+		}
+	    }
+	}
+
+	void mark_last_bb(Block *b_fct_exit, Block *main_suc, std::vector<Block *> visited)
+	{
+	    visited.push_back(main_suc);
+	    if (main_suc->isBasic())
+	    {
+		struct Memory_block *mb = MB_STRUCT(main_suc);
+		std::vector<Block *> v_tmp;
+		//std::cout << "----------------------------- FOUND suc" << std::endl;
+		mark_last_bb_bis(b_fct_exit, mb, v_tmp);
+	    }
+	    else
+	    {
+		if (main_suc->isSynth())
+		{
+		    std::vector<Block *> v_tmp;
+		    mark_last_bb(b_fct_exit, main_suc->toSynth()->callee()->entry(), v_tmp);
+		}
+		else
+		{
+
+		    for (Block::EdgeIter iter_suc(main_suc->outs());
+			 iter_suc();
+			 iter_suc++)
+		    {
+			Edge *edge = *iter_suc;
+			Block *target = edge->target();
+			if (not_present_in_vect(visited, target))
+			{
+
+			    mark_last_bb(b_fct_exit, target, visited);
+			}
+		    }
+		}
+	    }
+	}
+
+	void add_links(Block *b, struct Memory_block *mb, std::vector<Block *> visited)
+	{
+	    visited.push_back(b);
+
+	    if (b->isBasic())
+	    {
+		BasicBlock *bb = b->toBasic();
+		struct Memory_block *mb_suc = MB_STRUCT(b);
+		mb->suc.push_back(mb_suc);
+		mb_suc->pred.push_back(mb);
+	    }
+	    else
+	    {
+		if (b->isSynth())
+		{
+		    SynthBlock *sb = b->toSynth();
+		    CFG *cfg_fct = sb->callee();
+
+		    Block *b_fct_entry = cfg_fct->entry();
+		    //Block *b_fct_exit = cfg_fct->exit();
+		    std::vector<Block *> exits = get_last_blocks(cfg_fct);
+		    std::vector<Block *> v_tmp;
+		    mark_first_bb(b_fct_entry, mb, v_tmp);
+
+		    for (Block::EdgeIter iter_suc(b->outs());
+			 iter_suc();
+			 iter_suc++)
+		    {
+			Edge *edge = *iter_suc;
+			Block *target = edge->target();
+			std::vector<Block *> v_tmp_bis;
+			for (int i = 0; i < exits.size(); i++)
+			{
+			    mark_last_bb(exits[i], target, v_tmp_bis);
+			}
+		    }
+		}
+		else
+		{
+
+		    for (Block::EdgeIter iter_suc(b->outs());
+			 iter_suc();
+			 iter_suc++)
+		    {
+			Edge *edge = *iter_suc;
+			Block *target = edge->target();
+			if (not_present_in_vect(visited, target))
+			{
+			    add_links(target, mb, visited);
+			}
+		    }
+		}
+	    }
+	}
+
+	//----------------------------------------------------------------
+
+	// TRUE LRU
+
+	std::vector<Address> add_LRU(std::vector<Address> cache, Address elem, int nb_way) {
+
+	    // if elem already in cache
+	    bool is_present = false;
+	    for(int i = 0; i < cache.size(); i++) {
+		if(cache[i] == elem) {
+		    cache.erase(cache.begin() + i);
+		    break;
+		}
+	    }
+
+	    cache.push_back(elem);
+	    while(cache.size() > nb_way) {
+		cache.erase(cache.begin());
+	    }
+
+	    return cache;
+
       
-    void VulnerabilityProcessor::processWorkSpace(WorkSpace *ws) {
-      const CFGCollection *coll = INVOLVED_CFGS(ws);
-      const otawa::hard::CacheConfiguration *cf = otawa::hard::CACHE_CONFIGURATION_FEATURE.get(ws); 
-      const otawa::hard::Cache* cache = cf->instCache();
+	}
 
-      int nb_index = cache->rowCount();
-      int nb_way = cache->wayCount();
+	std::vector<Address> add_LRU_bis(std::vector<Address> cache, Address elem, int nb_way) {
 
-      unsigned long vul = 0;
+	    // if elem already in cache
+	    bool is_present = false;
+	    for(int i = 0; i < cache.size(); i++) {
+		if(cache[i] == elem) {
+		    cache.erase(cache.begin() + i);
+		    break;
+		}
+	    }
 
-      ilp::System* sys = otawa::ipet::SYSTEM(ws);
+	    cache.insert(cache.begin(), elem);
+	    while(cache.size() > nb_way) {
+		cache.pop_back();
+	    }
 
-      for(CFGCollection::Iter cfg_iter(*coll); cfg_iter(); cfg_iter++) {
-	for(CFG::BlockIter block_iter = cfg_iter->blocks(); block_iter(); block_iter++) {
-	  if(block_iter->isBasic()) {
-	    BasicBlock *bb = block_iter->toBasic();
-	    struct Memory_block *mb = MB_STRUCT(bb);
+	    return cache;
+	}
+    
+	std::vector<Address> rmb_LRU(std::vector<Address> gen, std::vector<Address> rmb, int nb_way)
+	{
+	    for(int i = 0; i < gen.size(); i++) {
+		rmb = add_LRU(rmb, gen[i], nb_way);
+	    }
+	    return rmb;
+	}
 
-	    std::vector<Address> ucb_in = compute_ucb(*(mb->rmb_in), *(mb->lmb_in), nb_way);
-	    std::vector<Address> ucb_out = compute_ucb(*(mb->rmb_out), *(mb->lmb_out), nb_way);
+	std::vector<Address> lmb_LRU(std::vector<Address> gen, std::vector<Address> lmb, int nb_way)
+	{
 
-	    unsigned long vul_tmp = compute_vul_block(bb, ucb_in, ucb_out, cache, sys);
-	    vul += vul_tmp;
-	  }
+	    for(int i = (gen.size()-1); i >= 0; i--) {
+		lmb = add_LRU_bis(lmb, gen[i], nb_way);
+	    }
+	    return lmb;
 	}
-      }
+    
+	void init_gen(BasicBlock *bb, int nb_index, int nb_way, const otawa::hard::Cache *cache) {
+	    Memory_block *mb = MB_STRUCT(bb);
+	    std::vector<Address> vect[nb_index];
+	    AllocArray<LBlock *> *lblock_array = BB_LBLOCKS(bb);
 
-       for(CFGCollection::Iter cfg_iter(*coll); cfg_iter(); cfg_iter++) {
-	for(CFG::BlockIter block_iter = cfg_iter->blocks(); block_iter(); block_iter++) {
-	  if(block_iter->isBasic()) {
-	    BasicBlock *bb = block_iter->toBasic();
-	    
+	    for (int i = 0; i < lblock_array->count(); i++) {
+		LBlock *lb = (*lblock_array)[i];
+		otawa::Address lb_id = cache->round(lb->address());
+		vect[cache->line(lb->address())].push_back(lb_id);
+	    }
+      
+	    for (int index_tmp = 0; index_tmp < nb_index; index_tmp++) {
+		for (int i = 0; i < nb_way; i++) {
+		    if (i < vect[index_tmp].size()) {
+			mb->lmb_gen[index_tmp].push_back(vect[index_tmp][i]);
+		    }
+		    int j = vect[index_tmp].size() - 1 - i;
+		    if (j >= 0) {
+			mb->rmb_gen[index_tmp].insert(mb->rmb_gen[index_tmp].begin(), vect[index_tmp][j]);
+		    }
+		}
+
+		if(mb->lmb_gen[index_tmp].size() != 0)
+		    mb->lmb_in[index_tmp].push_back(mb->lmb_gen[index_tmp]);
+	
+		if(mb->rmb_gen[index_tmp].size() != 0)
+		    mb->rmb_out[index_tmp].push_back(mb->rmb_gen[index_tmp]);
+	    }
+	}
+   
+
+	//-------------------------------------------------------------
+	// RMB LMB
+	//-------------------------------------------------------------
+
+
+	void create_structure(const CFGCollection *coll, int nb_index, int nb_way) {
+	    for (CFGCollection::Iter cfg_iter(*coll); cfg_iter(); cfg_iter++)
+	    {
+		for (CFG::BlockIter block_iter = cfg_iter->blocks(); block_iter(); block_iter++)
+		{
+		    if (block_iter->isBasic())
+		    {
+			BasicBlock *bb = block_iter->toBasic();
+			MB_STRUCT(bb) = new Memory_block(nb_index, nb_way, bb);
+		    }
+		}
+	    }
+
+	}
+
+	void link_structure(const CFGCollection *coll, int nb_way, int nb_index) {
+	    for (CFGCollection::Iter cfg_iter(*coll); cfg_iter(); cfg_iter++)
+	    {
+		for (CFG::BlockIter block_iter = cfg_iter->blocks(); block_iter(); block_iter++)
+		{
+		    if (block_iter->isBasic())
+		    {
+			BasicBlock *bb = block_iter->toBasic();
+
+			Memory_block *mb = MB_STRUCT(bb);
+			mb->block_id = bb->id();
+			for (
+			    Block::EdgeIter iter_suc(bb->outs());
+			    iter_suc();
+			    iter_suc++)
+			{
+
+			    Edge *edge = *iter_suc;
+			    Block *target = edge->target();
+			    std::vector<Block *> visited;
+			    add_links(target, mb, visited);
+			}
+		    }
+		}
+	    }
+
+	}
+
+	void initialize_structure(const CFGCollection *coll, int nb_way, int nb_index, const hard::Cache *cache) {
+	    for (CFGCollection::Iter cfg_iter(*coll); cfg_iter(); cfg_iter++)
+	    {
+		for (CFG::BlockIter block_iter = cfg_iter->blocks(); block_iter(); block_iter++)
+		{
+		    if (block_iter->isBasic())
+		    {
+			BasicBlock *bb = block_iter->toBasic();
+			Memory_block *mb = MB_STRUCT(bb);
+				
+
+			init_gen(bb, nb_index, nb_way, cache);
+		    }
+		}
+	    }
+	}
+
+	void compute_rmb(const CFGCollection *coll, int nb_way, int nb_index) {
+	    bool change = true;
+	    while(change) {
+
+		change = false;
+	  
+		for(CFGCollection::Iter cfg_iter(*coll); cfg_iter(); cfg_iter++) {
+		    for(CFG::BlockIter block_iter = cfg_iter->blocks(); block_iter(); block_iter++) {
+
+			// ----- for each BB -----
+			if(block_iter->isBasic()) {
+			    BasicBlock *bb = block_iter->toBasic();
+			    Memory_block *mb = MB_STRUCT(bb);
+
+			    // ----- for each row -----
+			    for (int index = 0; index < nb_index; index++) {
+
+				// RMB IN
+				mb->rmb_in[index].clear();
+				for (int pred_mb = 0; pred_mb < mb->pred.size(); pred_mb++) {
+				    mb->rmb_in[index] =
+					get_set(vector_union(mb->rmb_in[index],
+							     mb->pred[pred_mb]->rmb_out[index]));	  
+				}
+
+				// RMB OUT
+				std::vector<std::vector<Address>> oldout(mb->rmb_out[index]);
+				mb->rmb_out[index].clear();
+	
+				std::vector<std::vector<Address>> rmb_in = mb->rmb_in[index];
+				if(rmb_in.size() == 0) {
+				    // TODO: Need to modify this part to take into account empty gen
+				    //if(mb->rmb_gen[index].size() != 0) {
+				    mb->rmb_out[index].push_back(mb->rmb_gen[index]);
+				    //}
+				} else {
+				    for (int tmp_rmb = 0; tmp_rmb < rmb_in.size(); tmp_rmb++) {
+					std::vector<Address> tmp_vect = mb->rmb_gen[index];
+					rmb_in[tmp_rmb] = get_set(rmb_LRU(tmp_vect, rmb_in[tmp_rmb], nb_way));
+					mb->rmb_out[index].push_back(rmb_in[tmp_rmb]);
+				    }
+				}
+
+				mb->rmb_out[index] = get_set(mb->rmb_out[index]);
+		
+				// UPDATE END CONDITION
+				if (oldout != mb->rmb_out[index]) {
+				    change = true;
+				}
+		
+			    }
+			}
+		    }
+		}
+	    }
+	}
+
+	void compute_lmb(const CFGCollection *coll, int nb_way, int nb_index) {
+	    bool change = true;
+	    while (change) {
+	
+		change = false;
+	
+		for (CFGCollection::Iter cfg_iter(*coll); cfg_iter(); cfg_iter++) {
+		    for (CFG::BlockIter block_iter = cfg_iter->blocks(); block_iter(); block_iter++) {
+
+			// ----- for each BB -----
+			if (block_iter->isBasic()) {
+			    BasicBlock *bb = block_iter->toBasic();
+			    Memory_block *mb = MB_STRUCT(bb);
+
+			    // ----- for each row -----
+	      
+			    for (int index = 0; index < nb_index; index++) {
+
+				// LMB OUT
+				mb->lmb_out[index].clear();
+				for (int suc_mb = 0; suc_mb < mb->suc.size(); suc_mb++) {
+				    mb->lmb_out[index] =
+					get_set(vector_union(mb->lmb_out[index],
+							     mb->suc[suc_mb]->lmb_in[index]));
+				}
+
+				// LMB IN
+				std::vector<std::vector<Address>> oldout(mb->lmb_in[index]);
+				mb->lmb_in[index].clear();
+
+				std::vector<std::vector<Address>> lmb_out = get_set(mb->lmb_out[index]);
+				if(lmb_out.size() == 0) {
+				    // TODO: Need to modify this part to take into account empty gen
+				    //if(mb->lmb_gen[index].size() != 0) {
+				    mb->lmb_in[index].push_back(mb->lmb_gen[index]);
+				    //}
+				} else {
+				    for (int tmp_lmb = 0; tmp_lmb < lmb_out.size(); tmp_lmb++) {
+					std::vector<Address> tmp_vect = mb->lmb_gen[index];
+					lmb_out[tmp_lmb] = get_set(lmb_LRU(tmp_vect, lmb_out[tmp_lmb], nb_way));
+					mb->lmb_in[index].push_back(lmb_out[tmp_lmb]);
+				    }
+				}
+
+				mb->lmb_in[index] = get_set(mb->lmb_in[index]);
+
+				// UPDATE END CONDITION
+				if (oldout != mb->lmb_in[index]) {
+				    change = true;
+				}
+			    }
+			}
+		    }
+		}
+	    }
+      
+	}
+    
+	void start_rmb_lmb_computation(WorkSpace *ws)
+	{
+
+	    const CFGCollection *coll = INVOLVED_CFGS(ws);
+
+	    const otawa::hard::CacheConfiguration *cf = otawa::hard::CACHE_CONFIGURATION_FEATURE.get(ws); 
+	    const otawa::hard::Cache* cache = cf->instCache();
+
+	    int nb_index = cache->rowCount();
+	    int nb_way = cache->wayCount();
+
+	    // create structures
+	    create_structure(coll, nb_index, nb_way);
+      
+	    // links structures
+	    link_structure(coll, nb_way, nb_index);
+
+	    // Initialize all structures
+	    initialize_structure(coll, nb_way, nb_index, cache);
+
+	    // RMB
+
+	    compute_rmb(coll, nb_way, nb_index);
+      
+	    // LMB
+
+	    compute_lmb(coll, nb_way, nb_index);
+      
+	    for (CFGCollection::Iter cfg_iter(*coll); cfg_iter(); cfg_iter++) {
+		for (CFG::BlockIter block_iter = cfg_iter->blocks(); block_iter(); block_iter++) {
+		    if (block_iter->isBasic()) {
+
+			BasicBlock *bb = block_iter->toBasic();
+			Memory_block *mb = MB_STRUCT(bb);
+		    }
+		}
+	    }
+      
+	}
+
+	//-------------------------------------------------------------
+	// Vulnerability
+	//-------------------------------------------------------------
+
+
+	long data_vulnerable(LBlock *lb,  const otawa::hard::Cache* cache) {
+	    BasicBlock* bb = lb->bb();
 	    struct Memory_block *mb = MB_STRUCT(bb);
+	    std::vector<Address> ucb_out = compute_ucb(*(mb->rmb_out), *(mb->lmb_out), cache->wayCount());
+	    otawa::Address lb_id = cache->round(lb->address());
+	    for(int i = 0; i < ucb_out.size(); i++) {
+		if(ucb_out[i] == lb_id) {
+		    return lb->size();
+		}
+	    }
+	    return cache->blockSize();
+	}
+
+
+      long data_vulnerability_on_path_ex(otawa::Address cb, Block *b, const otawa::hard::Cache* cache, std::vector<Block*> current_path,  ilp::System* sys) {
+         struct Memory_block *mb = MB_STRUCT(b);
+	 std::vector<Address> ucb_out = compute_ucb(*(mb->rmb_out), *(mb->lmb_out), cache->wayCount());
+	 std::vector<Address> ucb_in = compute_ucb(*(mb->rmb_in), *(mb->lmb_in), cache->wayCount());
+	 bool is_present = false;
+	 // If not present in exit ucb of the block
+	 for(int i = 0; i < ucb_out.size(); i++) {
+	   if(ucb_out[i] == cb) {
+	     is_present = true;
+	   }
+	 }
+	 if(!is_present) {
+	   return -1;
+	 }
+
+	 // If no present in the entry ucb of the block (call during the block)
+	 is_present = false;
+	 // If not present in exit ucb of the block
+	 for(int i = 0; i < ucb_in.size(); i++) {
+	   if(ucb_in[i] == cb) {
+	     is_present = true;
+	   }
+	 }
+	 if(!is_present) {
+	   return 0;
+	 }
 
-	    std::vector<Address> ucb_in = compute_ucb(*(mb->rmb_out), *(mb->lmb_out), nb_way);
+	 // Explore different paths
 
-	    for(int i = 0; i < mb->suc.size(); i++) {
-	      struct Memory_block *mb_suc = MB_STRUCT(bb);
-	      std::vector<Address> ucb_out = compute_ucb(*(mb_suc->rmb_in), *(mb_suc->lmb_in), nb_way);
-	      unsigned long vul_tmp = compute_vul_edge(bb, mb_suc->bb_ptr, ucb_in, ucb_out, cache, sys);
-	       vul += vul_tmp;
+	 current_path.push_back(b);
+	 unsigned long iteration = compute_total_iteration(b);
+	 long longuest_path = 0;
+	 for(Block::EdgeIter iter_pred(b->ins()); iter_pred(); iter_pred++) {
+	   Edge *edge = *iter_pred;
+	   Block *source = edge->source();
+	   if(find(current_path.begin(), current_path.end(), source) == current_path.end()) {
+	     long tmp = data_vulnerability_on_path_ex(cb, source, cache, current_path, sys);
+	     if(tmp != -1) {
 	      
+	       elm::Pair<long int, otawa::ilp::Var*> p = etime:: HTS_CONFIG(edge);
+	       tmp += p.fst * sys->valueOf(p.snd);
+	       tmp += iteration * etime::LTS_TIME(edge);
+	       longuest_path = max(longuest_path, tmp);
+
+	     }
+	   }
+	 }
+	 return longuest_path;
+      }
+      
+      long data_vulnerability_on_path(LBlock *lb,  const otawa::hard::Cache* cache,  ilp::System* sys) {
+	    // Look if the cache block of the lblock is present in the Useful Cache Block at the entry of the Basic Block
+	    BasicBlock *bb = lb->bb();
+	    struct Memory_block *mb = MB_STRUCT(bb);
+	    std::vector<Address> ucb_in = compute_ucb(*(mb->rmb_in), *(mb->lmb_in), cache->wayCount());
+	    otawa::Address lb_id = cache->round(lb->address());
+	    bool is_present = false;
+	    for(int i = 0; i < ucb_in.size(); i++) {
+		if(ucb_in[i] == lb_id) {
+		    is_present = true;
+		}
+	    }
+	    // If it is not the case then it means that the lblock is not vulnerable on a path.
+	    if(!is_present) {
+		return 0;
+	    }
+	    // If it is the case we have to list all the path and take the longest.
+
+	    // TODO !!!
+	    std::vector<Block*> current_path;
+	    long max_value = 0;
+	    for (Block::EdgeIter iter_pred(bb->ins()); iter_pred(); iter_pred++) {
+		Edge *edge = *iter_pred;
+		Block *source = edge->source();
+		max_value = max(max_value, data_vulnerability_on_path_ex(cache->round(lb->address()), source, cache, current_path, sys));
 	    }
+	    return max_value;
+	}
+
+      long maximum_execution_time_bb(BasicBlock *bb, ilp::System* sys) {
+	    long execution_time = 0;
+	    unsigned long iteration = compute_total_iteration(bb);
+		 
+	    for (Block::EdgeIter iter_pred(bb->ins()); iter_pred(); iter_pred++) {
+		Edge *edge = *iter_pred;
+		Block *source = edge->source();
+		// 3 cases
+		// - basic block: execution time is on edge before
+		// - synth block: execution time is on exit fct edge
+		// - other: 0
+		if(source->isBasic()) {
+		    elm::Pair<long int, otawa::ilp::Var*> p = etime:: HTS_CONFIG(edge);
+		    long time_tmp = p.fst * sys->valueOf(p.snd);
+		    time_tmp += iteration * etime::LTS_TIME(edge);
+		    execution_time = max(execution_time, time_tmp);
+		} else {
+		    if(source->isSynth()) {
+			SynthBlock* sb = bb->toSynth();
+			Block* ex = sb->callee()->exit();
+			long time_tmp_ex = 0;
+			for (Block::EdgeIter iter_pred_ex(ex->ins()); iter_pred_ex(); iter_pred_ex++) {
+			    Edge *edge_ex = *iter_pred_ex;
+			    long tmp = 0;
+			    elm::Pair<long int, otawa::ilp::Var*> p_ex = etime:: HTS_CONFIG(edge_ex);
+			    tmp = p_ex.fst * sys->valueOf(p_ex.snd);
+			    tmp += iteration * etime::LTS_TIME(edge_ex);
+			    time_tmp_ex = max(time_tmp_ex, tmp);
+			}
+			execution_time = max(execution_time, time_tmp_ex);
+		    }
+		}
+	    }
+	    return execution_time;
+	}
+	  
+      long data_vulnerability(LBlock *lb,  const otawa::hard::Cache* cache,  ilp::System* sys) {
+	    long data_size =  data_vulnerable(lb, cache);
+	    long v = maximum_execution_time_bb(lb->bb(), sys);
+	    v += data_vulnerability_on_path(lb, cache, sys);
+	    return data_size * v;
+	}
+    
+    
+    
+	//-------------------------------------------------------------
+	// PROCESS WORKSPACE
+	//-------------------------------------------------------------
+
+	void VulnerabilityProcessor::processWorkSpace(WorkSpace *ws) {
+	    // Initialize RMB LMB
+	    vulnerability::start_rmb_lmb_computation(ws);
+
+	    //Get cache configuration
+	    const CFGCollection *coll = INVOLVED_CFGS(ws);
+	    const otawa::hard::CacheConfiguration *cf = otawa::hard::CACHE_CONFIGURATION_FEATURE.get(ws); 
+	    const otawa::hard::Cache* cache = cf->instCache();
+
+	    int nb_index = cache->rowCount();
+	    int nb_way = cache->wayCount();
+
+	    // Initialization of vulnerability cost to 0
+	    unsigned long vul = 0;
+	    std::vector<Cache_Miss> miss_collection;
+	    ilp::System* sys = otawa::ipet::SYSTEM(ws);
+
+	    // For all basic block of any CFG
+	    for(CFGCollection::Iter cfg_iter(*coll); cfg_iter(); cfg_iter++) {
+		for(CFG::BlockIter block_iter = cfg_iter->blocks(); block_iter(); block_iter++) {
+		  if(block_iter->isBasic()) {
+		    BasicBlock *bb = block_iter->toBasic();
+		    AllocArray<LBlock *> *lblock_array = BB_LBLOCKS(bb);
+		    for (int i = 0; i < lblock_array->count(); i++) {
+		      LBlock *lb = (*lblock_array)[i];
+		      vul += data_vulnerability(lb, cache, sys);
+		    }
+		  }
+		}
+	    }
+	    VUL(ws) = vul;
+	    // // For all basic block of any CFG
+	    // for(CFGCollection::Iter cfg_iter(*coll); cfg_iter(); cfg_iter++) {
+	    // 	for(CFG::BlockIter block_iter = cfg_iter->blocks(); block_iter(); block_iter++) {
+	    // 	  if(block_iter->isBasic()) {
 	    
-	   
-	  }
+	    // 	    BasicBlock *bb = block_iter->toBasic();
+	    // 	    struct Memory_block *mb = MB_STRUCT(bb);
+
+	    // 	    // Get UCB (in and out) sets 
+	    // 	    std::vector<Address> ucb_in = compute_ucb(*(mb->rmb_in), *(mb->lmb_in), nb_way);
+	    // 	    std::vector<Address> ucb_out = compute_ucb(*(mb->rmb_out), *(mb->lmb_out), nb_way);
+
+	    // 	    // Compute the vulnerability of the basic block with these value
+	    // 	    unsigned long vul_tmp = compute_vul_block(bb, ucb_in, ucb_out, cache, sys);
+	    // 	    vul += vul_tmp;
+	    
+	    // 	  }
+	    // 	}
+	    // }
+
+      
+	    // // For all basic block of any CFG
+	    // for(CFGCollection::Iter cfg_iter(*coll); cfg_iter(); cfg_iter++) {
+	    // 	for(CFG::BlockIter block_iter = cfg_iter->blocks(); block_iter(); block_iter++) {
+	    // 	  if(block_iter->isBasic()) {
+	    
+	    // 	    BasicBlock *bb = block_iter->toBasic();
+	    // 	    struct Memory_block *mb = MB_STRUCT(bb);
+
+	    // 	    // Get UCB (in) set
+	    // 	    std::vector<Address> ucb_in = compute_ucb(*(mb->rmb_out), *(mb->lmb_out), nb_way);
+
+	    // 	    for(int i = 0; i < mb->suc.size(); i++) {
+	    // 	      struct Memory_block *mb_suc = MB_STRUCT(bb);
+	    // 	      std::vector<Address> ucb_out = compute_ucb(*(mb_suc->rmb_in), *(mb_suc->lmb_in), nb_way);
+	    // 	      unsigned long vul_tmp = compute_vul_edge(bb, mb_suc->bb_ptr, ucb_in, ucb_out, cache, sys);
+	    // 	      vul += vul_tmp;
+	    // 	    }
+	    // 	  }
+	    // 	}
+	    // }
+
+	    // VUL(ws) = vul;
 	}
-      }
 
-      VUL(ws) = vul;
-    }
 
 
+	// definition propriete 
+	/*
+	  Identifier<DAGHNode*> DAG_HNODE("otawa::vulnerability::DAG_HNODE");
+	*/
+    
+	Identifier<std::vector<Address>*> UCB_IN("otawa::vulnerability::UCB_IN");
+	Identifier<std::vector<Address>*> UCB_OUT("otawa::vulnerability::UCB_OUT");
+	Identifier<unsigned long> VUL("otowa::vulnerability::VUL");
 
-    // definition propriete 
-    /*
-      Identifier<DAGHNode*> DAG_HNODE("otawa::vulnerability::DAG_HNODE");
-    */
-    Identifier<std::vector<Address>*> UCB_IN("otawa::initialize_RMB_LMB::UCB_IN");
-    Identifier<std::vector<Address>*> UCB_OUT("otawa::initialize_RMB_LMB::UCB_OUT");
-    Identifier<unsigned long> VUL("otowa::initialize_RMB_LMB::VUL");
-  }
+	//----------------------------------------------------
+	// Initialize RMB LMB old plugin
+	//----------------------------------------------------
+    
+	Identifier<struct Memory_block *> MB_STRUCT("otawa::vulnerability::MB_STRUCT");
+    }
 }
diff --git a/vulnerability/vulnerability.so b/vulnerability/vulnerability.so
index 3e236d85990519abc3fc056c291818dee61da5ad..8f37dffed3728e82eef436f8c8fb6230f21d0fda 100755
Binary files a/vulnerability/vulnerability.so and b/vulnerability/vulnerability.so differ