diff --git a/AMOEBAonAMAK/src/agents/AmoebaAgent.java b/AMOEBAonAMAK/src/agents/AmoebaAgent.java
index 45a2c6c1ba8e1985d2d4a11c0c2075cfeff62fb5..8ae90bc81b63ebea93836dfe2a4d0c0d07bab4fc 100644
--- a/AMOEBAonAMAK/src/agents/AmoebaAgent.java
+++ b/AMOEBAonAMAK/src/agents/AmoebaAgent.java
@@ -1,109 +1,110 @@
-package agents;
-
-import agents.percept.Percept;
-import fr.irit.smac.amak.Agent;
-import fr.irit.smac.amak.tools.Loggable;
-import gui.RenderStrategy;
-import kernel.AMOEBA;
-import kernel.World;
-
-/**
- * The base class for all AMOEBA agents
- */
-public abstract class AmoebaAgent extends Agent<AMOEBA, World> implements Loggable {
-	// Attributes
-	protected String name;
-	private boolean dying;
-	
-	protected RenderStrategy renderStrategy;
-
-	/**
-	 * Instantiate a new agent attached to an amoeba
-	 * @param the amoeba
-	 */
-	public AmoebaAgent(AMOEBA amas, Object... params) {
-		super(amas, params);
-		this.dying = false;
-	}
-	
-	@Override
-	protected void onReady() {
-		super.onReady();
-		logger().debug("CYCLE "+getAmas().getCycle(), "Agent %s ready.", toString());
-	}
-
-	@Override
-	protected void onDecide() {
-	}
-
-	@Override
-	protected void onRenderingInitialization() {
-		if(renderStrategy != null) {
-			renderStrategy.initialize();
-		}
-	}
-	
-	@Override
-	public void onUpdateRender() {
-		amas.getEnvironment().incrementNbActivatedAgent();
-		if(renderStrategy != null && !isDying()) {
-			if (amas.isRenderUpdate()) {
-				renderStrategy.render();
-			}
-		}
-	}
-
-	/**
-	 * Set the name of the agent. Useful for visualization, and essential for {@link Percept}.
-	 * @param name
-	 */
-	public void setName(String name) {
-		this.name = name;
-	}
-	
-	@Override
-	public void destroy() {
-		dying = true;
-		if(renderStrategy != null) {
-			renderStrategy.delete();
-		}
-		super.destroy();
-		logger().debug("CYCLE "+getAmas().getCycle(), "Agent %s destroyed.", toString());
-	}
-
-	/**
-	 * Get the name of the agent. Useful for visualization, and essential for {@link Percept}.
-	 * @param name
-	 */
-	public String getName() {
-		return name;
-	}
-
-	/**
-	 * Tell if the agent is dying. A dying agent no longer perform any useful action, but is not yet removed from its system.
-	 * @return
-	 */
-	public boolean isDying() {
-		return dying;
-	}
-	
-	/**
-	 * Set the render strategy of an agent.<br/>
-	 * {@link RenderStrategy#delete()} the old one, and {@link RenderStrategy#initialize()} the new one.
-	 * @param renderStrategy
-	 * @see RenderStrategy
-	 */
-	public void setRenderStrategy(RenderStrategy renderStrategy) {
-		if(this.renderStrategy != null) this.renderStrategy.delete();
-		this.renderStrategy = renderStrategy;
-		if(this.renderStrategy != null) this.renderStrategy.initialize();
-	}
-	
-	/**
-	 * Get the render strategy of an agent.
-	 * @return
-	 */
-	public RenderStrategy getRenderStrategy() {
-		return renderStrategy;
-	}
-}
+package agents;
+
+import agents.percept.Percept;
+import fr.irit.smac.amak.Agent;
+import fr.irit.smac.amak.tools.Loggable;
+import gui.RenderStrategy;
+import kernel.AMOEBA;
+import kernel.World;
+
+/**
+ * The base class for all AMOEBA agents
+ */
+public abstract class AmoebaAgent extends Agent<AMOEBA, World> implements Loggable {
+	// Attributes
+	protected String name;
+	private boolean dying;
+	
+	protected RenderStrategy renderStrategy;
+
+	/**
+	 * Instantiate a new agent attached to an amoeba
+	 * @param the amoeba
+	 */
+	public AmoebaAgent(AMOEBA amas, Object... params) {
+		super(amas, params);
+		this.dying = false;
+	}
+	
+	@Override
+	protected void onReady() {
+		super.onReady();
+		logger().debug("CYCLE "+getAmas().getCycle(), "Agent %s ready.", toString());
+	}
+
+	@Override
+	protected void onDecide() {
+	}
+
+	@Override
+	protected void onRenderingInitialization() {
+		if(renderStrategy != null) {
+			renderStrategy.initialize(getAmas().getVUIMulti());
+			
+		}
+	}
+	
+	@Override
+	public void onUpdateRender() {
+		amas.getEnvironment().incrementNbActivatedAgent();
+		if(renderStrategy != null && !isDying()) {
+			if (amas.isRenderUpdate()) {
+				renderStrategy.render();
+			}
+		}
+	}
+
+	/**
+	 * Set the name of the agent. Useful for visualization, and essential for {@link Percept}.
+	 * @param name
+	 */
+	public void setName(String name) {
+		this.name = name;
+	}
+	
+	@Override
+	public void destroy() {
+		dying = true;
+		if(renderStrategy != null) {
+			renderStrategy.delete();
+		}
+		super.destroy();
+		logger().debug("CYCLE "+getAmas().getCycle(), "Agent %s destroyed.", toString());
+	}
+
+	/**
+	 * Get the name of the agent. Useful for visualization, and essential for {@link Percept}.
+	 * @param name
+	 */
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 * Tell if the agent is dying. A dying agent no longer perform any useful action, but is not yet removed from its system.
+	 * @return
+	 */
+	public boolean isDying() {
+		return dying;
+	}
+	
+	/**
+	 * Set the render strategy of an agent.<br/>
+	 * {@link RenderStrategy#delete()} the old one, and {@link RenderStrategy#initialize()} the new one.
+	 * @param renderStrategy
+	 * @see RenderStrategy
+	 */
+	public void setRenderStrategy(RenderStrategy renderStrategy) {
+		if(this.renderStrategy != null) this.renderStrategy.delete();
+		this.renderStrategy = renderStrategy;
+		if(this.renderStrategy != null) this.renderStrategy.initialize(getAmas().getVUIMulti());
+	}
+	
+	/**
+	 * Get the render strategy of an agent.
+	 * @return
+	 */
+	public RenderStrategy getRenderStrategy() {
+		return renderStrategy;
+	}
+}
diff --git a/AMOEBAonAMAK/src/experiments/nDimensionsLaunchers/F_N_LauncherMultiUI.java b/AMOEBAonAMAK/src/experiments/nDimensionsLaunchers/F_N_LauncherMultiUI.java
new file mode 100644
index 0000000000000000000000000000000000000000..7b50124964d5a245386f9ffdf49c536d5720112c
--- /dev/null
+++ b/AMOEBAonAMAK/src/experiments/nDimensionsLaunchers/F_N_LauncherMultiUI.java
@@ -0,0 +1,265 @@
+package experiments.nDimensionsLaunchers;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.ArrayList;
+
+import experiments.FILE;
+import fr.irit.smac.amak.Configuration;
+import fr.irit.smac.amak.examples.randomantsMultiUi.AntHillExampleMultiUI;
+import fr.irit.smac.amak.examples.randomantsMultiUi.WorldExampleMultiUI;
+import fr.irit.smac.amak.ui.AmasMultiUIWindow;
+import fr.irit.smac.amak.ui.VUI;
+import fr.irit.smac.amak.ui.VUIMulti;
+import gui.AmoebaMultiUIWindow;
+import gui.AmoebaWindow;
+import javafx.application.Application;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.scene.control.Slider;
+import javafx.stage.Stage;
+import kernel.AMOEBA;
+import kernel.StudiedSystem;
+import kernel.backup.BackupSystem;
+import kernel.backup.IBackupSystem;
+import kernel.backup.SaveHelperImpl;
+
+
+/**
+ * The Class BadContextLauncherEasy.
+ */
+public class F_N_LauncherMultiUI extends Application implements Serializable {
+
+
+	public static final double oracleNoiseRange = 0.5;
+	public static final double learningSpeed = 0.01;
+	public static final int regressionPoints = 100;
+	public static final int dimension = 2;
+	public static final double spaceSize = 50.0	;
+	public static final int nbOfModels = 3	;
+	public static final int normType = 2	;
+	public static final boolean randomExploration = true;
+	public static final boolean limitedToSpaceZone = true;
+	//public static final double mappingErrorAllowed = 0.07; // BIG SQUARE
+	public static double mappingErrorAllowed = 0.03; // MULTI
+	public static final double explorationIncrement = 1.0	;
+	public static final double explorationWidht = 0.5	;
+	
+	public static final int nbCycle = 1000;
+	
+
+	
+	public static void main(String[] args) throws IOException {
+		
+		
+		Application.launch(args);
+
+
+	}
+	
+	@Override
+	public void start(Stage arg0) throws Exception, IOException {
+
+		Configuration.multiUI=true;
+		Configuration.commandLineMode = false;
+		Configuration.allowedSimultaneousAgentsExecution = 1;
+		Configuration.waitForGUI = true;
+		Configuration.plotMilliSecondsUpdate = 20000;
+		
+		VUIMulti amoebaVUI = VUIMulti.get("2D");
+		AmoebaMultiUIWindow amoebaUI = new AmoebaMultiUIWindow("ELLSA", amoebaVUI);
+		AMOEBA amoeba = new AMOEBA(amoebaUI,  amoebaVUI);
+		
+		StudiedSystem studiedSystem = new F_N_Manager(spaceSize, dimension, nbOfModels, normType, randomExploration, explorationIncrement,explorationWidht,limitedToSpaceZone, oracleNoiseRange);
+		amoeba.setStudiedSystem(studiedSystem);
+		IBackupSystem backupSystem = new BackupSystem(amoeba);
+		File file = new File("resources/twoDimensionsLauncher.xml");
+		backupSystem.load(file);
+		
+		amoeba.saver = new SaveHelperImpl(amoeba);
+		amoeba.allowGraphicalScheduler(true);
+		amoeba.setRenderUpdate(true);		
+		amoeba.data.learningSpeed = learningSpeed;
+		amoeba.data.numberOfPointsForRegression = regressionPoints;
+		amoeba.getEnvironment().setMappingErrorAllowed(mappingErrorAllowed);
+		
+		// Exemple for adding a tool in the toolbar
+		Slider slider = new Slider(0.01, 0.1, mappingErrorAllowed);
+		slider.setShowTickLabels(true);
+		slider.setShowTickMarks(true);
+		
+		slider.valueProperty().addListener(new ChangeListener<Number>() {
+			@Override
+			public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
+				System.out.println("new Value "+newValue);
+				mappingErrorAllowed = (double)newValue;
+				amoeba.getEnvironment().setMappingErrorAllowed(mappingErrorAllowed);
+			}
+		});
+		amoebaUI.addToolbar(slider);
+		
+		studiedSystem.playOneStep();
+		amoeba.learn(studiedSystem.getOutput());
+		
+		VUIMulti amoebaVUI2 = VUIMulti.get("2D");
+		AmoebaMultiUIWindow amoebaUI2 = new AmoebaMultiUIWindow("ELLSA", amoebaVUI2);
+		AMOEBA amoeba2 = new AMOEBA(amoebaUI2,  amoebaVUI2);
+		
+		StudiedSystem studiedSystem2 = new F_N_Manager(spaceSize, dimension, nbOfModels, normType, randomExploration, explorationIncrement,explorationWidht,limitedToSpaceZone, oracleNoiseRange);
+		amoeba2.setStudiedSystem(studiedSystem2);
+		IBackupSystem backupSystem2 = new BackupSystem(amoeba2);
+		File file2 = new File("resources/twoDimensionsLauncher.xml");
+		backupSystem2.load(file2);
+		
+		amoeba2.saver = new SaveHelperImpl(amoeba2);
+		amoeba2.allowGraphicalScheduler(true);
+		amoeba2.setRenderUpdate(true);		
+		amoeba2.data.learningSpeed = learningSpeed;
+		amoeba2.data.numberOfPointsForRegression = regressionPoints;
+		amoeba2.getEnvironment().setMappingErrorAllowed(mappingErrorAllowed);
+		
+		// Exemple for adding a tool in the toolbar
+		Slider slider2 = new Slider(0.01, 0.1, mappingErrorAllowed);
+		slider2.setShowTickLabels(true);
+		slider2.setShowTickMarks(true);
+		
+		slider2.valueProperty().addListener(new ChangeListener<Number>() {
+			@Override
+			public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
+				System.out.println("new Value "+newValue);
+				mappingErrorAllowed = (double)newValue;
+				amoeba2.getEnvironment().setMappingErrorAllowed(mappingErrorAllowed);
+			}
+		});
+		amoebaUI2.addToolbar(slider2);
+		
+		studiedSystem2.playOneStep();
+		amoeba2.learn(studiedSystem2.getOutput());
+		
+
+		
+	}
+
+	public static void launch() throws IOException{
+		
+		
+		
+		
+		// Set AMAK configuration before creating an AMOEBA
+		
+		
+		AMOEBA amoeba = new AMOEBA(null,  VUIMulti.get("2D"));
+		StudiedSystem studiedSystem = new F_N_Manager(spaceSize, dimension, nbOfModels, normType, randomExploration, explorationIncrement,explorationWidht,limitedToSpaceZone, oracleNoiseRange);
+		amoeba.setStudiedSystem(studiedSystem);
+		IBackupSystem backupSystem = new BackupSystem(amoeba);
+		File file = new File("resources/twoDimensionsLauncher.xml");
+		backupSystem.load(file);
+		
+		
+		amoeba.saver = new SaveHelperImpl(amoeba);
+		amoeba.allowGraphicalScheduler(true);
+		amoeba.setRenderUpdate(true);		
+		amoeba.data.learningSpeed = learningSpeed;
+		amoeba.data.numberOfPointsForRegression = regressionPoints;
+		amoeba.getEnvironment().setMappingErrorAllowed(mappingErrorAllowed);
+		
+		// Exemple for adding a tool in the toolbar
+		Slider slider = new Slider(0.01, 0.1, mappingErrorAllowed);
+		slider.setShowTickLabels(true);
+		slider.setShowTickMarks(true);
+		
+		slider.valueProperty().addListener(new ChangeListener<Number>() {
+			@Override
+			public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
+				System.out.println("new Value "+newValue);
+				mappingErrorAllowed = (double)newValue;
+				amoeba.getEnvironment().setMappingErrorAllowed(mappingErrorAllowed);
+			}
+		});
+		AmoebaWindow.addToolbar(slider);
+		
+		studiedSystem.playOneStep();
+		amoeba.learn(studiedSystem.getOutput());
+		
+		/* AUTOMATIC */
+//		long start = System.currentTimeMillis();
+//		for (int i = 0; i < nbCycle; ++i) {
+//			studiedSystem.playOneStep();
+//			amoeba.learn(studiedSystem.getOutput());
+//		}
+//		long end = System.currentTimeMillis();
+//		System.out.println("Done in : " + (end - start) );
+//		
+//		start = System.currentTimeMillis();
+//		for (int i = 0; i < nbCycle; ++i) {
+//			studiedSystem.playOneStep();
+//			amoeba.request(studiedSystem.getOutput());
+//		}
+//		end = System.currentTimeMillis();
+//		System.out.println("Done in : " + (end - start) );
+		
+		
+//		/* XP PIERRE */
+//		
+//		String fileName = fileName(new ArrayList<String>(Arrays.asList("GaussiennePierre")));
+//		
+//		FILE Pierrefile = new FILE("Pierre",fileName);
+//		for (int i = 0; i < nbCycle; ++i) {
+//			studiedSystem.playOneStep();
+//			amoeba.learn(studiedSystem.getOutput());
+//			if(amoeba.getHeadAgent().isActiveLearning()) {
+//				studiedSystem.setActiveLearning(true);
+//				studiedSystem.setSelfRequest(amoeba.getHeadAgent().getSelfRequest());
+//				 
+//			}
+//		}
+//		
+//		for (int i = 0; i < 10; ++i) {
+//			studiedSystem.playOneStep();
+//			System.out.println(studiedSystem.getOutput());
+//			System.out.println(amoeba.request(studiedSystem.getOutput()));
+//			
+//			
+//		}
+//		
+//		Pierrefile.write(new ArrayList<String>(Arrays.asList("ID contexte","Coeff Cte","Coeff X0","Coeff X1","Min Value","Max Value")));
+//		
+//		for(Context ctxt : amoeba.getContexts()) {
+//			
+//			writeMessage(Pierrefile, ctxt.toStringArrayPierre());
+//
+//		}
+//		
+//		
+//		Pierrefile.close();
+		
+	
+	}
+	
+	public static String fileName(ArrayList<String> infos) {
+		String fileName = "";
+		
+		for(String info : infos) {
+			fileName += info + "_";
+		}
+		
+		return fileName;
+	}
+	
+	public static void writeMessage(FILE file, ArrayList<String> message) {
+		
+		file.initManualMessage();
+		
+		for(String m : message) {
+			file.addManualMessage(m);
+		}
+		
+		file.sendManualMessage();
+		
+	}
+
+
+
+	
+}
diff --git a/AMOEBAonAMAK/src/gui/AmoebaMultiUIWindow.java b/AMOEBAonAMAK/src/gui/AmoebaMultiUIWindow.java
new file mode 100644
index 0000000000000000000000000000000000000000..43f23e59b758a7bd6fb77dd2068b388db48c6874
--- /dev/null
+++ b/AMOEBAonAMAK/src/gui/AmoebaMultiUIWindow.java
@@ -0,0 +1,166 @@
+package gui;
+
+import java.util.HashMap;
+
+import javax.management.InstanceAlreadyExistsException;
+
+import fr.irit.smac.amak.tools.Log;
+import fr.irit.smac.amak.tools.RunLaterHelper;
+import fr.irit.smac.amak.ui.AmakPlot;
+import fr.irit.smac.amak.ui.AmakPlot.ChartType;
+import fr.irit.smac.amak.ui.AmasMultiUIWindow;
+import fr.irit.smac.amak.ui.MainWindow;
+import fr.irit.smac.amak.ui.SchedulerToolbar;
+import fr.irit.smac.amak.ui.VUI;
+import fr.irit.smac.amak.ui.VUIMulti;
+import fr.irit.smac.amak.ui.drawables.Drawable;
+import javafx.application.Application;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.scene.control.Button;
+import javafx.scene.control.Menu;
+import javafx.scene.control.Slider;
+import javafx.scene.control.ToggleButton;
+import javafx.scene.control.Tooltip;
+import javafx.scene.paint.Color;
+import kernel.AMOEBA;
+import kernel.backup.SaveHelperImpl;
+
+/**
+ * The main window for AMOEBA GUI.
+ * @author Hugo
+ *
+ */
+public class AmoebaMultiUIWindow extends AmasMultiUIWindow{
+
+	protected HashMap<String, AmakPlot> plots = new HashMap<>();
+	
+	/**
+	 * The main {@link VUI} for AMOEBA, by default it's the 2D representation of the contexts.
+	 */
+	public VUIMulti mainVUI;
+	
+	public Drawable point;
+	public Drawable rectangle;
+	public ToggleButton toggleRender;
+	public SchedulerToolbar schedulerToolbar;
+	public DimensionSelector dimensionSelector;
+	public Menu windowMenu;
+	
+	public AmoebaMultiUIWindow(String title, VUIMulti vui) {
+		super(title);
+		mainVUI = vui;
+	}
+	
+	public void initialize(AMOEBA amoeba) {
+		
+
+		mainVUI.setDefaultView(200, 0, 0);
+		addTabbedPanel("2D VUI", mainVUI.getPanel());
+		
+		// scheduler toolbar
+		schedulerToolbar = new SchedulerToolbar("AMOEBA", amoeba.getScheduler());
+		addToolbar(schedulerToolbar);	
+		
+		// plots
+		point = mainVUI.createAndAddPoint(0, 0);
+		point.setName("Cursor");
+		rectangle = mainVUI.createAndAddRectangle(10, 10, 10, 10);
+		rectangle.setName("Neighborhood");
+		rectangle.setColor(new Color(1, 1, 1, 0));
+		
+		plots.put("This loop NCS", new AmakPlot(this, "This loop NCS", ChartType.LINE, "Cycle", "Number of NCS"));
+		plots.put("All time NCS", new AmakPlot(this, "All time NCS", ChartType.LINE, "Cycle", "Number of NCS"));
+		plots.put("Number of agents", new AmakPlot(this, "Number of agents", ChartType.LINE, "Cycle", "Number of agents"));
+		plots.put("Errors", new AmakPlot(this, "Errors", ChartType.LINE, "Cycle", "Coefficients"));
+		plots.put("Distances to models", new AmakPlot(this, "Distances to models", ChartType.LINE, "Cycle", "Distances"));
+		plots.put("Global Mapping Criticality", new AmakPlot(this, "Global Mapping Criticality", ChartType.LINE, "Cycle", "Criticalities"));
+		plots.put("Time Execution", new AmakPlot(this, "Time Execution", ChartType.LINE, "Cycle", "Times"));
+		plots.put("Criticalities", new AmakPlot(this, "Criticalities", ChartType.LINE, "Cycle", "Criticalities"));
+		
+		// update render button
+		toggleRender = new ToggleButton("Allow Rendering");
+		toggleRender.setOnAction(evt -> {
+			amoeba.setRenderUpdate(toggleRender.isSelected()); 
+			if(amoeba.isRenderUpdate()) {
+				amoeba.updateAgentsVisualisation();
+				amoeba.nextCycleRunAllAgents();
+			}
+		});
+		toggleRender.setSelected(amoeba.isRenderUpdate());
+		addToolbar(toggleRender);
+		
+		// dimension selector
+		dimensionSelector = new DimensionSelector(amoeba.getPercepts(), new EventHandler<ActionEvent>() {
+			@Override
+			public void handle(ActionEvent event) {
+				amoeba.updateAgentsVisualisation();
+			}
+		});
+		RunLaterHelper.runLater(()->mainVUI.toolbar.getItems().add(dimensionSelector));
+		
+		// contextMenu "Request Here" on VUI
+		new ContextMenuVUI(amoeba, mainVUI); //the ContextMenu add itself to the VUI
+		
+		// manual save button
+		addToolbar(newManualSaveButton(amoeba));
+		
+		Slider slider = new Slider(0, 0.1, 0.1);
+		slider.setShowTickLabels(true);
+		slider.setShowTickMarks(true);
+		slider.valueProperty().addListener(new ChangeListener<Number>() {
+			@Override
+			public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
+				amoeba.getEnvironment().mappingErrorAllowed = newValue.doubleValue();
+			}
+		});
+		addToolbar(slider);
+	}
+	
+	
+	
+	/**
+	 * Get an existing {@link AmakPlot}. 
+	 * @param name name of the plot to get
+	 * @return an existing plot.
+	 * @see AmoebaMultiUIWindow#addPlot(String, AmakPlot)
+	 */
+	public AmakPlot getPlot(String name) {
+		return plots.get(name);
+	}
+	
+	/**
+	 * Add an {@link AmakPlot} to le map of plots. Allowing for easy access with {@code AmoebaWindow.instance().getPlot(name)}
+	 * @param name name of the plot to add
+	 * @param plot the plot to add
+	 * @see AmoebaMultiUIWindow#getPlot(String)
+	 */
+	public void addPlot(String name, AmakPlot plot) {
+		plots.put(name, plot);
+	}
+	
+	/**
+	 * Create a button 'Quick Save' button, when clicked create a manual save point using an amoeba's saver.
+	 * @param amoeba
+	 * @return
+	 * @see AMOEBA#saver
+	 * @see SaveHelperImpl#newManualSave(String)
+	 */
+	public Button newManualSaveButton(AMOEBA amoeba) {
+		Button button = new Button("Quick save");
+		button.setTooltip(new Tooltip("Create a new save point. You will be able to find it in 'Save Explorer' -> 'Manual Saves'"));
+		button.setOnAction(new EventHandler<ActionEvent>() {
+			@Override
+			public void handle(ActionEvent event) {
+				if(amoeba.saver != null) {
+					amoeba.saver.newManualSave("manualSaveButton");
+				} else {
+					Log.defaultLog.error("Main Window", "Cannot make a save point of an amoeba without saver");
+				}
+			}
+		});
+		return button;
+	}
+}
diff --git a/AMOEBAonAMAK/src/gui/ContextMenuVUI.java b/AMOEBAonAMAK/src/gui/ContextMenuVUI.java
index aad5e8bf8af3891878e442f441183af8bd3948f8..80ef51de949fa701b6045a4a830da0682e53c04f 100644
--- a/AMOEBAonAMAK/src/gui/ContextMenuVUI.java
+++ b/AMOEBAonAMAK/src/gui/ContextMenuVUI.java
@@ -6,6 +6,7 @@ import java.util.Optional;
 import agents.percept.Percept;
 import fr.irit.smac.amak.tools.Log;
 import fr.irit.smac.amak.ui.VUI;
+import fr.irit.smac.amak.ui.VUIMulti;
 import javafx.event.ActionEvent;
 import javafx.event.EventHandler;
 import javafx.scene.control.Button;
@@ -38,7 +39,7 @@ public class ContextMenuVUI extends ContextMenu {
 	 * @param amoeba the amoeba where {@link AMOEBA#request(HashMap)} and {@link AMOEBA#learn(HashMap)} will be executed.
 	 * @param vui the {@link VUI} hosting the {@link ContextMenuVUI}
 	 */
-	public ContextMenuVUI(AMOEBA amoeba, VUI vui) {
+	public ContextMenuVUI(AMOEBA amoeba, VUIMulti vui) {
 		// "request here" menu item
 		setupRequestHereMenuItem(amoeba, vui);
 		
@@ -56,7 +57,7 @@ public class ContextMenuVUI extends ContextMenu {
 		});	
 	}
 
-	private void setupRequestHereMenuItem(AMOEBA amoeba, VUI vui) {
+	private void setupRequestHereMenuItem(AMOEBA amoeba, VUIMulti vui) {
 		MenuItem reqHere = new MenuItem("Request Here");
 		reqHere.setOnAction(new EventHandler<ActionEvent>() {
 			@Override
@@ -78,7 +79,7 @@ public class ContextMenuVUI extends ContextMenu {
 	 * @param amoeba
 	 * @param vui
 	 */
-	private void reqTwoDimension(AMOEBA amoeba, VUI vui) {
+	private void reqTwoDimension(AMOEBA amoeba, VUIMulti vui) {
 		double x = vui.screenToWorldX(reqHereX);
 		double y = vui.screenToWorldY(reqHereY);
 		HashMap<String, Double> req = new HashMap<String, Double>();
@@ -95,7 +96,7 @@ public class ContextMenuVUI extends ContextMenu {
 	 * @param amoeba
 	 * @param vui
 	 */
-	private void reqNDimension(AMOEBA amoeba, VUI vui) {
+	private void reqNDimension(AMOEBA amoeba, VUIMulti vui) {
 		double x = vui.screenToWorldX(reqHereX);
 		double y = vui.screenToWorldY(reqHereY);
 		
@@ -143,7 +144,7 @@ public class ContextMenuVUI extends ContextMenu {
 		});
 	}
 	
-	private void setupLearnHereMenuItem(AMOEBA amoeba, VUI vui) {
+	private void setupLearnHereMenuItem(AMOEBA amoeba, VUIMulti vui) {
 		MenuItem learnHere = new MenuItem("Learn Here");
 		learnHere.setOnAction(new EventHandler<ActionEvent>() {
 			@Override
@@ -165,7 +166,7 @@ public class ContextMenuVUI extends ContextMenu {
 	 * @param amoeba
 	 * @param vui
 	 */
-	private void learnTwoDimension(AMOEBA amoeba, VUI vui) {
+	private void learnTwoDimension(AMOEBA amoeba, VUIMulti vui) {
 		double x = vui.screenToWorldX(reqHereX);
 		double y = vui.screenToWorldY(reqHereY);
 		HashMap<String, Double> req = new HashMap<String, Double>();
@@ -181,7 +182,7 @@ public class ContextMenuVUI extends ContextMenu {
 	 * @param amoeba
 	 * @param vui
 	 */
-	private void learnNDimebsion(AMOEBA amoeba, VUI vui) {
+	private void learnNDimebsion(AMOEBA amoeba, VUIMulti vui) {
 		double x = vui.screenToWorldX(reqHereX);
 		double y = vui.screenToWorldY(reqHereY);
 		
diff --git a/AMOEBAonAMAK/src/gui/ContextRendererFX.java b/AMOEBAonAMAK/src/gui/ContextRendererFX.java
index 75ddf4125607f21b3ef19ca0dcaaea006105be4d..cd4843863eeedd8f763e1103d6246ff541d681f2 100644
--- a/AMOEBAonAMAK/src/gui/ContextRendererFX.java
+++ b/AMOEBAonAMAK/src/gui/ContextRendererFX.java
@@ -2,6 +2,7 @@ package gui;
 
 import agents.context.Context;
 import agents.percept.Percept;
+import fr.irit.smac.amak.ui.VUIMulti;
 import fr.irit.smac.amak.ui.drawables.DrawableRectangle;
 import gui.utils.ContextColor;
 import javafx.scene.paint.Color;
@@ -64,8 +65,8 @@ public class ContextRendererFX extends RenderStrategy {
 	 * window.
 	 */
 	@Override
-	public void initialize() {
-		getDrawable().setName(context.toString()); // create the drawable if it does not exist
+	public void initialize(VUIMulti vui) {
+		getDrawable(vui).setName(context.toString()); // create the drawable if it does not exist
 
 	}
 
@@ -81,10 +82,10 @@ public class ContextRendererFX extends RenderStrategy {
 	 * 
 	 * @return
 	 */
-	public DrawableRectangle getDrawable() {
+	public DrawableRectangle getDrawable(VUIMulti vui) {
 		if (!context.isDying() && drawable == null) {
 			drawable = new DrawableContext(0, 0, 0, 0, context);
-			AmoebaWindow.instance().mainVUI.add(drawable);
+			vui.add(drawable);
 		}
 		return drawable;
 	}
diff --git a/AMOEBAonAMAK/src/gui/RenderStrategy.java b/AMOEBAonAMAK/src/gui/RenderStrategy.java
index d6bf4f7424a9b9166fb9d1ffe30ae5a34d740e99..7552c9518486d3050b687bb8f78114e2d274e774 100644
--- a/AMOEBAonAMAK/src/gui/RenderStrategy.java
+++ b/AMOEBAonAMAK/src/gui/RenderStrategy.java
@@ -1,5 +1,7 @@
 package gui;
 
+import fr.irit.smac.amak.ui.VUIMulti;
+
 /**
  * Strategy on how to render an object.
  * See {@link ContextRendererFX} for example on how to extends this class.
@@ -16,7 +18,8 @@ public abstract class RenderStrategy {
 	/**
 	 * Called when the rendered object need to be initialized
 	 */
-	abstract public void initialize();
+	//abstract public void initialize();
+	abstract public void initialize(VUIMulti vui);
 	
 	/**
 	 * Called to render the object.
diff --git a/AMOEBAonAMAK/src/kernel/AMOEBA.java b/AMOEBAonAMAK/src/kernel/AMOEBA.java
index dd2b1e7a6e324d66aac411429f0a847ac00ce42b..bf1b2c6299a6ea8f207ce0eac336f62eefc8d771 100644
--- a/AMOEBAonAMAK/src/kernel/AMOEBA.java
+++ b/AMOEBAonAMAK/src/kernel/AMOEBA.java
@@ -23,6 +23,8 @@ import fr.irit.smac.amak.Scheduling;
 import fr.irit.smac.amak.tools.Log;
 import fr.irit.smac.amak.tools.RunLaterHelper;
 import fr.irit.smac.amak.ui.AmakPlot;
+import fr.irit.smac.amak.ui.VUIMulti;
+import gui.AmoebaMultiUIWindow;
 import gui.AmoebaWindow;
 import gui.DimensionSelector;
 import kernel.backup.IBackupSystem;
@@ -38,6 +40,9 @@ import utils.PrintOnce;
  */
 public class AMOEBA extends Amas<World> implements IAMOEBA {
 	// -- Attributes
+	
+	
+	public VUIMulti vuiMulti;
 	/**
 	 * Utility to save, autosave, and load amoebas.
 	 */
@@ -48,6 +53,8 @@ public class AMOEBA extends Amas<World> implements IAMOEBA {
 	 */
 	public StudiedSystem studiedSystem;
 	
+	public AmoebaMultiUIWindow multiUIWindow;
+	
 	private Head head;
 	private TypeLocalModel localModel = TypeLocalModel.MILLER_REGRESSION;
 	private HashMap<String, Double> perceptions = new HashMap<String, Double>();
@@ -82,8 +89,9 @@ public class AMOEBA extends Amas<World> implements IAMOEBA {
 	 * @param studiedSystem
 	 *            the studied system
 	 */
-	public AMOEBA() {
-		super(new World(), Scheduling.HIDDEN);
+	public AMOEBA(AmoebaMultiUIWindow window, VUIMulti vui) {
+		super(window, vui, new World(), Scheduling.HIDDEN);
+		vuiMulti = vui;
 	}
 	
 	/**
@@ -91,8 +99,9 @@ public class AMOEBA extends Amas<World> implements IAMOEBA {
 	 * 
 	 * @param path path to the config file.
 	 */
-	public AMOEBA(String path, StudiedSystem studiedSystem) {
-		super(new World(), Scheduling.HIDDEN);
+	public AMOEBA(AmoebaMultiUIWindow window, VUIMulti vui, String path, StudiedSystem studiedSystem) {
+		super(window, vui, new World(), Scheduling.HIDDEN);
+		vuiMulti = vui;
 		this.studiedSystem = studiedSystem;
 		setRenderUpdate(true);
 		saver = new SaveHelperImpl(this);
@@ -112,23 +121,22 @@ public class AMOEBA extends Amas<World> implements IAMOEBA {
 	
 	@Override
 	protected void onRenderingInitialization() {
-		AmoebaWindow.instance().initialize(this);
+		((AmoebaMultiUIWindow) amasMultiUIWindow).initialize(this);
 	}
 
 	@Override
 	protected void onUpdateRender() {
 		// Update statistics
-		if(AmoebaWindow.isInstance()) {
-			AmoebaWindow window = AmoebaWindow.instance();
-
-			AmakPlot loopNCS = window.getPlot("This loop NCS");
-			AmakPlot allNCS = window.getPlot("All time NCS");
-			AmakPlot nbAgent = window.getPlot("Number of agents");
-			AmakPlot errors = window.getPlot("Errors");
-			AmakPlot distancesToModels = window.getPlot("Distances to models");
-			AmakPlot gloabalMappingCriticality = window.getPlot("Global Mapping Criticality");
-			AmakPlot timeExecution = window.getPlot("Time Execution");
-			AmakPlot criticalities = window.getPlot("Criticalities");
+		if(amasMultiUIWindow!=null) {
+
+			AmakPlot loopNCS = ((AmoebaMultiUIWindow)amasMultiUIWindow).getPlot("This loop NCS");
+			AmakPlot allNCS = ((AmoebaMultiUIWindow)amasMultiUIWindow).getPlot("All time NCS");
+			AmakPlot nbAgent = ((AmoebaMultiUIWindow)amasMultiUIWindow).getPlot("Number of agents");
+			AmakPlot errors = ((AmoebaMultiUIWindow)amasMultiUIWindow).getPlot("Errors");
+			AmakPlot distancesToModels = ((AmoebaMultiUIWindow)amasMultiUIWindow).getPlot("Distances to models");
+			AmakPlot gloabalMappingCriticality = ((AmoebaMultiUIWindow)amasMultiUIWindow).getPlot("Global Mapping Criticality");
+			AmakPlot timeExecution = ((AmoebaMultiUIWindow)amasMultiUIWindow).getPlot("Time Execution");
+			AmakPlot criticalities = ((AmoebaMultiUIWindow)amasMultiUIWindow).getPlot("Criticalities");
 			
 			
 			boolean notify = isRenderUpdate();
@@ -174,7 +182,7 @@ public class AMOEBA extends Amas<World> implements IAMOEBA {
 		}
 		
 		if (isRenderUpdate()) {
-			AmoebaWindow.instance().mainVUI.updateCanvas();
+			((AmoebaMultiUIWindow)amasMultiUIWindow).mainVUI.updateCanvas();
 			updateAgentsVisualisation();
 			RunLaterHelper.runLater(() -> {resetCycleWithoutRender();});
 		}
@@ -454,7 +462,7 @@ public class AMOEBA extends Amas<World> implements IAMOEBA {
 	 */
 	public void allowGraphicalScheduler(boolean allow) {
 		if (!Configuration.commandLineMode) {
-			AmoebaWindow.instance().schedulerToolbar.setDisable(!allow);
+			((AmoebaMultiUIWindow)amasMultiUIWindow).schedulerToolbar.setDisable(!allow);
 		}
 	}
 
@@ -476,7 +484,7 @@ public class AMOEBA extends Amas<World> implements IAMOEBA {
 		super.addPendingAgents();
 		nextCycleRunAllAgents();
 		if(!Configuration.commandLineMode) {
-			AmoebaWindow.instance().dimensionSelector.update(getPercepts());
+			((AmoebaMultiUIWindow)amasMultiUIWindow).dimensionSelector.update(getPercepts());
 			updateAgentsVisualisation();
 		}
 	}
@@ -504,7 +512,7 @@ public class AMOEBA extends Amas<World> implements IAMOEBA {
 	public void setRenderUpdate(boolean renderUpdate) {
 		if (!Configuration.commandLineMode) {
 			this.renderUpdate = renderUpdate;
-			AmoebaWindow.instance().toggleRender.setSelected(renderUpdate);
+			((AmoebaMultiUIWindow)amasMultiUIWindow).toggleRender.setSelected(renderUpdate);
 			if(renderUpdate == true)
 				nextCycleRunAllAgents();
 		}
@@ -595,13 +603,13 @@ public class AMOEBA extends Amas<World> implements IAMOEBA {
 		for(Agent<? extends Amas<World>, World> a : getAgents()) {
 			a.onUpdateRender();
 		}
-		AmoebaWindow.instance().point.move(AmoebaWindow.instance().dimensionSelector.d1().getValue(), AmoebaWindow.instance().dimensionSelector.d2().getValue());
-		AmoebaWindow.instance().rectangle.setHeight(2*getEnvironment().getContextCreationNeighborhood(null, AmoebaWindow.instance().dimensionSelector.d2()));
-		AmoebaWindow.instance().rectangle.setWidth(2*getEnvironment().getContextCreationNeighborhood(null, AmoebaWindow.instance().dimensionSelector.d1()));
-		AmoebaWindow.instance().rectangle.move(AmoebaWindow.instance().dimensionSelector.d1().getValue() - getEnvironment().getContextCreationNeighborhood(null, AmoebaWindow.instance().dimensionSelector.d1()), AmoebaWindow.instance().dimensionSelector.d2().getValue() - getEnvironment().getContextCreationNeighborhood(null, AmoebaWindow.instance().dimensionSelector.d2()));
-		AmoebaWindow.instance().mainVUI.updateCanvas();
-		AmoebaWindow.instance().point.toFront();
-		AmoebaWindow.instance().point.setInfo(getCursorInfo());
+		((AmoebaMultiUIWindow)amasMultiUIWindow).point.move(((AmoebaMultiUIWindow)amasMultiUIWindow).dimensionSelector.d1().getValue(), ((AmoebaMultiUIWindow)amasMultiUIWindow).dimensionSelector.d2().getValue());
+		((AmoebaMultiUIWindow)amasMultiUIWindow).rectangle.setHeight(2*getEnvironment().getContextCreationNeighborhood(null, ((AmoebaMultiUIWindow)amasMultiUIWindow).dimensionSelector.d2()));
+		((AmoebaMultiUIWindow)amasMultiUIWindow).rectangle.setWidth(2*getEnvironment().getContextCreationNeighborhood(null, ((AmoebaMultiUIWindow)amasMultiUIWindow).dimensionSelector.d1()));
+		((AmoebaMultiUIWindow)amasMultiUIWindow).rectangle.move(((AmoebaMultiUIWindow)amasMultiUIWindow).dimensionSelector.d1().getValue() - getEnvironment().getContextCreationNeighborhood(null, ((AmoebaMultiUIWindow)amasMultiUIWindow).dimensionSelector.d1()), ((AmoebaMultiUIWindow)amasMultiUIWindow).dimensionSelector.d2().getValue() - getEnvironment().getContextCreationNeighborhood(null, ((AmoebaMultiUIWindow)amasMultiUIWindow).dimensionSelector.d2()));
+		((AmoebaMultiUIWindow)amasMultiUIWindow).mainVUI.updateCanvas();
+		((AmoebaMultiUIWindow)amasMultiUIWindow).point.toFront();
+		((AmoebaMultiUIWindow)amasMultiUIWindow).point.setInfo(getCursorInfo());
 	}
 	
 	/**
@@ -609,7 +617,7 @@ public class AMOEBA extends Amas<World> implements IAMOEBA {
 	 * @return
 	 */
 	public DimensionSelector getDimensionSelector() {
-		return AmoebaWindow.instance().dimensionSelector;
+		return ((AmoebaMultiUIWindow)amasMultiUIWindow).dimensionSelector;
 	}
 	
 	/**
diff --git a/AMOEBAonAMAK/src/kernel/backup/SaveHelperImpl.java b/AMOEBAonAMAK/src/kernel/backup/SaveHelperImpl.java
index b2258c51d799c99816a3b9d049b84901f5374c1f..152a7433223b7797e72c658192964cb5cbf59d3e 100644
--- a/AMOEBAonAMAK/src/kernel/backup/SaveHelperImpl.java
+++ b/AMOEBAonAMAK/src/kernel/backup/SaveHelperImpl.java
@@ -11,6 +11,7 @@ import java.util.List;
 
 import fr.irit.smac.amak.Configuration;
 import fr.irit.smac.amak.ui.MainWindow;
+import gui.AmoebaMultiUIWindow;
 import gui.AmoebaWindow;
 import gui.saveExplorer.SaveExplorer;
 import javafx.event.ActionEvent;
@@ -33,6 +34,9 @@ public class SaveHelperImpl implements ISaveHelper{
 	public static final String autosaveDirName = "autosave";
 	public static final String manualsaveDirName = "manual";
 
+	
+	public AmoebaMultiUIWindow amoebaMultiUIWindow;
+	
 	/**
 	 * The backup system used by the SaveHelper.
 	 */
@@ -116,6 +120,51 @@ public class SaveHelperImpl implements ISaveHelper{
 			setupGraphicalTool();
 		}
 	}
+	
+	public SaveHelperImpl(AMOEBA amoeba, AmoebaMultiUIWindow window) {
+		amoebaMultiUIWindow = window;
+		autoSave = !Configuration.commandLineMode;
+		this.amoeba = amoeba;
+		backupSystem = new BackupSystem(amoeba);
+		String dirName = amoeba.toString() + "_" + System.currentTimeMillis();
+		dir = Paths.get(savesRoot, dirName);
+		if (autoSave) {
+			dirAuto = Paths.get(dir.toString(), autosaveDirName);
+			try {
+				Files.createDirectories(dirAuto);
+			} catch (IOException e) {
+				e.printStackTrace();
+				System.err.println("Cannot create auto save directory. Auto saving is disabled.");
+				dirAuto = null;
+				autoSave = false;
+			}
+		}
+		dirManual = Paths.get(dir.toString(), manualsaveDirName);
+		try {
+			Files.createDirectories(dirManual);
+		} catch (IOException e) {
+			e.printStackTrace();
+			System.err.println("Cannot create manual save directory.");
+			dirManual = null;
+		}
+
+		// add graphical element if relevant
+		if (AmoebaWindow.isInstance()) {
+			SaveExplorer se = new SaveExplorer(amoeba);
+			AmoebaWindow.addTabbedPanel("Save Explorer", se);
+			AmoebaWindow.addOnCloseAction(()-> {
+				if(deleteFolderOnClose) {
+					try {
+						DeleteDirectory.deleteDirectoryRecursion(dir);
+					} catch (IOException e) {
+						e.printStackTrace();
+						System.err.println("Failed to delete saves files on close.");
+					}
+				}
+			});
+			setupGraphicalTool();
+		}
+	}
 
 	@Override
 	public void load(String path) {
@@ -187,7 +236,7 @@ public class SaveHelperImpl implements ISaveHelper{
 	 * Add save/load options in the main window.
 	 */
 	private void setupGraphicalTool() {
-		MainWindow mw = AmoebaWindow.instance();
+		AmoebaMultiUIWindow mw = amoebaMultiUIWindow;
 		// TODO remove if they exist items Save and Load in menu Option.
 		FileChooser fileChooser = new FileChooser();
 		fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("XML", "*.xml"),
@@ -198,7 +247,7 @@ public class SaveHelperImpl implements ISaveHelper{
 			@Override
 			public void handle(ActionEvent event) {
 				amoeba.getScheduler().stop();
-				File file = fileChooser.showOpenDialog(mw.stage);
+				File file = fileChooser.showOpenDialog(mw);
 				if (file != null)
 					backupSystem.load(file);
 			}
@@ -210,7 +259,7 @@ public class SaveHelperImpl implements ISaveHelper{
 			@Override
 			public void handle(ActionEvent event) {
 				amoeba.getScheduler().stop();
-				File file = fileChooser.showSaveDialog(mw.stage);
+				File file = fileChooser.showSaveDialog(mw);
 				if (file != null)
 					backupSystem.save(file);
 			}