diff --git a/AMAKFX/src/fr/irit/smac/amak/Agent.java b/AMAKFX/src/fr/irit/smac/amak/Agent.java
index 9685e065123e3ae277e7482e37e39789ce88c9f1..d67c8b8f047833affa05fdc10fcb3ba07107424d 100644
--- a/AMAKFX/src/fr/irit/smac/amak/Agent.java
+++ b/AMAKFX/src/fr/irit/smac/amak/Agent.java
@@ -8,6 +8,8 @@ import java.util.Map.Entry;
 
 import fr.irit.smac.amak.Amas.ExecutionPolicy;
 import fr.irit.smac.amak.tools.Log;
+import fr.irit.smac.amak.ui.AmasWindow;
+import fr.irit.smac.amak.ui.MainWindow;
 
 /**
  * This class must be overridden by all agents
@@ -20,6 +22,10 @@ import fr.irit.smac.amak.tools.Log;
  *            The kind of Environment the agent AND the Amas refer to
  */
 public abstract class Agent<A extends Amas<E>, E extends Environment> implements Runnable {
+	
+	public AmasWindow amasWindow;
+	
+	
 	/**
 	 * Neighborhood of the agent (must refer to the same couple amas, environment
 	 */
@@ -103,7 +109,8 @@ public abstract class Agent<A extends Amas<E>, E extends Environment> implements
 	 * @param params
 	 *            The params to initialize the agent
 	 */
-	public Agent(A amas, Object... params) {
+	public Agent(AmasWindow window, A amas, Object... params) {
+		this.amasWindow = window;
 		this.id = uniqueIndex++;
 		this.params = params;
 		this.amas = amas;
diff --git a/AMAKFX/src/fr/irit/smac/amak/Amas.java b/AMAKFX/src/fr/irit/smac/amak/Amas.java
index a73d0e5107ef13fc638c7e17037858d93ae44c5d..6dcfd7c9c1f5c5d41801c760d1ddef8080c870e8 100644
--- a/AMAKFX/src/fr/irit/smac/amak/Amas.java
+++ b/AMAKFX/src/fr/irit/smac/amak/Amas.java
@@ -13,6 +13,7 @@ import java.util.stream.Collectors;
 
 import fr.irit.smac.amak.tools.Log;
 import fr.irit.smac.amak.tools.RunLaterHelper;
+import fr.irit.smac.amak.ui.AmasWindow;
 import fr.irit.smac.amak.ui.MainWindow;
 import fr.irit.smac.amak.ui.SchedulerToolbar;
 import fr.irit.smac.amak.ui.VUI;
@@ -26,6 +27,9 @@ import fr.irit.smac.amak.ui.VUI;
  *            The environment of the MAS
  */
 public class Amas<E extends Environment> implements Schedulable {
+	
+	public AmasWindow amasWindow;
+	
 	/**
 	 * List of agents present in the system
 	 */
@@ -129,17 +133,20 @@ public class Amas<E extends Environment> implements Schedulable {
 	 * @param params
 	 *            The params to initialize the amas
 	 */
-	public Amas(E environment, Scheduling scheduling, Object... params) {
+	public Amas(AmasWindow window, E environment, Scheduling scheduling, Object... params) {
+		amasWindow = window;
 		executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(Configuration.allowedSimultaneousAgentsExecution);
 		if (scheduling == Scheduling.DEFAULT) {
-			MainWindow.instance();
-			this.scheduler = Scheduler.getDefaultScheduler();
+//			System.out.println("Amas");
+//			mainWindow.instance();
+			this.scheduler = new Scheduler(amasWindow);
+			this.scheduler = this.scheduler.getDefaultScheduler(amasWindow);
 			this.scheduler.add(this);
 		} else {
-			this.scheduler = new Scheduler(this);
+			this.scheduler = new Scheduler(amasWindow, this);
 			if (scheduling == Scheduling.UI && !Configuration.commandLineMode) {
-				MainWindow.instance();
-				MainWindow.addToolbar(new SchedulerToolbar("Amas #" + id, getScheduler()));
+				//amasWindow.instance();
+				amasWindow.addToolbar(new SchedulerToolbar("Amas #" + id, getScheduler()));
 			}
 		}
 		this.scheduler.lock();
@@ -371,7 +378,7 @@ public class Amas<E extends Environment> implements Schedulable {
 	 * {@link Amas#onRenderingInitialization}
 	 */
 	protected void onUpdateRender() {
-		VUI.get().updateCanvas();
+		VUI.get(amasWindow).updateCanvas();
 	}
 
 	/**
diff --git a/AMAKFX/src/fr/irit/smac/amak/CommunicatingAgent.java b/AMAKFX/src/fr/irit/smac/amak/CommunicatingAgent.java
index b0f2b5a38a9fc6931b91e2bc053975631760f369..bac17a3d8edd1b6adfd7cdda18e5dda21b57b823 100644
--- a/AMAKFX/src/fr/irit/smac/amak/CommunicatingAgent.java
+++ b/AMAKFX/src/fr/irit/smac/amak/CommunicatingAgent.java
@@ -84,7 +84,7 @@ public abstract class CommunicatingAgent<A extends Amas<E>, E extends Environmen
 	 *            The strategy of messaging reader.
 	 */
 	public CommunicatingAgent(A amas, IMessagingReader msgReader, Object... params) {
-		super(amas, params);
+		super(null,amas, params);
 		// build the address...
 		final String randomUUID = getRawID(params);
 		IAmakAddress address = messagingService.getOrCreateAmakAddress(randomUUID);
diff --git a/AMAKFX/src/fr/irit/smac/amak/Environment.java b/AMAKFX/src/fr/irit/smac/amak/Environment.java
index 68433e456f0c7b95e24b646a47e8806d67dd4666..1461349c6c15379f9801f57ad8755d89e7135041 100644
--- a/AMAKFX/src/fr/irit/smac/amak/Environment.java
+++ b/AMAKFX/src/fr/irit/smac/amak/Environment.java
@@ -1,145 +1,150 @@
-package fr.irit.smac.amak;
-
-import java.util.Random;
-
-import fr.irit.smac.amak.ui.MainWindow;
-import fr.irit.smac.amak.ui.SchedulerToolbar;
-
-/**
- * This class must be overridden by environments
- * 
- * @author Alexandre Perles
- *
- */
-public abstract class Environment implements Schedulable {
-
-	/**
-	 * Unique index to give unique id to each environment
-	 */
-	private static int uniqueIndex;
-
-	/**
-	 * The id of the environment
-	 */
-	private final int id = uniqueIndex++;
-
-	/**
-	 * The parameters that are passed to {@link Environment#onInitialization()}
-	 */
-	protected Object[] params;
-	/**
-	 * Random object common to the amas
-	 */
-	private Random random = new Random();
-	/**
-	 * The scheduler of the environment
-	 */
-	private Scheduler scheduler;
-
-	/**
-	 * Constructor
-	 * 
-	 * @param _scheduling
-	 *            The scheduling of the environment
-	 * @param params
-	 *            The parameters to initialize the environment
-	 */
-	public Environment(Scheduling _scheduling, Object... params) {
-		if (_scheduling == Scheduling.DEFAULT) {
-			this.scheduler = Scheduler.getDefaultScheduler();
-			this.scheduler.add(this);
-		} else {
-			this.scheduler = new Scheduler(this);
-			if (_scheduling == Scheduling.UI && !Configuration.commandLineMode)
-				MainWindow.addToolbar(new SchedulerToolbar("Environment #" + id, getScheduler()));
-		}
-		this.scheduler.lock();
-		this.params = params;
-		onInitialization();
-		onInitialEntitiesCreation();
-		if (!Configuration.commandLineMode)
-			onRenderingInitialization();
-		this.scheduler.unlock();
-	}
-
-	/**
-	 * Override this method is you wish to render environment. For example, you can
-	 * use this method to create a VUI drawable object.
-	 */
-	private void onRenderingInitialization() {
-	}
-
-	/**
-	 * Getter for the scheduler
-	 * 
-	 * @return the scheduler
-	 */
-	public Scheduler getScheduler() {
-		return scheduler;
-	}
-
-	/**
-	 * Set the seed for the common random object. This method should be called at
-	 * the very beginning of the initialization process
-	 * 
-	 * @param _seed
-	 *            The seed to initialize the random object
-	 */
-	public void setSeed(long _seed) {
-		random = new Random(_seed);
-	}
-
-	/**
-	 * This method is called during the initialization process of the environment
-	 */
-	public void onInitialization() {
-	}
-
-	/**
-	 * This method is called after the initialization process of the environment to
-	 * create entities
-	 */
-	public void onInitialEntitiesCreation() {
-	}
-
-	/**
-	 * This method is called at each cycle of the environment
-	 */
-	public void onCycle() {
-	}
-
-	@Override
-	public boolean stopCondition() {
-		return false;
-	}
-
-	@Override
-	public final void cycle() {
-		onCycle();
-		if (!Configuration.commandLineMode)
-			onUpdateRender();
-	}
-
-	/**
-	 * Override this method to update rendering related to the environment
-	 */
-	protected void onUpdateRender() {
-	}
-
-	/**
-	 * Getter for the random object
-	 * 
-	 * @return the random object
-	 */
-	public Random getRandom() {
-		return random;
-	}
-
-	@Override
-	public void onSchedulingStarts() {
-	}
-
-	@Override
-	public void onSchedulingStops() {
-	}
-}
+package fr.irit.smac.amak;
+
+import java.util.Random;
+
+import fr.irit.smac.amak.ui.AmasWindow;
+import fr.irit.smac.amak.ui.MainWindow;
+import fr.irit.smac.amak.ui.SchedulerToolbar;
+
+/**
+ * This class must be overridden by environments
+ * 
+ * @author Alexandre Perles
+ *
+ */
+public abstract class Environment implements Schedulable {
+
+	public AmasWindow amasWindow;
+	
+	/**
+	 * Unique index to give unique id to each environment
+	 */
+	private static int uniqueIndex;
+
+	/**
+	 * The id of the environment
+	 */
+	private final int id = uniqueIndex++;
+
+	/**
+	 * The parameters that are passed to {@link Environment#onInitialization()}
+	 */
+	protected Object[] params;
+	/**
+	 * Random object common to the amas
+	 */
+	private Random random = new Random();
+	/**
+	 * The scheduler of the environment
+	 */
+	private Scheduler scheduler;
+
+	/**
+	 * Constructor
+	 * 
+	 * @param _scheduling
+	 *            The scheduling of the environment
+	 * @param params
+	 *            The parameters to initialize the environment
+	 */
+	public Environment(AmasWindow window, Scheduling _scheduling, Object... params) {
+		amasWindow = window;
+		if (_scheduling == Scheduling.DEFAULT) {
+			this.scheduler = new Scheduler(amasWindow);
+			this.scheduler = this.scheduler.getDefaultScheduler(amasWindow);
+			this.scheduler.add(this);
+		} else {
+			this.scheduler = new Scheduler(amasWindow,this);
+			if (_scheduling == Scheduling.UI && !Configuration.commandLineMode)
+				amasWindow.addToolbar(new SchedulerToolbar("Environment #" + id, getScheduler()));
+		}
+		this.scheduler.lock();
+		this.params = params;
+		onInitialization();
+		onInitialEntitiesCreation();
+		if (!Configuration.commandLineMode)
+			onRenderingInitialization();
+		this.scheduler.unlock();
+	}
+
+	/**
+	 * Override this method is you wish to render environment. For example, you can
+	 * use this method to create a VUI drawable object.
+	 */
+	private void onRenderingInitialization() {
+	}
+
+	/**
+	 * Getter for the scheduler
+	 * 
+	 * @return the scheduler
+	 */
+	public Scheduler getScheduler() {
+		return scheduler;
+	}
+
+	/**
+	 * Set the seed for the common random object. This method should be called at
+	 * the very beginning of the initialization process
+	 * 
+	 * @param _seed
+	 *            The seed to initialize the random object
+	 */
+	public void setSeed(long _seed) {
+		random = new Random(_seed);
+	}
+
+	/**
+	 * This method is called during the initialization process of the environment
+	 */
+	public void onInitialization() {
+	}
+
+	/**
+	 * This method is called after the initialization process of the environment to
+	 * create entities
+	 */
+	public void onInitialEntitiesCreation() {
+	}
+
+	/**
+	 * This method is called at each cycle of the environment
+	 */
+	public void onCycle() {
+	}
+
+	@Override
+	public boolean stopCondition() {
+		return false;
+	}
+
+	@Override
+	public final void cycle() {
+		onCycle();
+		if (!Configuration.commandLineMode)
+			onUpdateRender();
+	}
+
+	/**
+	 * Override this method to update rendering related to the environment
+	 */
+	protected void onUpdateRender() {
+	}
+
+	/**
+	 * Getter for the random object
+	 * 
+	 * @return the random object
+	 */
+	public Random getRandom() {
+		return random;
+	}
+
+	@Override
+	public void onSchedulingStarts() {
+	}
+
+	@Override
+	public void onSchedulingStops() {
+	}
+}
diff --git a/AMAKFX/src/fr/irit/smac/amak/Scheduler.java b/AMAKFX/src/fr/irit/smac/amak/Scheduler.java
index bffeeb2ce6a8d7e7a2422d165b41817e2e8b44c6..09dc4808599cc137369be4fdd99bf053027efbc6 100644
--- a/AMAKFX/src/fr/irit/smac/amak/Scheduler.java
+++ b/AMAKFX/src/fr/irit/smac/amak/Scheduler.java
@@ -1,341 +1,349 @@
-package fr.irit.smac.amak;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.ConcurrentModificationException;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Queue;
-import java.util.Set;
-import java.util.concurrent.locks.ReentrantLock;
-import java.util.function.Consumer;
-
-import fr.irit.smac.amak.ui.MainWindow;
-import fr.irit.smac.amak.ui.SchedulerToolbar;
-
-/**
- * A scheduler associated to a MAS
- * 
- * @author Alexandre Perles
- *
- */
-public class Scheduler implements Runnable, Serializable {
-	/**
-	 * Unique ID meant to handle serialization correctly
-	 */
-	private static final long serialVersionUID = -4765899565369100376L;
-	/**
-	 * The schedulables object handled by the scheduler
-	 */
-	private final Set<Schedulable> schedulables = new LinkedHashSet<>();
-	/**
-	 * The state of the scheduler {@link State}
-	 */
-	private State state;
-	/**
-	 * The sleep time in ms between each cycle
-	 */
-	private int sleep;
-	/**
-	 * A lock to protect the state
-	 */
-	private final ReentrantLock stateLock = new ReentrantLock();
-	/**
-	 * Method that is called when the scheduler stops
-	 */
-	private Consumer<Scheduler> onStop;
-	/**
-	 * The methods called when the speed is changed. Useful to change the value of
-	 * the GUI slider of {@link SchedulerToolbar}
-	 */
-	private List<Consumer<Scheduler>> onChange = new ArrayList<>();
-	/**
-	 * The idea is to prevent scheduler from launching if the schedulables are not
-	 * yet fully ready
-	 */
-	private int locked = 0;
-	/**
-	 * The default scheduler
-	 */
-	private static Scheduler defaultScheduler;
-	/**
-	 * The schedulables that must be added
-	 */
-	private Queue<Schedulable> pendingAdditionSchedulables = new LinkedList<>();
-	/**
-	 * The schedulables that must be removed
-	 */
-	private Queue<Schedulable> pendingRemovalSchedulables = new LinkedList<>();
-
-	/**
-	 * State of the scheduler
-	 *
-	 */
-	public enum State {
-		/**
-		 * The scheduler is running
-		 */
-		RUNNING,
-		/**
-		 * The scheduler is paused
-		 */
-		IDLE,
-		/**
-		 * The scheduler is expected to stop at the end at the current cycle
-		 */
-		PENDING_STOP
-
-	}
-
-	/**
-	 * Constructor which set the initial state and auto start if requested
-	 * 
-	 * @param _schedulables
-	 *            the corresponding schedulables
-	 */
-	public Scheduler(Schedulable... _schedulables) {
-
-		for (Schedulable schedulable : _schedulables) {
-			this.add(schedulable);
-		}
-		this.state = State.IDLE;
-	}
-
-	/**
-	 * Create or return the default scheduler
-	 * 
-	 * @return The default scheduler
-	 */
-	public static Scheduler getDefaultScheduler() {
-		if (defaultScheduler == null) {
-			defaultScheduler = new Scheduler();
-			if (!Configuration.commandLineMode) {
-				MainWindow.instance();
-				SchedulerToolbar st = new SchedulerToolbar("Default", defaultScheduler);
-				MainWindow.addToolbar(st);
-			}
-		}
-		return defaultScheduler;
-	}
-
-	/**
-	 * Set the delay between two cycles and launch the scheduler if it is not
-	 * running
-	 * 
-	 * @param i
-	 *            the delay between two cycles
-	 */
-	public void startWithSleep(int i) {
-		if (locked > 0) {
-
-			synchronized (onChange) {
-				onChange.forEach(c -> c.accept(this));
-			}
-			return;
-		}
-		setSleep(i);
-		stateLock.lock();
-		switch (state) {
-		case IDLE:
-			state = State.RUNNING;
-			new Thread(this).start();
-			break;
-		default:
-			break;
-		}
-		stateLock.unlock();
-		synchronized (onChange) {
-			onChange.forEach(c -> c.accept(this));
-		}
-	}
-
-	/**
-	 * Start (or continue) with no delay between cycles
-	 */
-	public void start() {
-		startWithSleep(Schedulable.DEFAULT_SLEEP);
-	}
-
-	/**
-	 * Execute one cycle
-	 */
-	public void step() {
-		if (locked > 0) {
-			synchronized (onChange) {
-				onChange.forEach(c -> c.accept(this));
-			}
-			return;
-		}
-		this.setSleep(0);
-		stateLock.lock();
-		switch (state) {
-		case IDLE:
-			state = State.PENDING_STOP;
-			new Thread(this).start();
-			break;
-		default:
-			break;
-
-		}
-		stateLock.unlock();
-		synchronized (onChange) {
-			onChange.forEach(c -> c.accept(this));
-		}
-	}
-
-	/**
-	 * Stop the scheduler if it is running
-	 */
-	public void stop() {
-		stateLock.lock();
-		switch (state) {
-		case RUNNING:
-			state = State.PENDING_STOP;
-			break;
-		default:
-			break;
-
-		}
-		stateLock.unlock();
-		synchronized (onChange) {
-			onChange.forEach(c -> c.accept(this));
-		}
-	}
-
-	/**
-	 * Threaded run method
-	 */
-	@Override
-	public void run() {
-		treatPendingSchedulables();
-		for (Schedulable schedulable : schedulables) {
-			schedulable.onSchedulingStarts();
-		}
-		boolean mustStop;
-		do {
-			for (Schedulable schedulable : schedulables) {
-				schedulable.cycle();
-			}
-			if (getSleep() != 0) {
-				try {
-					Thread.sleep(getSleep());
-				} catch (final InterruptedException e) {
-					e.printStackTrace();
-				}
-			}
-			mustStop = false;
-			for (Schedulable schedulable : schedulables) {
-				mustStop |= schedulable.stopCondition();
-			}
-		} while (state == State.RUNNING && !mustStop);
-		stateLock.lock();
-		state = State.IDLE;
-		stateLock.unlock();
-
-		for (Schedulable schedulable : schedulables) {
-			schedulable.onSchedulingStops();
-		}
-		treatPendingSchedulables();
-		if (onStop != null)
-			onStop.accept(this);
-	}
-
-	/**
-	 * Effectively Add or Remove the schedulables that were added or removed during
-	 * a cycle to avoid {@link ConcurrentModificationException}
-	 */
-	private void treatPendingSchedulables() {
-		while (!pendingAdditionSchedulables.isEmpty())
-			schedulables.add(pendingAdditionSchedulables.poll());
-		while (!pendingRemovalSchedulables.isEmpty())
-			schedulables.remove(pendingRemovalSchedulables.poll());
-
-	}
-
-	/**
-	 * Set the method that must be executed when the system is stopped
-	 * 
-	 * @param _onStop
-	 *            Consumer method
-	 */
-	public final void setOnStop(Consumer<Scheduler> _onStop) {
-		this.onStop = _onStop;
-	}
-
-	/**
-	 * Add a method that must be executed when the scheduler speed is changed
-	 * 
-	 * @param _onChange
-	 *            Consumer method
-	 */
-	public final void addOnChange(Consumer<Scheduler> _onChange) {
-		synchronized (onChange) {
-			this.onChange.add(_onChange);
-		}
-	}
-
-	/**
-	 * Is the scheduler running ?
-	 * 
-	 * @return true if the scheduler is running
-	 */
-	public boolean isRunning() {
-		return state == State.RUNNING;
-	}
-
-	/**
-	 * Getter for the sleep time
-	 * 
-	 * @return the sleep time
-	 */
-
-	public int getSleep() {
-		return sleep;
-	}
-
-	/**
-	 * Setter for the sleep time
-	 * 
-	 * @param sleep
-	 *            The time between each cycle
-	 */
-	public void setSleep(int sleep) {
-		this.sleep = sleep;
-	}
-
-	/**
-	 * Plan to add a schedulable
-	 * 
-	 * @param _schedulable
-	 *            the schedulable to add
-	 */
-	public void add(Schedulable _schedulable) {
-		this.pendingAdditionSchedulables.add(_schedulable);
-	}
-
-	/**
-	 * Plan to remove a schedulable
-	 * 
-	 * @param _schedulable
-	 *            the schedulable to remove
-	 */
-	public void remove(Schedulable _schedulable) {
-		this.pendingRemovalSchedulables.add(_schedulable);
-	}
-
-	/**
-	 * Soft lock the scheduler to avoid a too early running
-	 */
-	public void lock() {
-		locked++;
-	}
-
-	/**
-	 * Soft unlock the scheduler to avoid a too early running
-	 */
-	public void unlock() {
-		locked--;
-	}
-
-}
+package fr.irit.smac.amak;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.ConcurrentModificationException;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+import java.util.Set;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.function.Consumer;
+
+import fr.irit.smac.amak.ui.AmasWindow;
+import fr.irit.smac.amak.ui.MainWindow;
+import fr.irit.smac.amak.ui.SchedulerToolbar;
+
+/**
+ * A scheduler associated to a MAS
+ * 
+ * @author Alexandre Perles
+ *
+ */
+public class Scheduler implements Runnable, Serializable {
+	
+	public AmasWindow amasWindow;
+	
+	/**
+	 * Unique ID meant to handle serialization correctly
+	 */
+	private static final long serialVersionUID = -4765899565369100376L;
+	/**
+	 * The schedulables object handled by the scheduler
+	 */
+	private final Set<Schedulable> schedulables = new LinkedHashSet<>();
+	/**
+	 * The state of the scheduler {@link State}
+	 */
+	private State state;
+	/**
+	 * The sleep time in ms between each cycle
+	 */
+	private int sleep;
+	/**
+	 * A lock to protect the state
+	 */
+	private final ReentrantLock stateLock = new ReentrantLock();
+	/**
+	 * Method that is called when the scheduler stops
+	 */
+	private Consumer<Scheduler> onStop;
+	/**
+	 * The methods called when the speed is changed. Useful to change the value of
+	 * the GUI slider of {@link SchedulerToolbar}
+	 */
+	private List<Consumer<Scheduler>> onChange = new ArrayList<>();
+	/**
+	 * The idea is to prevent scheduler from launching if the schedulables are not
+	 * yet fully ready
+	 */
+	private int locked = 0;
+	/**
+	 * The default scheduler
+	 */
+	private static Scheduler defaultScheduler;
+	/**
+	 * The schedulables that must be added
+	 */
+	private Queue<Schedulable> pendingAdditionSchedulables = new LinkedList<>();
+	/**
+	 * The schedulables that must be removed
+	 */
+	private Queue<Schedulable> pendingRemovalSchedulables = new LinkedList<>();
+
+	/**
+	 * State of the scheduler
+	 *
+	 */
+	public enum State {
+		/**
+		 * The scheduler is running
+		 */
+		RUNNING,
+		/**
+		 * The scheduler is paused
+		 */
+		IDLE,
+		/**
+		 * The scheduler is expected to stop at the end at the current cycle
+		 */
+		PENDING_STOP
+
+	}
+
+	/**
+	 * Constructor which set the initial state and auto start if requested
+	 * 
+	 * @param _schedulables
+	 *            the corresponding schedulables
+	 */
+	public Scheduler(AmasWindow window, Schedulable... _schedulables) {
+		amasWindow = window;
+		
+		
+		for (Schedulable schedulable : _schedulables) {
+			this.add(schedulable);
+		}
+		this.state = State.IDLE;
+	}
+
+	/**
+	 * Create or return the default scheduler
+	 * 
+	 * @return The default scheduler
+	 */
+	public Scheduler getDefaultScheduler(AmasWindow window) {
+		amasWindow = window;
+		if (defaultScheduler == null) {
+			defaultScheduler = new Scheduler(amasWindow);
+			if (!Configuration.commandLineMode) {
+//				System.out.println("getDefaultScheduler");
+//				mainWindow.instance();
+				SchedulerToolbar st = new SchedulerToolbar("Default", defaultScheduler);
+				amasWindow.addToolbar(st);
+			}
+		}
+		return defaultScheduler;
+	}
+
+	/**
+	 * Set the delay between two cycles and launch the scheduler if it is not
+	 * running
+	 * 
+	 * @param i
+	 *            the delay between two cycles
+	 */
+	public void startWithSleep(int i) {
+		if (locked > 0) {
+
+			synchronized (onChange) {
+				onChange.forEach(c -> c.accept(this));
+			}
+			return;
+		}
+		setSleep(i);
+		stateLock.lock();
+		switch (state) {
+		case IDLE:
+			state = State.RUNNING;
+			new Thread(this).start();
+			break;
+		default:
+			break;
+		}
+		stateLock.unlock();
+		synchronized (onChange) {
+			onChange.forEach(c -> c.accept(this));
+		}
+	}
+
+	/**
+	 * Start (or continue) with no delay between cycles
+	 */
+	public void start() {
+		startWithSleep(Schedulable.DEFAULT_SLEEP);
+	}
+
+	/**
+	 * Execute one cycle
+	 */
+	public void step() {
+		if (locked > 0) {
+			synchronized (onChange) {
+				onChange.forEach(c -> c.accept(this));
+			}
+			return;
+		}
+		this.setSleep(0);
+		stateLock.lock();
+		switch (state) {
+		case IDLE:
+			state = State.PENDING_STOP;
+			new Thread(this).start();
+			break;
+		default:
+			break;
+
+		}
+		stateLock.unlock();
+		synchronized (onChange) {
+			onChange.forEach(c -> c.accept(this));
+		}
+	}
+
+	/**
+	 * Stop the scheduler if it is running
+	 */
+	public void stop() {
+		stateLock.lock();
+		switch (state) {
+		case RUNNING:
+			state = State.PENDING_STOP;
+			break;
+		default:
+			break;
+
+		}
+		stateLock.unlock();
+		synchronized (onChange) {
+			onChange.forEach(c -> c.accept(this));
+		}
+	}
+
+	/**
+	 * Threaded run method
+	 */
+	@Override
+	public void run() {
+		treatPendingSchedulables();
+		for (Schedulable schedulable : schedulables) {
+			schedulable.onSchedulingStarts();
+		}
+		boolean mustStop;
+		do {
+			for (Schedulable schedulable : schedulables) {
+				schedulable.cycle();
+			}
+			if (getSleep() != 0) {
+				try {
+					Thread.sleep(getSleep());
+				} catch (final InterruptedException e) {
+					e.printStackTrace();
+				}
+			}
+			mustStop = false;
+			for (Schedulable schedulable : schedulables) {
+				mustStop |= schedulable.stopCondition();
+			}
+		} while (state == State.RUNNING && !mustStop);
+		stateLock.lock();
+		state = State.IDLE;
+		stateLock.unlock();
+
+		for (Schedulable schedulable : schedulables) {
+			schedulable.onSchedulingStops();
+		}
+		treatPendingSchedulables();
+		if (onStop != null)
+			onStop.accept(this);
+	}
+
+	/**
+	 * Effectively Add or Remove the schedulables that were added or removed during
+	 * a cycle to avoid {@link ConcurrentModificationException}
+	 */
+	private void treatPendingSchedulables() {
+		while (!pendingAdditionSchedulables.isEmpty())
+			schedulables.add(pendingAdditionSchedulables.poll());
+		while (!pendingRemovalSchedulables.isEmpty())
+			schedulables.remove(pendingRemovalSchedulables.poll());
+
+	}
+
+	/**
+	 * Set the method that must be executed when the system is stopped
+	 * 
+	 * @param _onStop
+	 *            Consumer method
+	 */
+	public final void setOnStop(Consumer<Scheduler> _onStop) {
+		this.onStop = _onStop;
+	}
+
+	/**
+	 * Add a method that must be executed when the scheduler speed is changed
+	 * 
+	 * @param _onChange
+	 *            Consumer method
+	 */
+	public final void addOnChange(Consumer<Scheduler> _onChange) {
+		synchronized (onChange) {
+			this.onChange.add(_onChange);
+		}
+	}
+
+	/**
+	 * Is the scheduler running ?
+	 * 
+	 * @return true if the scheduler is running
+	 */
+	public boolean isRunning() {
+		return state == State.RUNNING;
+	}
+
+	/**
+	 * Getter for the sleep time
+	 * 
+	 * @return the sleep time
+	 */
+
+	public int getSleep() {
+		return sleep;
+	}
+
+	/**
+	 * Setter for the sleep time
+	 * 
+	 * @param sleep
+	 *            The time between each cycle
+	 */
+	public void setSleep(int sleep) {
+		this.sleep = sleep;
+	}
+
+	/**
+	 * Plan to add a schedulable
+	 * 
+	 * @param _schedulable
+	 *            the schedulable to add
+	 */
+	public void add(Schedulable _schedulable) {
+		this.pendingAdditionSchedulables.add(_schedulable);
+	}
+
+	/**
+	 * Plan to remove a schedulable
+	 * 
+	 * @param _schedulable
+	 *            the schedulable to remove
+	 */
+	public void remove(Schedulable _schedulable) {
+		this.pendingRemovalSchedulables.add(_schedulable);
+	}
+
+	/**
+	 * Soft lock the scheduler to avoid a too early running
+	 */
+	public void lock() {
+		locked++;
+	}
+
+	/**
+	 * Soft unlock the scheduler to avoid a too early running
+	 */
+	public void unlock() {
+		locked--;
+	}
+
+}
diff --git a/AMAKFX/src/fr/irit/smac/amak/examples/philosophers/PhilosopherExample.java b/AMAKFX/src/fr/irit/smac/amak/examples/philosophers/PhilosopherExample.java
index c52a91a4e1126a4c0156cc9c6c2f6f0d1da37598..d3f6e0bdc9f8d420aa14bf83910e83690a37be30 100644
--- a/AMAKFX/src/fr/irit/smac/amak/examples/philosophers/PhilosopherExample.java
+++ b/AMAKFX/src/fr/irit/smac/amak/examples/philosophers/PhilosopherExample.java
@@ -1,199 +1,199 @@
-package fr.irit.smac.amak.examples.philosophers;
-
-import java.util.Random;
-
-import fr.irit.smac.amak.Agent;
-import fr.irit.smac.amak.ui.VUI;
-import fr.irit.smac.amak.ui.drawables.Drawable;
-import fr.irit.smac.amak.ui.drawables.DrawableRectangle;
-import javafx.scene.paint.Color;
-
-/**
- * This class represents a philosopher;
- * 
- * @author perles
- *
- */
-public class PhilosopherExample extends Agent<PhilosophersAMASExample, TableExample> {
-
-	/**
-	 * The fork on the left of its plate
-	 */
-	private ForkExample left;
-	/**
-	 * The fork on the right of its plate
-	 */
-	private ForkExample right;
-	/**
-	 * The amount of time (in cycle) the philosopher haven't ate (while in state
-	 * hungry)
-	 */
-	private double hungerDuration;
-	/**
-	 * The amount of eaten pastas
-	 */
-	private double eatenPastas;
-
-	/**
-	 * The id of the philosopher
-	 */
-	private int id;
-
-	/**
-	 * States philosophers can be in
-	 * 
-	 * @author perles
-	 *
-	 */
-	public enum State {
-		/**
-		 * The philosopher is thinking. It essentially means that they are not hungry
-		 * and not eating
-		 */
-		THINK,
-		/**
-		 * The philosopher is hungry. He wants to be in the state eating.
-		 */
-		HUNGRY,
-		/**
-		 * The philosopher has obtained the two forks and eat.
-		 */
-		EATING
-	}
-
-	/**
-	 * The current state of the philosopher
-	 */
-	private State state = State.THINK;
-
-	/**
-	 * A rectangle meant to render the state and the location of the philosopher
-	 */
-	private DrawableRectangle drawableRectangle;
-	/**
-	 * The rendering of the left fork when handled by the philosopher
-	 */
-	private Drawable drawableLeftFork;
-	/**
-	 * The rendering of the right fork when handled by the philosopher
-	 */
-	private Drawable drawableRightFork;
-
-	/**
-	 * Constructor of the philosopher
-	 * 
-	 * @param id
-	 *            the identifier of the philosopher
-	 * @param amas
-	 *            the corresponding MAS
-	 * @param left
-	 *            the left fork
-	 * @param right
-	 *            the right fork
-	 */
-	public PhilosopherExample(int id, PhilosophersAMASExample amas, ForkExample left, ForkExample right) {
-		super(amas, id, left, right);
-	}
-
-	@Override
-	public void onInitialization() {
-		this.id = (int) params[0];
-		this.left = (ForkExample) params[1];
-		this.right = (ForkExample) params[2];
-	}
-
-	@Override
-	protected void onRenderingInitialization() {
-		double x = 100 * Math.cos(2 * Math.PI * id / this.amas.getEnvironment().getForks().length);
-		double y = 100 * Math.sin(2 * Math.PI * id / this.amas.getEnvironment().getForks().length);
-		drawableRectangle = VUI.get().createAndAddRectangle(x, y, 20, 20);
-		drawableRectangle.setName("Philosopher "+getId());
-		drawableLeftFork = VUI.get().createAndAddRectangle(x - 10, y, 5, 20).setColor(Color.BLACK).setStrokeOnly().hide().setShowInExplorer(false);
-		drawableRightFork = VUI.get().createAndAddRectangle(x + 10, y, 5, 20).setColor(Color.BLACK).setStrokeOnly().hide().setShowInExplorer(false);
-
-	}
-
-	@Override
-	protected void onPerceive() {
-		// Nothing goes here as the perception of neighbors criticality is already made
-		// by the framework
-	}
-
-	@Override
-	protected void onDecideAndAct() {
-		State nextState = state;
-		switch (state) {
-		case EATING:
-			eatenPastas++;
-			if (new Random().nextInt(101) > 50) {
-				left.release(this);
-				right.release(this);
-				nextState = State.THINK;
-			}
-			break;
-		case HUNGRY:
-			hungerDuration++;
-			if (getMostCriticalNeighbor(true) == this) {
-				left.tryTake(this);
-				right.tryTake(this);
-				if (left.owned(this) && right.owned(this))
-					nextState = State.EATING;
-
-			} else {
-				left.release(this);
-				right.release(this);
-			}
-			break;
-		case THINK:
-			if (new Random().nextInt(101) > 50) {
-				hungerDuration = 0;
-				nextState = State.HUNGRY;
-			}
-			break;
-		default:
-			break;
-
-		}
-
-		state = nextState;
-	}
-
-	@Override
-	protected double computeCriticality() {
-		if (state == State.HUNGRY)
-			return hungerDuration;
-		return -1;
-	}
-
-	@Override
-	public void onUpdateRender() {
-		drawableRectangle.setInfo(
-			"Philosopher "+getId()+" :\n"+
-			"State : "+state+"\n"+
-			"Eaten pastas : "+eatenPastas+"."
-		);
-		amas.plot.addData("Eaten pasta", id, eatenPastas);
-		switch (state) {
-		case EATING:
-			drawableRectangle.setColor(Color.BLUE);
-			break;
-		case HUNGRY:
-			drawableRectangle.setColor(Color.RED);
-			break;
-		case THINK:
-			drawableRectangle.setColor(Color.GREEN);
-			break;
-
-		}
-		if (left.owned(this)) {
-			drawableLeftFork.show();
-		} else {
-			drawableLeftFork.hide();
-		}
-		if (right.owned(this)) {
-			drawableRightFork.show();
-		} else {
-			drawableRightFork.hide();
-		}
-	}
-}
+package fr.irit.smac.amak.examples.philosophers;
+
+import java.util.Random;
+
+import fr.irit.smac.amak.Agent;
+import fr.irit.smac.amak.ui.VUI;
+import fr.irit.smac.amak.ui.drawables.Drawable;
+import fr.irit.smac.amak.ui.drawables.DrawableRectangle;
+import javafx.scene.paint.Color;
+
+/**
+ * This class represents a philosopher;
+ * 
+ * @author perles
+ *
+ */
+public class PhilosopherExample extends Agent<PhilosophersAMASExample, TableExample> {
+
+	/**
+	 * The fork on the left of its plate
+	 */
+	private ForkExample left;
+	/**
+	 * The fork on the right of its plate
+	 */
+	private ForkExample right;
+	/**
+	 * The amount of time (in cycle) the philosopher haven't ate (while in state
+	 * hungry)
+	 */
+	private double hungerDuration;
+	/**
+	 * The amount of eaten pastas
+	 */
+	private double eatenPastas;
+
+	/**
+	 * The id of the philosopher
+	 */
+	private int id;
+
+	/**
+	 * States philosophers can be in
+	 * 
+	 * @author perles
+	 *
+	 */
+	public enum State {
+		/**
+		 * The philosopher is thinking. It essentially means that they are not hungry
+		 * and not eating
+		 */
+		THINK,
+		/**
+		 * The philosopher is hungry. He wants to be in the state eating.
+		 */
+		HUNGRY,
+		/**
+		 * The philosopher has obtained the two forks and eat.
+		 */
+		EATING
+	}
+
+	/**
+	 * The current state of the philosopher
+	 */
+	private State state = State.THINK;
+
+	/**
+	 * A rectangle meant to render the state and the location of the philosopher
+	 */
+	private DrawableRectangle drawableRectangle;
+	/**
+	 * The rendering of the left fork when handled by the philosopher
+	 */
+	private Drawable drawableLeftFork;
+	/**
+	 * The rendering of the right fork when handled by the philosopher
+	 */
+	private Drawable drawableRightFork;
+
+	/**
+	 * Constructor of the philosopher
+	 * 
+	 * @param id
+	 *            the identifier of the philosopher
+	 * @param amas
+	 *            the corresponding MAS
+	 * @param left
+	 *            the left fork
+	 * @param right
+	 *            the right fork
+	 */
+	public PhilosopherExample(int id, PhilosophersAMASExample amas, ForkExample left, ForkExample right) {
+		super(null, amas, id, left, right);
+	}
+
+	@Override
+	public void onInitialization() {
+		this.id = (int) params[0];
+		this.left = (ForkExample) params[1];
+		this.right = (ForkExample) params[2];
+	}
+
+	@Override
+	protected void onRenderingInitialization() {
+		double x = 100 * Math.cos(2 * Math.PI * id / this.amas.getEnvironment().getForks().length);
+		double y = 100 * Math.sin(2 * Math.PI * id / this.amas.getEnvironment().getForks().length);
+		drawableRectangle = VUI.get(mainWindow).createAndAddRectangle(x, y, 20, 20);
+		drawableRectangle.setName("Philosopher "+getId());
+		drawableLeftFork = VUI.get(mainWindow).createAndAddRectangle(x - 10, y, 5, 20).setColor(Color.BLACK).setStrokeOnly().hide().setShowInExplorer(false);
+		drawableRightFork = VUI.get(mainWindow).createAndAddRectangle(x + 10, y, 5, 20).setColor(Color.BLACK).setStrokeOnly().hide().setShowInExplorer(false);
+
+	}
+
+	@Override
+	protected void onPerceive() {
+		// Nothing goes here as the perception of neighbors criticality is already made
+		// by the framework
+	}
+
+	@Override
+	protected void onDecideAndAct() {
+		State nextState = state;
+		switch (state) {
+		case EATING:
+			eatenPastas++;
+			if (new Random().nextInt(101) > 50) {
+				left.release(this);
+				right.release(this);
+				nextState = State.THINK;
+			}
+			break;
+		case HUNGRY:
+			hungerDuration++;
+			if (getMostCriticalNeighbor(true) == this) {
+				left.tryTake(this);
+				right.tryTake(this);
+				if (left.owned(this) && right.owned(this))
+					nextState = State.EATING;
+
+			} else {
+				left.release(this);
+				right.release(this);
+			}
+			break;
+		case THINK:
+			if (new Random().nextInt(101) > 50) {
+				hungerDuration = 0;
+				nextState = State.HUNGRY;
+			}
+			break;
+		default:
+			break;
+
+		}
+
+		state = nextState;
+	}
+
+	@Override
+	protected double computeCriticality() {
+		if (state == State.HUNGRY)
+			return hungerDuration;
+		return -1;
+	}
+
+	@Override
+	public void onUpdateRender() {
+		drawableRectangle.setInfo(
+			"Philosopher "+getId()+" :\n"+
+			"State : "+state+"\n"+
+			"Eaten pastas : "+eatenPastas+"."
+		);
+		amas.plot.addData("Eaten pasta", id, eatenPastas);
+		switch (state) {
+		case EATING:
+			drawableRectangle.setColor(Color.BLUE);
+			break;
+		case HUNGRY:
+			drawableRectangle.setColor(Color.RED);
+			break;
+		case THINK:
+			drawableRectangle.setColor(Color.GREEN);
+			break;
+
+		}
+		if (left.owned(this)) {
+			drawableLeftFork.show();
+		} else {
+			drawableLeftFork.hide();
+		}
+		if (right.owned(this)) {
+			drawableRightFork.show();
+		} else {
+			drawableRightFork.hide();
+		}
+	}
+}
diff --git a/AMAKFX/src/fr/irit/smac/amak/examples/philosophers/PhilosophersAMASExample.java b/AMAKFX/src/fr/irit/smac/amak/examples/philosophers/PhilosophersAMASExample.java
index 5b00921f5659adf1f7ec2f59b52e4a425f244ae4..f996df5458cdfbee0d9812a2533d0357c0b99d47 100644
--- a/AMAKFX/src/fr/irit/smac/amak/examples/philosophers/PhilosophersAMASExample.java
+++ b/AMAKFX/src/fr/irit/smac/amak/examples/philosophers/PhilosophersAMASExample.java
@@ -1,74 +1,79 @@
-package fr.irit.smac.amak.examples.philosophers;
-
-import fr.irit.smac.amak.Amas;
-import fr.irit.smac.amak.Configuration;
-import fr.irit.smac.amak.Scheduling;
-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.MainWindow;
-import fr.irit.smac.amak.ui.VUI;
-import javafx.scene.control.Label;
-import javafx.scene.paint.Color;
-
-public class PhilosophersAMASExample extends Amas<TableExample> {
-	private Label comp;
-	private PhilosopherExample[] ps;
-	
-	public AmakPlot plot;
-
-	public PhilosophersAMASExample(TableExample env) {
-		super(env, Scheduling.DEFAULT);
-	}
-	
-	@Override
-	protected void onRenderingInitialization() {
-		super.onRenderingInitialization();
-		plot = new AmakPlot("Eaten pasten", ChartType.BAR, "Philosophers", "Number of eaten pastas");
-	}
-
-	@Override
-	protected void onInitialConfiguration() {
-		Configuration.executionPolicy = ExecutionPolicy.TWO_PHASES;
-		comp = new Label("Cycle");
-		MainWindow.addToolbar(comp);
-
-		VUI.get().createAndAddRectangle(20, 20, 20, 20).setColor(Color.RED).setFixed().setLayer(10).setShowInExplorer(false);
-		VUI.get().createAndAddString(45, 25, "Hungry").setFixed().setLayer(10).setShowInExplorer(false);
-
-		VUI.get().createAndAddRectangle(20, 45, 20, 20).setColor(Color.BLUE).setFixed().setLayer(10).setShowInExplorer(false);
-		VUI.get().createAndAddString(45, 50, "Eating").setFixed().setLayer(10).setShowInExplorer(false);
-
-		VUI.get().createAndAddRectangle(20, 70, 20, 20).setColor(Color.GREEN).setFixed().setLayer(10).setShowInExplorer(false);
-		VUI.get().createAndAddString(45, 75, "Thinking").setFixed().setLayer(10).setShowInExplorer(false);
-	}
-
-	@Override
-	protected void onInitialAgentsCreation() {
-		ps = new PhilosopherExample[getEnvironment().getForks().length];
-		// Create one agent per fork
-		for (int i = 0; i < getEnvironment().getForks().length - 1; i++) {
-			ps[i] = new PhilosopherExample(i, this, getEnvironment().getForks()[i], getEnvironment().getForks()[i + 1]);
-		}
-
-		// Let the last philosopher takes the first fork (round table)
-		ps[getEnvironment().getForks().length - 1] = new PhilosopherExample(getEnvironment().getForks().length - 1,
-				this, getEnvironment().getForks()[getEnvironment().getForks().length - 1],
-				getEnvironment().getForks()[0]);
-
-		// Add neighborhood
-		for (int i = 1; i < ps.length; i++) {
-			ps[i].addNeighbor(ps[i - 1]);
-			ps[i - 1].addNeighbor(ps[i]);
-		}
-		ps[0].addNeighbor(ps[ps.length - 1]);
-		ps[ps.length - 1].addNeighbor(ps[0]);
-	}
-
-	@Override
-	protected void onSystemCycleBegin() {
-		RunLaterHelper.runLater(() -> {
-			comp.setText("Cycle " + getCycle());
-		});
-	}
-}
+package fr.irit.smac.amak.examples.philosophers;
+
+import fr.irit.smac.amak.Amas;
+import fr.irit.smac.amak.Configuration;
+import fr.irit.smac.amak.Scheduling;
+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.MainWindow;
+import fr.irit.smac.amak.ui.VUI;
+import javafx.scene.control.Label;
+import javafx.scene.paint.Color;
+
+public class PhilosophersAMASExample extends Amas<TableExample> {
+	
+	public MainWindow mainWindow;
+	
+	private Label comp;
+	private PhilosopherExample[] ps;
+	
+	public AmakPlot plot;
+
+	public PhilosophersAMASExample(MainWindow window, TableExample env) {
+		super(window, env, Scheduling.DEFAULT);
+		
+		mainWindow = window;
+	}
+	
+	@Override
+	protected void onRenderingInitialization() {
+		super.onRenderingInitialization();
+		plot = new AmakPlot(mainWindow, "Eaten pasten", ChartType.BAR, "Philosophers", "Number of eaten pastas");
+	}
+
+	@Override
+	protected void onInitialConfiguration() {
+		Configuration.executionPolicy = ExecutionPolicy.TWO_PHASES;
+		comp = new Label("Cycle");
+		mainWindow.addToolbar(comp);
+
+		VUI.get(mainWindow).createAndAddRectangle(20, 20, 20, 20).setColor(Color.RED).setFixed().setLayer(10).setShowInExplorer(false);
+		VUI.get(mainWindow).createAndAddString(45, 25, "Hungry").setFixed().setLayer(10).setShowInExplorer(false);
+
+		VUI.get(mainWindow).createAndAddRectangle(20, 45, 20, 20).setColor(Color.BLUE).setFixed().setLayer(10).setShowInExplorer(false);
+		VUI.get(mainWindow).createAndAddString(45, 50, "Eating").setFixed().setLayer(10).setShowInExplorer(false);
+
+		VUI.get(mainWindow).createAndAddRectangle(20, 70, 20, 20).setColor(Color.GREEN).setFixed().setLayer(10).setShowInExplorer(false);
+		VUI.get(mainWindow).createAndAddString(45, 75, "Thinking").setFixed().setLayer(10).setShowInExplorer(false);
+	}
+
+	@Override
+	protected void onInitialAgentsCreation() {
+		ps = new PhilosopherExample[getEnvironment().getForks().length];
+		// Create one agent per fork
+		for (int i = 0; i < getEnvironment().getForks().length - 1; i++) {
+			ps[i] = new PhilosopherExample(i, this, getEnvironment().getForks()[i], getEnvironment().getForks()[i + 1]);
+		}
+
+		// Let the last philosopher takes the first fork (round table)
+		ps[getEnvironment().getForks().length - 1] = new PhilosopherExample(getEnvironment().getForks().length - 1,
+				this, getEnvironment().getForks()[getEnvironment().getForks().length - 1],
+				getEnvironment().getForks()[0]);
+
+		// Add neighborhood
+		for (int i = 1; i < ps.length; i++) {
+			ps[i].addNeighbor(ps[i - 1]);
+			ps[i - 1].addNeighbor(ps[i]);
+		}
+		ps[0].addNeighbor(ps[ps.length - 1]);
+		ps[ps.length - 1].addNeighbor(ps[0]);
+	}
+
+	@Override
+	protected void onSystemCycleBegin() {
+		RunLaterHelper.runLater(() -> {
+			comp.setText("Cycle " + getCycle());
+		});
+	}
+}
diff --git a/AMAKFX/src/fr/irit/smac/amak/examples/philosophers/PhilosophersLaunchExample.java b/AMAKFX/src/fr/irit/smac/amak/examples/philosophers/PhilosophersLaunchExample.java
index 872f28a17493cde46af4924279f3c0e49af984c2..94c4576b4d229f7a0572a5ec91602252e324d57f 100644
--- a/AMAKFX/src/fr/irit/smac/amak/examples/philosophers/PhilosophersLaunchExample.java
+++ b/AMAKFX/src/fr/irit/smac/amak/examples/philosophers/PhilosophersLaunchExample.java
@@ -1,10 +1,10 @@
-package fr.irit.smac.amak.examples.philosophers;
-
-public class PhilosophersLaunchExample {
-
-	public static void main(String[] args) {
-		TableExample env = new TableExample();
-		new PhilosophersAMASExample(env);
-		
-	}
-}
+package fr.irit.smac.amak.examples.philosophers;
+
+public class PhilosophersLaunchExample {
+
+	public static void main(String[] args) {
+		TableExample env = new TableExample();
+		new PhilosophersAMASExample(null, env);
+		
+	}
+}
diff --git a/AMAKFX/src/fr/irit/smac/amak/examples/philosophers/TableExample.java b/AMAKFX/src/fr/irit/smac/amak/examples/philosophers/TableExample.java
index c5227eff27b3e368460ac0e86c74f30e979b2dd7..a84c75bdc512e387baaf08ba6ae67f9aba70fbd7 100644
--- a/AMAKFX/src/fr/irit/smac/amak/examples/philosophers/TableExample.java
+++ b/AMAKFX/src/fr/irit/smac/amak/examples/philosophers/TableExample.java
@@ -1,24 +1,24 @@
-package fr.irit.smac.amak.examples.philosophers;
-
-import fr.irit.smac.amak.Environment;
-import fr.irit.smac.amak.Scheduling;
-
-public class TableExample extends Environment {
-	public TableExample(Object...params) {
-		super(Scheduling.HIDDEN, params);
-	}
-
-	private ForkExample[] forks;
-
-	@Override
-	public void onInitialization() {
-		// Set 10 forks on the table
-		forks = new ForkExample[10];
-		for (int i = 0; i < forks.length; i++)
-			forks[i] = new ForkExample();
-	}
-
-	public ForkExample[] getForks() {
-		return forks;
-	}
-}
+package fr.irit.smac.amak.examples.philosophers;
+
+import fr.irit.smac.amak.Environment;
+import fr.irit.smac.amak.Scheduling;
+
+public class TableExample extends Environment {
+	public TableExample(Object...params) {
+		super(null, Scheduling.HIDDEN, params);
+	}
+
+	private ForkExample[] forks;
+
+	@Override
+	public void onInitialization() {
+		// Set 10 forks on the table
+		forks = new ForkExample[10];
+		for (int i = 0; i < forks.length; i++)
+			forks[i] = new ForkExample();
+	}
+
+	public ForkExample[] getForks() {
+		return forks;
+	}
+}
diff --git a/AMAKFX/src/fr/irit/smac/amak/examples/randomants/AntExample.java b/AMAKFX/src/fr/irit/smac/amak/examples/randomants/AntExample.java
index 8186b0d4b27f736e337391f0110cb3340d7b2d2d..c0d48981ffe6c83c2d021337b557a29de1fbe880 100644
--- a/AMAKFX/src/fr/irit/smac/amak/examples/randomants/AntExample.java
+++ b/AMAKFX/src/fr/irit/smac/amak/examples/randomants/AntExample.java
@@ -1,88 +1,90 @@
-package fr.irit.smac.amak.examples.randomants;
-
-import fr.irit.smac.amak.Agent;
-import fr.irit.smac.amak.ui.VUI;
-import fr.irit.smac.amak.ui.drawables.DrawableImage;
-
-public class AntExample extends Agent<AntHillExample, WorldExample> {
-	
-	private boolean dead = false; 
-	
-	/**
-	 * X coordinate of the ant in the world
-	 */
-	public double dx;
-	/**
-	 * Y coordinate of the ant in the world
-	 */
-	public double dy;
-	/**
-	 * Angle in radians
-	 */
-	private double angle = Math.random() * Math.PI * 2;
-	private DrawableImage image;
-
-	/**
-	 * Constructor of the ant
-	 * 
-	 * @param amas
-	 *            the amas the ant belongs to
-	 * @param startX
-	 *            Initial X coordinate
-	 * @param startY
-	 *            Initial Y coordinate
-	 */
-	public AntExample(AntHillExample amas, double startX, double startY) {
-		super(amas, startX, startY);
-	}
-	@Override
-	public void onInitialization() {
-		dx = (double) params[0];
-		dy = (double) params[1];
-	}
-
-	@Override
-	protected void onRenderingInitialization() {
-		image = VUI.get().createAndAddImage(dx, dy, "file:resources/ant.png");
-		image.setName("Ant "+getId());
-	}
-
-	/**
-	 * Move in a random direction
-	 */
-	@Override
-	protected void onDecideAndAct() {
-		double random = amas.getEnvironment().getRandom().nextGaussian();
-		angle += random * 0.1;
-		dx += Math.cos(angle);
-		dy += Math.sin(angle);
-		while (dx >= getAmas().getEnvironment().getWidth() / 2)
-			dx -= getAmas().getEnvironment().getWidth();
-		while (dy >= getAmas().getEnvironment().getHeight() / 2)
-			dy -= getAmas().getEnvironment().getHeight();
-		while (dx < -getAmas().getEnvironment().getWidth() / 2)
-			dx += getAmas().getEnvironment().getWidth();
-		while (dy < -getAmas().getEnvironment().getHeight() / 2)
-			dy += getAmas().getEnvironment().getHeight();
-
-		if (amas.getEnvironment().getRandom().nextDouble() < 0.001) {
-			dead = true;
-			destroy();
-		}
-
-		if (amas.getEnvironment().getRandom().nextDouble() < 0.001) {
-			new AntExample(getAmas(), dx, dy);
-		}
-	}
-
-	@Override
-	public void onUpdateRender() {
-		image.move(dx, dy);
-		image.setAngle(angle);
-		image.setInfo("Ant "+getId()+"\nPosition "+dx+" "+dy+"\nAngle "+angle);
-		if(dead) {
-			image.setFilename("file:Resources/ant_dead.png");
-			image.setInfo("Ant "+getId()+"\nPosition "+dx+" "+dy+"\nAngle "+angle+"\nDead");
-		}
-	}
-}
+package fr.irit.smac.amak.examples.randomants;
+
+import fr.irit.smac.amak.Agent;
+import fr.irit.smac.amak.ui.AmasWindow;
+import fr.irit.smac.amak.ui.MainWindow;
+import fr.irit.smac.amak.ui.VUI;
+import fr.irit.smac.amak.ui.drawables.DrawableImage;
+
+public class AntExample extends Agent<AntHillExample, WorldExample> {
+	
+	private boolean dead = false; 
+	
+	/**
+	 * X coordinate of the ant in the world
+	 */
+	public double dx;
+	/**
+	 * Y coordinate of the ant in the world
+	 */
+	public double dy;
+	/**
+	 * Angle in radians
+	 */
+	private double angle = Math.random() * Math.PI * 2;
+	private DrawableImage image;
+
+	/**
+	 * Constructor of the ant
+	 * 
+	 * @param amas
+	 *            the amas the ant belongs to
+	 * @param startX
+	 *            Initial X coordinate
+	 * @param startY
+	 *            Initial Y coordinate
+	 */
+	public AntExample(AmasWindow amasWindow, AntHillExample amas, double startX, double startY) {
+		super(amasWindow, amas, startX, startY);
+	}
+	@Override
+	public void onInitialization() {
+		dx = (double) params[0];
+		dy = (double) params[1];
+	}
+
+	@Override
+	protected void onRenderingInitialization() {
+		image = VUI.get(amasWindow).createAndAddImage(dx, dy, "file:resources/ant.png");
+		image.setName("Ant "+getId());
+	}
+
+	/**
+	 * Move in a random direction
+	 */
+	@Override
+	protected void onDecideAndAct() {
+		double random = amas.getEnvironment().getRandom().nextGaussian();
+		angle += random * 0.1;
+		dx += Math.cos(angle);
+		dy += Math.sin(angle);
+		while (dx >= getAmas().getEnvironment().getWidth() / 2)
+			dx -= getAmas().getEnvironment().getWidth();
+		while (dy >= getAmas().getEnvironment().getHeight() / 2)
+			dy -= getAmas().getEnvironment().getHeight();
+		while (dx < -getAmas().getEnvironment().getWidth() / 2)
+			dx += getAmas().getEnvironment().getWidth();
+		while (dy < -getAmas().getEnvironment().getHeight() / 2)
+			dy += getAmas().getEnvironment().getHeight();
+
+		if (amas.getEnvironment().getRandom().nextDouble() < 0.001) {
+			dead = true;
+			destroy();
+		}
+
+		if (amas.getEnvironment().getRandom().nextDouble() < 0.001) {
+			new AntExample(amasWindow, getAmas(), dx, dy);
+		}
+	}
+
+	@Override
+	public void onUpdateRender() {
+		image.move(dx, dy);
+		image.setAngle(angle);
+		image.setInfo("Ant "+getId()+"\nPosition "+dx+" "+dy+"\nAngle "+angle);
+		if(dead) {
+			image.setFilename("file:Resources/ant_dead.png");
+			image.setInfo("Ant "+getId()+"\nPosition "+dx+" "+dy+"\nAngle "+angle+"\nDead");
+		}
+	}
+}
diff --git a/AMAKFX/src/fr/irit/smac/amak/examples/randomants/AntHillExample.java b/AMAKFX/src/fr/irit/smac/amak/examples/randomants/AntHillExample.java
index 6e276bb04e76d3be16141419c6bda86f88dba450..76d93405b80869d26cb95b17417a35cd4b7d03a1 100644
--- a/AMAKFX/src/fr/irit/smac/amak/examples/randomants/AntHillExample.java
+++ b/AMAKFX/src/fr/irit/smac/amak/examples/randomants/AntHillExample.java
@@ -1,33 +1,39 @@
-package fr.irit.smac.amak.examples.randomants;
-
-import fr.irit.smac.amak.Amas;
-import fr.irit.smac.amak.Scheduling;
-import fr.irit.smac.amak.tools.RunLaterHelper;
-import fr.irit.smac.amak.ui.VUI;
-import fr.irit.smac.amak.ui.drawables.DrawableString;
-
-public class AntHillExample extends Amas<WorldExample> {
-
-	private DrawableString antsCountLabel;
-
-	public AntHillExample(WorldExample env) {
-		super(env, Scheduling.DEFAULT);
-	}
-
-	@Override
-	protected void onRenderingInitialization() {
-		VUI.get().createAndAddImage(20, 20, "file:Resources/ant.png").setFixed().setLayer(10).setShowInExplorer(false);
-		antsCountLabel = (DrawableString) VUI.get().createAndAddString(45, 25, "Ants count").setFixed().setLayer(10).setShowInExplorer(false);
-	}
-
-	@Override
-	protected void onInitialAgentsCreation() {
-		for (int i = 0; i < 50; i++)
-			new AntExample(this, 0, 0);
-	}
-
-	@Override
-	protected void onSystemCycleEnd() {
-		RunLaterHelper.runLater(()->antsCountLabel.setText("Ants count: " + getAgents().size()));
-	}
-}
+package fr.irit.smac.amak.examples.randomants;
+
+import fr.irit.smac.amak.Amas;
+import fr.irit.smac.amak.Scheduling;
+import fr.irit.smac.amak.tools.RunLaterHelper;
+import fr.irit.smac.amak.ui.AmasWindow;
+import fr.irit.smac.amak.ui.MainWindow;
+import fr.irit.smac.amak.ui.VUI;
+import fr.irit.smac.amak.ui.drawables.DrawableString;
+
+public class AntHillExample extends Amas<WorldExample> {
+
+
+	
+	private DrawableString antsCountLabel;
+
+	public AntHillExample(AmasWindow window, WorldExample env) {
+		super(window, env, Scheduling.DEFAULT);
+	}
+
+	@Override
+	protected void onRenderingInitialization() {
+		VUI.get(amasWindow).createAndAddImage(20, 20, "file:Resources/ant.png").setFixed().setLayer(10).setShowInExplorer(false);
+		antsCountLabel = (DrawableString) VUI.get(amasWindow).createAndAddString(45, 25, "Ants count").setFixed().setLayer(10).setShowInExplorer(false);
+		
+		
+	}
+
+	@Override
+	protected void onInitialAgentsCreation() {
+		for (int i = 0; i < 50; i++)
+			new AntExample(amasWindow, this, 0, 0);
+	}
+
+	@Override
+	protected void onSystemCycleEnd() {
+		RunLaterHelper.runLater(()->antsCountLabel.setText("Ants count: " + getAgents().size()));
+	}
+}
diff --git a/AMAKFX/src/fr/irit/smac/amak/examples/randomants/AntsLaunchExample.java b/AMAKFX/src/fr/irit/smac/amak/examples/randomants/AntsLaunchExample.java
index 523442073a9623b1a43990bc0704227c1a9c21bb..ce6e3f17c15d557f522688e40104613fab8f05ca 100644
--- a/AMAKFX/src/fr/irit/smac/amak/examples/randomants/AntsLaunchExample.java
+++ b/AMAKFX/src/fr/irit/smac/amak/examples/randomants/AntsLaunchExample.java
@@ -1,5 +1,6 @@
 package fr.irit.smac.amak.examples.randomants;
 
+import fr.irit.smac.amak.ui.AmasWindow;
 import fr.irit.smac.amak.ui.MainWindow;
 import javafx.scene.control.Label;
 import javafx.scene.layout.Pane;
@@ -7,14 +8,20 @@ import javafx.scene.layout.Pane;
 public class AntsLaunchExample {
 
 	public static void main(String[] args) {
-		WorldExample env = new WorldExample();
 		
-		new AntHillExample(env);
+		AmasWindow amasWindowAntHillExample = new AmasWindow();
+		
+		
+		WorldExample env = new WorldExample(amasWindowAntHillExample);
+		
+		
+		
+		new AntHillExample(amasWindowAntHillExample, env);
 		
 		Pane panel = new Pane();
 		panel.getChildren().add(new Label("AntHill simulation\n"
 				+ "Ants move randomly.\n"
 				+ "This demo is here to show AMAK rendering capacities.\n"));
-		MainWindow.setLeftPanel(panel);
+		amasWindowAntHillExample.setLeftPanel(panel);
 	}
 }
diff --git a/AMAKFX/src/fr/irit/smac/amak/examples/randomants/AntsLaunchExampleMultiUI.java b/AMAKFX/src/fr/irit/smac/amak/examples/randomants/AntsLaunchExampleMultiUI.java
new file mode 100644
index 0000000000000000000000000000000000000000..5d45bb7fea7d8120d4f6b85585e0a290630988ed
--- /dev/null
+++ b/AMAKFX/src/fr/irit/smac/amak/examples/randomants/AntsLaunchExampleMultiUI.java
@@ -0,0 +1,59 @@
+package fr.irit.smac.amak.examples.randomants;
+
+import fr.irit.smac.amak.ui.AmasWindow;
+import fr.irit.smac.amak.ui.MainWindow;
+import javafx.scene.control.Label;
+import javafx.scene.layout.Pane;
+
+public class AntsLaunchExampleMultiUI {
+
+
+	
+	
+	
+	public static void main(String[] args) {
+		
+		
+		MainWindow mainWindow = new MainWindow();
+		mainWindow.instance();
+		
+		AmasWindow mainWindowAntHillExample = new AmasWindow();
+		
+		
+
+		//MainWindow mainWindowAntHillExample2 = new MainWindow();
+		
+		
+		WorldExample env = new WorldExample(mainWindowAntHillExample);
+		
+		
+		
+		new AntHillExample(mainWindowAntHillExample, env);
+		
+		Pane panel = new Pane();
+		panel.getChildren().add(new Label("AntHill simulation\n"
+				+ "Ants move randomly.\n"
+				+ "This demo is here to show AMAK rendering capacities.\n"));
+		mainWindowAntHillExample.setLeftPanel(panel);
+		
+		
+		
+		
+	}
+	
+	
+	
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AMAKFX/src/fr/irit/smac/amak/examples/randomants/WorldExample.java b/AMAKFX/src/fr/irit/smac/amak/examples/randomants/WorldExample.java
index 2c6ea56a9ef181a9cf191d87669c578c3dd7e24b..a785f273a3b3120886fab89d22f82471d956416d 100644
--- a/AMAKFX/src/fr/irit/smac/amak/examples/randomants/WorldExample.java
+++ b/AMAKFX/src/fr/irit/smac/amak/examples/randomants/WorldExample.java
@@ -1,28 +1,31 @@
-package fr.irit.smac.amak.examples.randomants;
-
-import fr.irit.smac.amak.Environment;
-import fr.irit.smac.amak.Scheduling;
-
-public class WorldExample extends Environment {
-	public WorldExample(Object...params) {
-		super(Scheduling.DEFAULT, params);
-	}
-
-	private int width;
-	private int height;
-
-	public int getWidth() {
-		return width;
-	}
-
-	public int getHeight() {
-		return height;
-	}
-
-	@Override
-	public void onInitialization() {
-		this.width = 800;
-		this.height = 600;
-	}
-
-}
+package fr.irit.smac.amak.examples.randomants;
+
+import fr.irit.smac.amak.Environment;
+import fr.irit.smac.amak.Scheduling;
+import fr.irit.smac.amak.ui.AmasWindow;
+import fr.irit.smac.amak.ui.MainWindow;
+
+public class WorldExample extends Environment {
+	
+	public WorldExample(AmasWindow amasWindow, Object...params) {
+		super(amasWindow, Scheduling.DEFAULT, params);
+	}
+
+	private int width;
+	private int height;
+
+	public int getWidth() {
+		return width;
+	}
+
+	public int getHeight() {
+		return height;
+	}
+
+	@Override
+	public void onInitialization() {
+		this.width = 800;
+		this.height = 600;
+	}
+
+}
diff --git a/AMAKFX/src/fr/irit/smac/amak/tests/AsyncTest.java b/AMAKFX/src/fr/irit/smac/amak/tests/AsyncTest.java
index 7fe3c2a681425c49cded0d21b96c1f51b81bb2fe..5746c87884429b7a1ddc53b6b2b323b83ecbf257 100644
--- a/AMAKFX/src/fr/irit/smac/amak/tests/AsyncTest.java
+++ b/AMAKFX/src/fr/irit/smac/amak/tests/AsyncTest.java
@@ -1,88 +1,90 @@
-package fr.irit.smac.amak.tests;
-
-import fr.irit.smac.amak.Agent;
-import fr.irit.smac.amak.Amas;
-import fr.irit.smac.amak.Configuration;
-import fr.irit.smac.amak.Environment;
-import fr.irit.smac.amak.Scheduling;
-import fr.irit.smac.amak.tools.Log;
-import fr.irit.smac.amak.tools.Profiler;
-
-public class AsyncTest {
-
-	public static void main(String[] args) {
-		new AsyncTest();
-	}
-
-	public AsyncTest() {
-		Configuration.allowedSimultaneousAgentsExecution = 10;
-
-		Log.defaultMinLevel = Log.Level.DEBUG;
-		runAmas();
-	}
-
-	private void runAmas() {
-		MyAMAS amas = new MyAMAS(new MyEnvironment(), Scheduling.DEFAULT);
-		amas.getScheduler().setOnStop(s -> {
-			Log.defaultLog.inform("time", "Threads used: %d", Configuration.allowedSimultaneousAgentsExecution);
-			Log.defaultLog.inform("time", "Elapsed time: %s", Profiler.endHR("amas"));
-		});
-		Profiler.start("amas");
-
-		amas.start();
-	}
-
-	public class MyAMAS extends Amas<MyEnvironment> {
-
-		public MyAMAS(MyEnvironment environment, Scheduling scheduling, Object... params) {
-			super(environment, scheduling);
-		}
-
-		@Override
-		protected void onInitialAgentsCreation() {
-			for (int i = 0; i < 2; i++) {
-				new MyAgent(this);
-			}
-		}
-	}
-
-	public class MyAgent extends Agent<MyAMAS, MyEnvironment> {
-		public int myCycle = 0;
-
-		public MyAgent(MyAMAS amas, Object... params) {
-			super(amas, params);
-		}
-
-		@Override
-		public void onInitialization() {
-			setAsynchronous();
-		}
-
-		@Override
-		protected void onPerceive() {
-		}
-
-		@Override
-		protected void onAct() {
-			myCycle++;
-			// Sleep the thread to simulate a behavior
-			try {
-				Thread.sleep(getId() % 2 == 0 ? 0 : 1000);
-			} catch (InterruptedException e) {
-				e.printStackTrace();
-			}
-		}
-
-		@Override
-		protected void onAgentCycleEnd() {
-			Log.defaultLog.debug("AsyncTest", "Agent #%d cycle %d", getId(), myCycle);
-		}
-	}
-
-	public class MyEnvironment extends Environment {
-
-		public MyEnvironment(Object... params) {
-			super(Scheduling.DEFAULT, params);
-		}
-	}
-}
+package fr.irit.smac.amak.tests;
+
+import fr.irit.smac.amak.Agent;
+import fr.irit.smac.amak.Amas;
+import fr.irit.smac.amak.Configuration;
+import fr.irit.smac.amak.Environment;
+import fr.irit.smac.amak.Scheduling;
+import fr.irit.smac.amak.tools.Log;
+import fr.irit.smac.amak.tools.Profiler;
+import fr.irit.smac.amak.ui.MainWindow;
+
+public class AsyncTest {
+
+	public static void main(String[] args) {
+		new AsyncTest();
+	}
+
+	public AsyncTest() {
+		Configuration.allowedSimultaneousAgentsExecution = 10;
+
+		Log.defaultMinLevel = Log.Level.DEBUG;
+		runAmas();
+	}
+
+	private void runAmas() {
+		MainWindow mainWindow = new MainWindow();
+		MyAMAS amas = new MyAMAS(mainWindow, new MyEnvironment(), Scheduling.DEFAULT);
+		amas.getScheduler().setOnStop(s -> {
+			Log.defaultLog.inform("time", "Threads used: %d", Configuration.allowedSimultaneousAgentsExecution);
+			Log.defaultLog.inform("time", "Elapsed time: %s", Profiler.endHR("amas"));
+		});
+		Profiler.start("amas");
+
+		amas.start();
+	}
+
+	public class MyAMAS extends Amas<MyEnvironment> {
+
+		public MyAMAS(MainWindow mainWindow, MyEnvironment environment, Scheduling scheduling, Object... params) {
+			super(mainWindow, environment, scheduling);
+		}
+
+		@Override
+		protected void onInitialAgentsCreation() {
+			for (int i = 0; i < 2; i++) {
+				new MyAgent(this);
+			}
+		}
+	}
+
+	public class MyAgent extends Agent<MyAMAS, MyEnvironment> {
+		public int myCycle = 0;
+
+		public MyAgent(MyAMAS amas, Object... params) {
+			super(null,amas, params);
+		}
+
+		@Override
+		public void onInitialization() {
+			setAsynchronous();
+		}
+
+		@Override
+		protected void onPerceive() {
+		}
+
+		@Override
+		protected void onAct() {
+			myCycle++;
+			// Sleep the thread to simulate a behavior
+			try {
+				Thread.sleep(getId() % 2 == 0 ? 0 : 1000);
+			} catch (InterruptedException e) {
+				e.printStackTrace();
+			}
+		}
+
+		@Override
+		protected void onAgentCycleEnd() {
+			Log.defaultLog.debug("AsyncTest", "Agent #%d cycle %d", getId(), myCycle);
+		}
+	}
+
+	public class MyEnvironment extends Environment {
+
+		public MyEnvironment(Object... params) {
+			super(null,Scheduling.DEFAULT, params);
+		}
+	}
+}
diff --git a/AMAKFX/src/fr/irit/smac/amak/tests/CommandLineOnlyResolution.java b/AMAKFX/src/fr/irit/smac/amak/tests/CommandLineOnlyResolution.java
index c09792995c560aa219d13ce4a915a0e2de33b7e3..44b34b5ab47a0e24f857d3b4cd658a06f9ce8f13 100644
--- a/AMAKFX/src/fr/irit/smac/amak/tests/CommandLineOnlyResolution.java
+++ b/AMAKFX/src/fr/irit/smac/amak/tests/CommandLineOnlyResolution.java
@@ -1,40 +1,40 @@
-package fr.irit.smac.amak.tests;
-
-import fr.irit.smac.amak.Amas;
-import fr.irit.smac.amak.Configuration;
-import fr.irit.smac.amak.Environment;
-import fr.irit.smac.amak.Scheduling;
-import fr.irit.smac.amak.tools.Log;
-
-public class CommandLineOnlyResolution {
-
-	public static void main(String[] args) {
-		new CommandLineOnlyResolution();
-	}
-	public CommandLineOnlyResolution() {
-		Configuration.commandLineMode = true;
-		new MyAMAS().start();
-	}
-	
-	public class MyAMAS extends Amas<MyEnv> {
-
-		public MyAMAS() {
-			super(new MyEnv(), Scheduling.DEFAULT);
-		}
-		@Override
-		public boolean stopCondition() {
-			return cycle==100;
-		}
-		@Override
-		protected void onSystemCycleEnd() {
-			Log.defaultLog.debug("test", "yolo");
-		}
-	}
-	public class MyEnv extends Environment {
-
-		public MyEnv() {
-			super(Scheduling.DEFAULT);
-		}
-	}
-
-}
+package fr.irit.smac.amak.tests;
+
+import fr.irit.smac.amak.Amas;
+import fr.irit.smac.amak.Configuration;
+import fr.irit.smac.amak.Environment;
+import fr.irit.smac.amak.Scheduling;
+import fr.irit.smac.amak.tools.Log;
+
+public class CommandLineOnlyResolution {
+
+	public static void main(String[] args) {
+		new CommandLineOnlyResolution();
+	}
+	public CommandLineOnlyResolution() {
+		Configuration.commandLineMode = true;
+		new MyAMAS().start();
+	}
+	
+	public class MyAMAS extends Amas<MyEnv> {
+
+		public MyAMAS() {
+			super(null,new MyEnv(), Scheduling.DEFAULT);
+		}
+		@Override
+		public boolean stopCondition() {
+			return cycle==100;
+		}
+		@Override
+		protected void onSystemCycleEnd() {
+			Log.defaultLog.debug("test", "yolo");
+		}
+	}
+	public class MyEnv extends Environment {
+
+		public MyEnv() {
+			super(null, Scheduling.DEFAULT);
+		}
+	}
+
+}
diff --git a/AMAKFX/src/fr/irit/smac/amak/tests/Order.java b/AMAKFX/src/fr/irit/smac/amak/tests/Order.java
index ece9772761e35c275cb49bcd6c0e66a9cb87d055..d89b2bd7fdee60cddbdfaef32e268a728b29f8d3 100644
--- a/AMAKFX/src/fr/irit/smac/amak/tests/Order.java
+++ b/AMAKFX/src/fr/irit/smac/amak/tests/Order.java
@@ -1,61 +1,61 @@
-package fr.irit.smac.amak.tests;
-
-import fr.irit.smac.amak.Amas;
-import fr.irit.smac.amak.Configuration;
-import fr.irit.smac.amak.Environment;
-import fr.irit.smac.amak.Scheduling;
-import fr.irit.smac.amak.tools.Log;
-
-public class Order {
-	public boolean lastExecutedWasEnvironment;
-	public boolean firstFound = false;
-	public static void main(String[] args) {
-		new Order();
-		
-		
-	}
-	public Order() {
-		Configuration.commandLineMode = true;
-		new MyAMAS().start();
-	}
-	
-	public class MyAMAS extends Amas<MyEnv> {
-
-		public MyAMAS() {
-			super(new MyEnv(), Scheduling.DEFAULT);
-		}
-		@Override
-		public boolean stopCondition() {
-			return cycle==100000000;
-		}
-		@Override
-		protected void onSystemCycleEnd() {
-			if (!firstFound) {
-				Log.defaultLog.debug("test","First is MAS");
-				firstFound = true;
-			}
-			
-			if (!lastExecutedWasEnvironment) {
-				Log.defaultLog.fatal("test", "last executed was not the environment");
-				System.exit(-1);
-			}
-			lastExecutedWasEnvironment = false;
-		}
-	}
-	public class MyEnv extends Environment {
-
-		public MyEnv() {
-			super(Scheduling.DEFAULT);
-		}
-		@Override
-		public void onCycle() {
-			if (!firstFound) {
-				Log.defaultLog.debug("test","First is Environment");
-				firstFound = true;
-			}
-			
-			lastExecutedWasEnvironment = true;
-		}
-	}
-
-}
+package fr.irit.smac.amak.tests;
+
+import fr.irit.smac.amak.Amas;
+import fr.irit.smac.amak.Configuration;
+import fr.irit.smac.amak.Environment;
+import fr.irit.smac.amak.Scheduling;
+import fr.irit.smac.amak.tools.Log;
+
+public class Order {
+	public boolean lastExecutedWasEnvironment;
+	public boolean firstFound = false;
+	public static void main(String[] args) {
+		new Order();
+		
+		
+	}
+	public Order() {
+		Configuration.commandLineMode = true;
+		new MyAMAS().start();
+	}
+	
+	public class MyAMAS extends Amas<MyEnv> {
+
+		public MyAMAS() {
+			super(null,new MyEnv(), Scheduling.DEFAULT);
+		}
+		@Override
+		public boolean stopCondition() {
+			return cycle==100000000;
+		}
+		@Override
+		protected void onSystemCycleEnd() {
+			if (!firstFound) {
+				Log.defaultLog.debug("test","First is MAS");
+				firstFound = true;
+			}
+			
+			if (!lastExecutedWasEnvironment) {
+				Log.defaultLog.fatal("test", "last executed was not the environment");
+				System.exit(-1);
+			}
+			lastExecutedWasEnvironment = false;
+		}
+	}
+	public class MyEnv extends Environment {
+
+		public MyEnv() {
+			super(null, Scheduling.DEFAULT);
+		}
+		@Override
+		public void onCycle() {
+			if (!firstFound) {
+				Log.defaultLog.debug("test","First is Environment");
+				firstFound = true;
+			}
+			
+			lastExecutedWasEnvironment = true;
+		}
+	}
+
+}
diff --git a/AMAKFX/src/fr/irit/smac/amak/tests/ScalibilityTest.java b/AMAKFX/src/fr/irit/smac/amak/tests/ScalibilityTest.java
index d6b73adabf401c98c32c7d6d528f85d8e5bb3652..1a550f2f20e9d1313b6c9b43f8b018422b36ae1a 100644
--- a/AMAKFX/src/fr/irit/smac/amak/tests/ScalibilityTest.java
+++ b/AMAKFX/src/fr/irit/smac/amak/tests/ScalibilityTest.java
@@ -1,98 +1,98 @@
-package fr.irit.smac.amak.tests;
-
-import fr.irit.smac.amak.Agent;
-import fr.irit.smac.amak.Amas;
-import fr.irit.smac.amak.Environment;
-import fr.irit.smac.amak.Scheduling;
-import fr.irit.smac.amak.tools.FileHandler;
-import fr.irit.smac.amak.tools.Log;
-
-public class ScalibilityTest {
-
-	public static void main(String[] args) {
-		new ScalibilityTest();
-
-	}
-
-	private long startTime;
-
-	public ScalibilityTest() {
-		Log.defaultMinLevel = Log.Level.INFORM;
-		runAmasWithNAgents(1);
-	}
-
-	private void runAmasWithNAgents(int i) {
-		Log.defaultLog.inform("Global state", "start i:%d", i);
-		MyAMAS amas = new MyAMAS(new MyEnvironment(), Scheduling.HIDDEN, new Integer(i));
-		amas.getScheduler().setOnStop(s -> {
-			int nextI = i;
-			FileHandler.writeCSVLine("scalability_results.csv", i+"", (System.currentTimeMillis() - startTime)+"");
-			switch (i) {
-			case 1:
-				nextI = 5;
-				break;
-			case 5:
-				nextI = 10;
-				break;
-			case 10:
-				nextI = 100;
-				break;
-			case 100:
-				nextI = 1000;
-				break;
-			default:
-				Log.defaultLog.inform("Global state", "end");
-				return;
-			}
-			runAmasWithNAgents(nextI);
-		});
-		startTime = System.currentTimeMillis();
-		amas.start();
-	}
-
-	public class MyAMAS extends Amas<MyEnvironment> {
-
-		public MyAMAS(MyEnvironment environment, Scheduling scheduling, Object... params) {
-			super(environment, scheduling, params);
-		}
-
-		@Override
-		protected void onInitialAgentsCreation() {
-			for (int i = 0; i < (Integer) params[0]; i++) {
-				new MyAgent(this);
-			}
-		}
-
-		@Override
-		public boolean stopCondition() {
-			return cycle == 100;
-		}
-	}
-
-	public class MyAgent extends Agent<MyAMAS, MyEnvironment> {
-
-		public MyAgent(MyAMAS amas, Object... params) {
-			super(amas, params);
-		}
-
-		@Override
-		protected void onAct() {
-			// Sleep the thread to simulate a behavior
-			try {
-				Thread.sleep((long) ((amas.getEnvironment().getRandom().nextDouble() + 1) * 3));
-			} catch (InterruptedException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-		}
-
-	}
-
-	public class MyEnvironment extends Environment {
-
-		public MyEnvironment(Object...params) {
-			super(Scheduling.DEFAULT, params);
-		}
-
-	}
-}
+package fr.irit.smac.amak.tests;
+
+import fr.irit.smac.amak.Agent;
+import fr.irit.smac.amak.Amas;
+import fr.irit.smac.amak.Environment;
+import fr.irit.smac.amak.Scheduling;
+import fr.irit.smac.amak.tools.FileHandler;
+import fr.irit.smac.amak.tools.Log;
+
+public class ScalibilityTest {
+
+	public static void main(String[] args) {
+		new ScalibilityTest();
+
+	}
+
+	private long startTime;
+
+	public ScalibilityTest() {
+		Log.defaultMinLevel = Log.Level.INFORM;
+		runAmasWithNAgents(1);
+	}
+
+	private void runAmasWithNAgents(int i) {
+		Log.defaultLog.inform("Global state", "start i:%d", i);
+		MyAMAS amas = new MyAMAS(new MyEnvironment(), Scheduling.HIDDEN, new Integer(i));
+		amas.getScheduler().setOnStop(s -> {
+			int nextI = i;
+			FileHandler.writeCSVLine("scalability_results.csv", i+"", (System.currentTimeMillis() - startTime)+"");
+			switch (i) {
+			case 1:
+				nextI = 5;
+				break;
+			case 5:
+				nextI = 10;
+				break;
+			case 10:
+				nextI = 100;
+				break;
+			case 100:
+				nextI = 1000;
+				break;
+			default:
+				Log.defaultLog.inform("Global state", "end");
+				return;
+			}
+			runAmasWithNAgents(nextI);
+		});
+		startTime = System.currentTimeMillis();
+		amas.start();
+	}
+
+	public class MyAMAS extends Amas<MyEnvironment> {
+
+		public MyAMAS(MyEnvironment environment, Scheduling scheduling, Object... params) {
+			super(null, environment, scheduling, params);
+		}
+
+		@Override
+		protected void onInitialAgentsCreation() {
+			for (int i = 0; i < (Integer) params[0]; i++) {
+				new MyAgent(this);
+			}
+		}
+
+		@Override
+		public boolean stopCondition() {
+			return cycle == 100;
+		}
+	}
+
+	public class MyAgent extends Agent<MyAMAS, MyEnvironment> {
+
+		public MyAgent(MyAMAS amas, Object... params) {
+			super(null, amas, params);
+		}
+
+		@Override
+		protected void onAct() {
+			// Sleep the thread to simulate a behavior
+			try {
+				Thread.sleep((long) ((amas.getEnvironment().getRandom().nextDouble() + 1) * 3));
+			} catch (InterruptedException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		}
+
+	}
+
+	public class MyEnvironment extends Environment {
+
+		public MyEnvironment(Object...params) {
+			super(null, Scheduling.DEFAULT, params);
+		}
+
+	}
+}
diff --git a/AMAKFX/src/fr/irit/smac/amak/tests/VisibleUI.java b/AMAKFX/src/fr/irit/smac/amak/tests/VisibleUI.java
index 5076bc2352bf7cc23a28953f8c622ba5bcee51b9..a46a476b314988b98d89bd5d357a2f357c1f269c 100644
--- a/AMAKFX/src/fr/irit/smac/amak/tests/VisibleUI.java
+++ b/AMAKFX/src/fr/irit/smac/amak/tests/VisibleUI.java
@@ -1,12 +1,15 @@
-package fr.irit.smac.amak.tests;
-
-import fr.irit.smac.amak.ui.MainWindow;
-import fr.irit.smac.amak.ui.VUI;
-
-public class VisibleUI {
-	public static void main(String[] args) {
-		MainWindow.setWindowTitle("VUI Example");
-		MainWindow.setWindowIcon("file:Resources/ant.png");
-		VUI.get().createAndAddRectangle(0, 0, 200, 150);
-	}
-}
+package fr.irit.smac.amak.tests;
+
+import fr.irit.smac.amak.ui.MainWindow;
+import fr.irit.smac.amak.ui.VUI;
+
+public class VisibleUI {
+	public static void main(String[] args) {
+		
+		MainWindow mainWindow = new MainWindow();		
+		
+		mainWindow.setWindowTitle("VUI Example");
+		mainWindow.setWindowIcon("file:Resources/ant.png");
+		VUI.get(mainWindow).createAndAddRectangle(0, 0, 200, 150);
+	}
+}
diff --git a/AMAKFX/src/fr/irit/smac/amak/tests/executionorder/Test.java b/AMAKFX/src/fr/irit/smac/amak/tests/executionorder/Test.java
index 3eacfdf7bffd2b8c9f31f7c38b204820e11a0d93..79ff94defb8d42382a182a6b5d2ea0c6e90e48af 100644
--- a/AMAKFX/src/fr/irit/smac/amak/tests/executionorder/Test.java
+++ b/AMAKFX/src/fr/irit/smac/amak/tests/executionorder/Test.java
@@ -1,82 +1,82 @@
-package fr.irit.smac.amak.tests.executionorder;
-
-import fr.irit.smac.amak.Agent;
-import fr.irit.smac.amak.Amas;
-import fr.irit.smac.amak.Environment;
-import fr.irit.smac.amak.Scheduling;
-import fr.irit.smac.amak.tools.Log;
-
-public class Test {
-
-	public static void main(String[] args) {
-		Log.defaultMinLevel = Log.Level.DEBUG;
-		new Test();
-	}
-
-	public Test() {
-		MyAMAS amas = new MyAMAS(new MyEnvironment());
-
-		new Agent1(amas);
-		new Agent2(amas);
-		new Agent2(amas);
-		new Agent1(amas);
-
-		amas.start();
-	}
-
-	private class Agent1 extends Agent<MyAMAS, MyEnvironment> {
-
-		public Agent1(MyAMAS amas) {
-			super(amas);
-		}
-
-		@Override
-		protected int computeExecutionOrderLayer() {
-			return 1;
-		}
-
-		@Override
-		protected void onAct() {
-			Log.defaultLog.debug(toString(), getExecutionOrder()+"");
-		}
-	}
-
-	private class Agent2 extends Agent<MyAMAS, MyEnvironment> {
-
-		public Agent2(MyAMAS amas) {
-			super(amas);
-		}
-
-		@Override
-		protected int computeExecutionOrderLayer() {
-			return 2;
-		}
-
-		@Override
-		protected void onAct() {
-			Log.defaultLog.debug(toString(), getExecutionOrder()+"");
-		}
-	}
-
-	private class MyAMAS extends Amas<MyEnvironment> {
-
-		public MyAMAS(MyEnvironment environment) {
-			super(environment, Scheduling.HIDDEN);
-		}
-		@Override
-		protected void onSystemCycleBegin() {
-			System.out.println("--");
-		}
-
-	}
-
-	private class MyEnvironment extends Environment {
-
-		public MyEnvironment(Object...params) {
-			super(Scheduling.DEFAULT, params);
-			// TODO Auto-generated constructor stub
-		}
-
-	}
-
-}
+package fr.irit.smac.amak.tests.executionorder;
+
+import fr.irit.smac.amak.Agent;
+import fr.irit.smac.amak.Amas;
+import fr.irit.smac.amak.Environment;
+import fr.irit.smac.amak.Scheduling;
+import fr.irit.smac.amak.tools.Log;
+
+public class Test {
+
+	public static void main(String[] args) {
+		Log.defaultMinLevel = Log.Level.DEBUG;
+		new Test();
+	}
+
+	public Test() {
+		MyAMAS amas = new MyAMAS(new MyEnvironment());
+
+		new Agent1(amas);
+		new Agent2(amas);
+		new Agent2(amas);
+		new Agent1(amas);
+
+		amas.start();
+	}
+
+	private class Agent1 extends Agent<MyAMAS, MyEnvironment> {
+
+		public Agent1(MyAMAS amas) {
+			super(null, amas);
+		}
+
+		@Override
+		protected int computeExecutionOrderLayer() {
+			return 1;
+		}
+
+		@Override
+		protected void onAct() {
+			Log.defaultLog.debug(toString(), getExecutionOrder()+"");
+		}
+	}
+
+	private class Agent2 extends Agent<MyAMAS, MyEnvironment> {
+
+		public Agent2(MyAMAS amas) {
+			super(null, amas);
+		}
+
+		@Override
+		protected int computeExecutionOrderLayer() {
+			return 2;
+		}
+
+		@Override
+		protected void onAct() {
+			Log.defaultLog.debug(toString(), getExecutionOrder()+"");
+		}
+	}
+
+	private class MyAMAS extends Amas<MyEnvironment> {
+
+		public MyAMAS(MyEnvironment environment) {
+			super(null, environment, Scheduling.HIDDEN);
+		}
+		@Override
+		protected void onSystemCycleBegin() {
+			System.out.println("--");
+		}
+
+	}
+
+	private class MyEnvironment extends Environment {
+
+		public MyEnvironment(Object...params) {
+			super(null,Scheduling.DEFAULT, params);
+			// TODO Auto-generated constructor stub
+		}
+
+	}
+
+}
diff --git a/AMAKFX/src/fr/irit/smac/amak/ui/AmakPlot.java b/AMAKFX/src/fr/irit/smac/amak/ui/AmakPlot.java
index 60a58286244634a53702a0cea0126b6a792c29aa..b5399cc2a0f82343ae4a77477d82c541039e5824 100644
--- a/AMAKFX/src/fr/irit/smac/amak/ui/AmakPlot.java
+++ b/AMAKFX/src/fr/irit/smac/amak/ui/AmakPlot.java
@@ -23,6 +23,8 @@ import javafx.util.Duration;
  */
 public class AmakPlot {
 	
+	MainWindow mainWindow = null;
+	
 	public enum ChartType {LINE, BAR;}
 	
 	/* STATIC */
@@ -33,8 +35,13 @@ public class AmakPlot {
 	 */
 	public static boolean useSamplingRenderer = false;
 	
-	public static void add(AmakPlot chart) {
-		MainWindow.addTabbedPanel(chart.name, new ChartViewer(chart.chart));
+	public void add(MainWindow window, AmakPlot chart) {
+		if(mainWindow == null) {
+			mainWindow = window;
+		}
+		mainWindow.addTabbedPanel(chart.name, new ChartViewer(chart.chart));
+		
+		
 	}
 	/* ----- */
 	
@@ -55,7 +62,8 @@ public class AmakPlot {
 	 * @param yAxisLabel label for the y (vertical) axis
 	 * @param autoAdd automatically make an {@link AmakPlot#add(AmakPlot)} call ?
 	 */
-	public AmakPlot(String name, ChartType chartType, String xAxisLabel, String yAxisLabel, boolean autoAdd) {
+	public AmakPlot(MainWindow window, String name, ChartType chartType, String xAxisLabel, String yAxisLabel, boolean autoAdd) {
+		this.mainWindow = window;
 		this.name = name;
 		seriesCollection = new XYSeriesCollection();
 		switch (chartType) {
@@ -79,8 +87,10 @@ public class AmakPlot {
 		chart.setAntiAlias(false);
 		chart.getPlot().setBackgroundPaint(Color.WHITE);
 		if(autoAdd) {
-			add(this);
+			add(mainWindow, this);
 		}
+		
+		
 	}
 	
 	/**
@@ -90,8 +100,9 @@ public class AmakPlot {
 	 * @param xAxisLabel label for the x (horizontal) axis 
 	 * @param yAxisLabel label for the y (vertical) axis
 	 */
-	public AmakPlot(String name, ChartType chartType, String xAxisLabel, String yAxisLabel) {
-		this(name, chartType, xAxisLabel, yAxisLabel, true);
+	public AmakPlot(MainWindow window, String name, ChartType chartType, String xAxisLabel, String yAxisLabel) {
+		this(window, name, chartType, xAxisLabel, yAxisLabel, true);
+		mainWindow = window;
 	}
 	
 	
@@ -102,11 +113,12 @@ public class AmakPlot {
 	 * @param chart the {@link JFreeChart} using a {@link XYSeriesCollection} for dataset.
 	 * @param autoAdd automatically make an {@link AmakPlot#add(AmakPlot)} call ?
 	 */
-	public AmakPlot(String name, JFreeChart chart, boolean autoAdd) {
+	public AmakPlot(MainWindow window, String name, JFreeChart chart, boolean autoAdd) {
+		mainWindow = window;
 		this.name = name;
 		this.seriesCollection = (XYSeriesCollection) chart.getXYPlot().getDataset();
 		this.chart = chart;
-		add(this);
+		add(mainWindow, this);
 	}
 	
 	/**
@@ -115,8 +127,10 @@ public class AmakPlot {
 	 * @param name the name of the chart, used as the tab name.
 	 * @param chart the {@link JFreeChart} using a {@link XYSeriesCollection} for dataset.
 	 */
-	public AmakPlot(String name, JFreeChart chart) {
-		this(name, chart, true);
+	public AmakPlot(MainWindow window, String name, JFreeChart chart) {
+		this(window, name, chart, true);
+		mainWindow = window;
+		
 	}
 	
 	public String getName() {
diff --git a/AMAKFX/src/fr/irit/smac/amak/ui/AmasWindow.java b/AMAKFX/src/fr/irit/smac/amak/ui/AmasWindow.java
new file mode 100644
index 0000000000000000000000000000000000000000..3cc1763056f1afe7fb0748a806c94b02e4921643
--- /dev/null
+++ b/AMAKFX/src/fr/irit/smac/amak/ui/AmasWindow.java
@@ -0,0 +1,266 @@
+package fr.irit.smac.amak.ui;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.locks.ReentrantLock;
+
+import javax.management.InstanceAlreadyExistsException;
+
+import fr.irit.smac.amak.Information;
+import fr.irit.smac.amak.tools.RunLaterHelper;
+import javafx.application.Application;
+import javafx.application.Platform;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.scene.Node;
+import javafx.scene.Scene;
+import javafx.scene.control.Menu;
+import javafx.scene.control.MenuBar;
+import javafx.scene.control.MenuItem;
+import javafx.scene.control.Tab;
+import javafx.scene.control.TabPane;
+import javafx.scene.control.ToolBar;
+import javafx.scene.image.Image;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.Priority;
+import javafx.scene.layout.VBox;
+import javafx.stage.Stage;
+import javafx.stage.WindowEvent;
+
+/**
+ *
+ *
+ */
+public class AmasWindow  {
+	/**
+	 * The window itself
+	 */
+	public Stage stage;
+	/**
+	 * The panel which contains the toolbar
+	 */
+	public ToolBar toolbarPanel;
+
+	/**
+	 * The main pane of AMAK
+	 */
+	public BorderPane organizationPane;
+	
+	/**
+	 * The menu bar of the window
+	 */
+	public MenuBar menuBar;
+	/**
+	 * The menus
+	 */
+	public HashMap<String, Menu> menus = new HashMap<String, Menu>();
+	/**
+	 * The panel in which panels with tab can be added
+	 */
+	public TabPane tabbedPanel;
+
+	/**
+	 * Lock present to avoid the creation of a MainWindow while another is creating
+	 */
+	protected static ReentrantLock instanceLock = new ReentrantLock();
+	protected static Object startEnded = new Object();
+
+	
+	private boolean applicationLaunched = false;
+	
+	/**
+	 * Create the frame.
+	 * 
+	 * @throws InstanceAlreadyExistsException
+	 *             if the MainWindow has already been instantiated. This constructor
+	 *             should be used by the Application of JavaFX only.
+	 */
+	public AmasWindow() {
+
+			
+			
+			
+
+	
+	}
+
+	
+	
+	
+	
+
+	public void start(Stage primaryStage) throws Exception {
+		synchronized (startEnded) {
+			VBox root = new VBox();
+			
+			// Creation of the menu bar (Top)
+			menuBar = new MenuBar();
+			root.getChildren().add(menuBar);
+			
+			// Border organization
+			organizationPane = new BorderPane();
+			organizationPane.setMinSize(200, 200); //that way we avoid 0 size, which can cause problems
+			root.getChildren().add(organizationPane);
+			VBox.setVgrow(organizationPane, Priority.ALWAYS);
+			
+			// Creation of scene
+			primaryStage.setTitle("AMAK");
+			Scene scene = new Scene(root, 450, 300);
+			stage = primaryStage;
+			stage.setScene(scene);
+			stage.setOnCloseRequest(new EventHandler<WindowEvent>() {
+				@Override
+				public void handle(WindowEvent event) {
+					Platform.exit();
+				}
+			});
+	
+			// Creation of the toolbar (Bottom)
+			toolbarPanel = new ToolBar();
+			organizationPane.setBottom(toolbarPanel);
+	
+			// Creation of the right part of the split pane (Center Right)
+			tabbedPanel = new TabPane();
+			organizationPane.setCenter(tabbedPanel);
+	
+			// Creation of the close menu item
+			MenuItem menuItem = new MenuItem("Close");
+			menuItem.setOnAction(new EventHandler<ActionEvent>() {
+				@Override
+				public void handle(ActionEvent event) {
+					System.exit(0);
+				}
+			});
+			addToMenu("Options", menuItem);
+	
+			menuBar.getMenus().add(new Menu("AMAKFX v" + Information.VERSION));
+	
+			stage.show();
+			
+			startEnded.notify();
+		}
+	}
+
+	/**
+	 * Add an action when the JavaFX app close.
+	 * 
+	 * @param onClose
+	 *            The action to be executed when the window is closed
+	 */
+	public static void addOnCloseAction(Runnable onClose) {
+		Runtime.getRuntime().addShutdownHook(new Thread() {
+		    public void run() { onClose.run(); }
+		});
+	}
+	
+
+	public void stop() throws Exception {
+
+		System.exit(0);
+	}
+
+	/**
+	 * Change the icon of the window
+	 * 
+	 * @param filename
+	 *            The filename of the icon
+	 */
+	public void setWindowIcon(String filename) {
+
+		RunLaterHelper.runLater(() -> stage.getIcons().add(new Image(filename)));
+	}
+
+	/**
+	 * Change the title of the main window
+	 * 
+	 * @param title
+	 *            The new title
+	 */
+	public void setWindowTitle(String title) {
+		System.out.println("setWindowTitle");
+		RunLaterHelper.runLater(() -> stage.setTitle(title));
+	}
+	
+	/**
+	 * Add a button in the menu options
+	 * 
+	 * @param title
+	 *            The title of the button
+	 * @param event
+	 *            The action to be executed
+	 */
+	public void addOptionsItem(String title, EventHandler<ActionEvent> event) {
+		MenuItem menuItem = new MenuItem(title);
+		menuItem.setOnAction(event);
+
+		RunLaterHelper.runLater(() -> addToMenu("Options", menuItem));
+	}
+
+	/**
+	 * Add a tool in the toolbar.
+	 * 
+	 * @param tool
+	 */
+	public  void addToolbar(Node tool) {
+		RunLaterHelper.runLater(() -> toolbarPanel.getItems().add(tool));
+	}
+
+	/**
+	 * Set a panel to the left
+	 * 
+	 * @param panel
+	 *            The panel
+	 */
+	public void setLeftPanel(Node panel) {
+		RunLaterHelper.runLater(() -> organizationPane.setLeft(panel));
+	}
+
+	/**
+	 * Set a panel to the right
+	 * 
+	 * @param panel
+	 *            The panel
+	 */
+	public void setRightPanel(Node panel) {
+		RunLaterHelper.runLater(() -> organizationPane.setRight(panel));
+	}
+
+	
+	
+
+	/**
+	 * Add a panel with a tab
+	 * 
+	 * @param title
+	 *            The title of the tab
+	 * @param panel
+	 *            The panel to add
+	 */
+	public void addTabbedPanel(String title, Node panel) {
+		Tab t = new DraggableTab(title, panel);
+		RunLaterHelper.runLater(() -> tabbedPanel.getTabs().add(t));
+	}
+	
+	/**
+	 * Add a {@link MenuItem} to a {@link Menu}. May create the menu and add it to the menu bar.
+	 * @param menuName the name of the menu where the item will be added.
+	 * @param item the item to be added.
+	 */
+	public void addToMenu(String menuName, MenuItem item) {
+//		System.out.println("addToMenu");
+//		instance();
+		if( !this.menus.containsKey(menuName) ) {
+			Menu m = new Menu(menuName);
+			this.menus.put(menuName,m);
+			RunLaterHelper.runLater(() -> this.menuBar.getMenus().add(m));
+		}
+		RunLaterHelper.runLater(() -> this.menus.get(menuName).getItems().add(item));
+	}
+
+
+
+
+
+
+}
\ No newline at end of file
diff --git a/AMAKFX/src/fr/irit/smac/amak/ui/VUI.java b/AMAKFX/src/fr/irit/smac/amak/ui/VUI.java
index 136cb472ac33fbffb9e2f7c7ddda551fe2384d81..c6b8c50f0d03cf8885a6da1da711d0d429be9cb8 100644
--- a/AMAKFX/src/fr/irit/smac/amak/ui/VUI.java
+++ b/AMAKFX/src/fr/irit/smac/amak/ui/VUI.java
@@ -1,577 +1,577 @@
-package fr.irit.smac.amak.ui;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.locks.ReentrantLock;
-
-import fr.irit.smac.amak.tools.RunLaterHelper;
-import fr.irit.smac.amak.ui.drawables.Drawable;
-import fr.irit.smac.amak.ui.drawables.DrawableImage;
-import fr.irit.smac.amak.ui.drawables.DrawablePoint;
-import fr.irit.smac.amak.ui.drawables.DrawableRectangle;
-import fr.irit.smac.amak.ui.drawables.DrawableString;
-import javafx.event.ActionEvent;
-import javafx.event.EventHandler;
-import javafx.geometry.Insets;
-import javafx.scene.control.Button;
-import javafx.scene.control.Label;
-import javafx.scene.control.ToolBar;
-import javafx.scene.control.Tooltip;
-import javafx.scene.input.MouseEvent;
-import javafx.scene.input.ScrollEvent;
-import javafx.scene.layout.Background;
-import javafx.scene.layout.BackgroundFill;
-import javafx.scene.layout.BorderPane;
-import javafx.scene.layout.CornerRadii;
-import javafx.scene.layout.Pane;
-import javafx.scene.paint.Color;
-import javafx.scene.shape.Rectangle;
-import javafx.scene.text.TextAlignment;
-
-/**
- * 
- * Vectorial UI: This class allows to create dynamic rendering with zoom and
- * move capacities
- * 
- * @author of original version (the Swing one) perles
- *
- */
-public class VUI {
-	/**
-	 * The toolbar of the VUI.
-	 */
-	public ToolBar toolbar;
-	
-	/**
-	 * The VUI explorer.
-	 * @see VuiExplorer
-	 */
-	private VuiExplorer vuiExplorer;
-	
-	/**
-	 * List of objects currently being drawn by the VUI
-	 */
-	private List<Drawable> drawables = new LinkedList<>();
-	/**
-	 * Lock to avoid concurrent modification on the list {@link #drawables}
-	 */
-	private ReentrantLock drawablesLock = new ReentrantLock();
-
-	/**
-	 * A static map to facilitate access to different instances of VUI
-	 */
-	private static Map<String, VUI> instances = new HashMap<>();
-
-	/**
-	 * The horizontal offset of the drawing zone. Used to allow the user to move the
-	 * view.
-	 */
-	private double worldOffsetX;
-
-	/**
-	 * The vertical offset of the drawing zone. Used to allow the user to move the
-	 * view.
-	 */
-	private double worldOffsetY;
-
-	/**
-	 * The last horizontal position of the mouse when dragging
-	 */
-	protected Double lastDragX;
-
-	/**
-	 * The last vertical position of the mouse when dragging
-	 */
-	protected Double lastDragY;
-
-	/**
-	 * The main panel of the VUI
-	 */
-	private BorderPane panel;
-
-	/**
-	 * The canvas on which all is drawn
-	 */
-	private Pane canvas;
-
-	/**
-	 * Label aiming at showing information about the VUI (zoom and offset)
-	 */
-	private Label statusLabel;
-
-	/**
-	 * The default value of the {@link #zoom}
-	 */
-	private double defaultZoom = 100;
-	/**
-	 * The default horizontal position of the view
-	 */
-	private double defaultWorldCenterX = 0;
-	/**
-	 * The default vertical position of the view
-	 */
-	private double defaultWorldCenterY = 0;
-	/**
-	 * The value of the zoom. 100 means 1/1 scale
-	 */
-	protected double zoom = defaultZoom;
-
-	/**
-	 * The horizontal position of the view
-	 */
-	private double worldCenterX = defaultWorldCenterX;
-
-	/**
-	 * The vertical position of the view
-	 */
-	private double worldCenterY = defaultWorldCenterY;
-
-	/**
-	 * Used to be sure that only one thread at the same time create a VUI
-	 */
-	private static ReentrantLock instanceLock = new ReentrantLock();
-
-	/**
-	 * Get the default VUI
-	 * 
-	 * @return the default VUI
-	 */
-	public static VUI get() {
-		if(!instances.containsKey("Default"))
-			MainWindow.addTabbedPanel("Default VUI", get("Default").getPanel());
-		return get("Default");
-	}
-
-	/**
-	 * Create or get a VUI.<br/>
-	 * You have add its panel to the MainWindow yourself.
-	 * 
-	 * @param id
-	 *            The unique id of the VUI
-	 * @return The VUI with id "id"
-	 */
-	public static VUI get(String id) {
-		instanceLock.lock();
-		if (!instances.containsKey(id)) {
-			VUI value = new VUI(id);
-			instances.put(id, value);
-			instanceLock.unlock();
-			return value;
-		}
-		instanceLock.unlock();
-		return instances.get(id);
-	}
-
-	/**
-	 * Constructor of the VUI. This one is private as it can only be created through
-	 * static method.
-	 * 
-	 * @param title
-	 *            The title used for the vui
-	 */
-	private VUI(String title) {
-		Semaphore done = new Semaphore(0);
-		RunLaterHelper.runLater(() -> {
-			panel = new BorderPane();
-
-			toolbar = new ToolBar();
-			statusLabel = new Label("status");
-			statusLabel.setTextAlignment(TextAlignment.LEFT);
-			toolbar.getItems().add(statusLabel);
-			panel.setBottom(toolbar);
-
-			Button resetButton = new Button("Reset");
-			resetButton.setOnAction(new EventHandler<ActionEvent>() {
-				@Override
-				public void handle(ActionEvent event) {
-					zoom = defaultZoom;
-					worldCenterX = defaultWorldCenterX;
-					worldCenterY = defaultWorldCenterY;
-					updateCanvas();
-				}
-			});
-			toolbar.getItems().add(resetButton);
-
-			canvas = new Pane();
-			canvas.setBackground(new Background(new BackgroundFill(Color.WHITE, CornerRadii.EMPTY, Insets.EMPTY)));
-			// clip the canvas (avoid drawing outside of it)
-			Rectangle clip = new Rectangle(0, 0, 0, 0);
-			clip.widthProperty().bind(canvas.widthProperty());
-			clip.heightProperty().bind(canvas.heightProperty());
-			canvas.setClip(clip);
-			
-			canvas.setOnMousePressed(new EventHandler<MouseEvent>() {
-				@Override
-				public void handle(MouseEvent event) {
-					lastDragX = event.getX();
-					lastDragY = event.getY();
-				}
-			});
-			canvas.setOnMouseExited(new EventHandler<MouseEvent>() {
-				@Override
-				public void handle(MouseEvent event) {
-					lastDragX = null;
-					lastDragY = null;
-				}
-			});
-			canvas.setOnMouseDragged(new EventHandler<MouseEvent>() {
-				@Override
-				public void handle(MouseEvent event) {
-					try {
-						double transX = screenToWorldDistance(event.getX() - lastDragX);
-						double transY = screenToWorldDistance(event.getY() - lastDragY);
-						worldCenterX += transX;
-						worldCenterY += transY;
-						worldOffsetX += transX;
-						worldOffsetY += transY;
-						lastDragX = event.getX();
-						lastDragY = event.getY();
-						updateCanvas();
-					} catch (Exception ez) {
-						// Catch exception occurring when mouse is out of the canvas
-					}
-				}
-			});
-
-			canvas.setOnScroll(new EventHandler<ScrollEvent>() {
-				@Override
-				public void handle(ScrollEvent event) {
-					double wdx = screenToWorldDistance(canvas.getWidth() / 2 - event.getX());
-					double wdy = screenToWorldDistance(canvas.getHeight() / 2 - event.getY());
-					zoom += event.getDeltaY() / event.getMultiplierY() * 10;
-					if (zoom < 10)
-						zoom = 10;
-
-					double wdx2 = screenToWorldDistance(canvas.getWidth() / 2 - event.getX());
-					double wdy2 = screenToWorldDistance(canvas.getHeight() / 2 - event.getY());
-					worldCenterX -= wdx2 - wdx;
-					worldCenterY -= wdy2 - wdy;
-					updateCanvas();
-				}
-			});
-
-			panel.setCenter(canvas);
-			
-			//add VuiExplorer
-			vuiExplorer = new VuiExplorer(this);
-			panel.setLeft(vuiExplorer);
-			Button veButton = new Button("VUI explorer");
-			veButton.setOnAction(new EventHandler<ActionEvent>() {
-				@Override
-				public void handle(ActionEvent event) {
-					panel.setLeft(vuiExplorer);
-				}
-			});
-			veButton.setTooltip(new Tooltip("Show the VUI explorer if it was hidden."));
-			toolbar.getItems().add(veButton);
-			
-			done.release();
-		});
-		try {
-			done.acquire();
-		} catch (InterruptedException e) {
-			System.err.println("Failed to make sure that the VUI is correctly initialized.");
-			e.printStackTrace();
-		}
-	}
-
-	/**
-	 * Convert a distance in the world to its equivalent on the screen
-	 * 
-	 * @param d
-	 *            the in world distance
-	 * @return the on screen distance
-	 */
-	public double worldToScreenDistance(double d) {
-		return d * getZoomFactor();
-	}
-
-	/**
-	 * Convert a distance on the screen to its equivalent in the world
-	 * 
-	 * @param d
-	 *            the on screen distance
-	 * @return the in world distance
-	 */
-	public double screenToWorldDistance(double d) {
-		return d / getZoomFactor();
-	}
-
-	/**
-	 * Convert a X in the world to its equivalent on the screen
-	 * 
-	 * @param x
-	 *            the X in world
-	 *
-	 * @return the X on screen distance
-	 */
-	public double worldToScreenX(double x) {
-		return (x + getWorldOffsetX()) * getZoomFactor();
-	}
-
-	/**
-	 * A value that must be multiplied to scale objects
-	 * 
-	 * @return the zoom factor
-	 */
-	public double getZoomFactor() {
-		return zoom / 100;
-	}
-
-	/**
-	 * Convert a Y in the world to its equivalent on the screen
-	 * 
-	 * @param y
-	 *            the Y in world
-	 *
-	 * @return the Y on screen distance
-	 */
-	public double worldToScreenY(double y) {
-		return (-y + getWorldOffsetY()) * getZoomFactor();
-	}
-
-	/**
-	 * Convert a X on the screen to its equivalent in the world
-	 * 
-	 * @param x
-	 *            the X on screen
-	 *
-	 * @return the X in the world distance
-	 */
-	public double screenToWorldX(double x) {
-		return x / getZoomFactor() - getWorldOffsetX();
-	}
-
-	/**
-	 * Convert a Y on the screen to its equivalent in the world
-	 * 
-	 * @param y
-	 *            the Y on screen
-	 *
-	 * @return the Y in the world distance
-	 */
-	public double screenToWorldY(double y) {
-		return -y / getZoomFactor() + getWorldOffsetY();
-	}
-
-	/**
-	 * Add a drawable to the VUI.
-	 * 
-	 * @param d
-	 *            the new drawable
-	 */
-	public void add(Drawable d) {
-		d.setVUI(this);
-		RunLaterHelper.runLater(()-> canvas.getChildren().add(d.getNode()));
-		drawablesLock.lock();
-		drawables.add(d);
-		drawablesLock.unlock();
-		updateCanvas();
-	}
-	
-	/**
-	 * Remove a drawable from the VUI.
-	 * 
-	 * @param d
-	 *            the new drawable
-	 */
-	public void remove(Drawable d) {
-		drawablesLock.lock();
-		drawables.remove(d);
-		drawablesLock.unlock();
-		RunLaterHelper.runLater(()-> canvas.getChildren().remove(d.getNode()));
-		updateCanvas();
-	}
-	
-	/**
-	 * Remove all drawables from the VUI.
-	 */
-	public void clear() {
-		drawablesLock.lock();
-		drawables.clear();
-		RunLaterHelper.runLater(()->canvas.getChildren().clear());
-		drawablesLock.unlock();
-	}
-
-	/**
-	 * Refresh the canvas
-	 */
-	public void updateCanvas() {
-		final double w = canvas.getWidth();
-		final double h = canvas.getHeight();
-
-		setWorldOffsetX(worldCenterX + screenToWorldDistance(w / 2));
-		setWorldOffsetY(worldCenterY + screenToWorldDistance(h / 2));
-
-		drawablesLock.lock();
-		Collections.sort(drawables, (o1, o2) -> o1.getLayer() - o2.getLayer());
-		for (Drawable d : drawables)
-			RunLaterHelper.runLater(()-> d.onDraw());
-		drawablesLock.unlock();
-
-		RunLaterHelper.runLater(() -> {
-			statusLabel.setText(String.format("Zoom: %.2f Center: (%.2f,%.2f)", zoom, worldCenterX, worldCenterY));
-		});
-		
-		RunLaterHelper.runLater(()-> vuiExplorer.update(true));
-	}
-
-	/**
-	 * Get the width of the canvas
-	 * 
-	 * @return the canvas width
-	 */
-	public double getCanvasWidth() {
-		return canvas.getWidth();
-	}
-
-	/**
-	 * Get the height of the canvas
-	 * 
-	 * @return the canvas height
-	 */
-	public double getCanvasHeight() {
-		return canvas.getHeight();
-	}
-
-	/**
-	 * Get the value that must be added to the X coordinate of in world object
-	 * 
-	 * @return the X offset
-	 */
-	public double getWorldOffsetX() {
-		return worldOffsetX;
-	}
-
-	/**
-	 * Set the value that must be added to the X coordinate of in world object
-	 * 
-	 * @param offsetX
-	 *            the X offset
-	 */
-	public void setWorldOffsetX(double offsetX) {
-		this.worldOffsetX = offsetX;
-	}
-
-	/**
-	 * Get the value that must be added to the Y coordinate of in world object
-	 * 
-	 * @return the Y offset
-	 */
-	public double getWorldOffsetY() {
-		return worldOffsetY;
-	}
-
-	/**
-	 * Set the value that must be added to the Y coordinate of in world object
-	 * 
-	 * @param offsetY
-	 *            the Y offset
-	 */
-	public void setWorldOffsetY(double offsetY) {
-		this.worldOffsetY = offsetY;
-	}
-
-	/**
-	 * Create a point and start rendering it
-	 * 
-	 * @param dx
-	 *            the x coordinate
-	 * @param dy
-	 *            the y coordinate
-	 * @return the point object
-	 */
-	public DrawablePoint createAndAddPoint(double dx, double dy) {
-		DrawablePoint drawablePoint = new DrawablePoint(dx, dy);
-		add(drawablePoint);
-		return drawablePoint;
-	}
-
-	/**
-	 * Create a rectangle and start rendering it
-	 * 
-	 * @param x
-	 *            the x coordinate
-	 * @param y
-	 *            the y coordinate
-	 * @param w
-	 *            the width
-	 * @param h
-	 *            the height
-	 * @return the rectangle object
-	 */
-	public DrawableRectangle createAndAddRectangle(double x, double y, double w, double h) {
-		DrawableRectangle d = new DrawableRectangle(x, y, w, h);
-		add(d);
-		return d;
-	}
-
-	/**
-	 * Set the default configuration of the view
-	 * 
-	 * @param zoom
-	 *            the initial zoom value
-	 * @param worldCenterX
-	 *            the initial X center value
-	 * @param worldCenterY
-	 *            the initial Y center value
-	 */
-	public void setDefaultView(double zoom, double worldCenterX, double worldCenterY) {
-		this.zoom = zoom;
-		this.worldCenterX = worldCenterX;
-		this.worldCenterY = worldCenterY;
-		this.defaultZoom = zoom;
-		this.defaultWorldCenterX = worldCenterX;
-		this.defaultWorldCenterY = worldCenterY;
-	}
-
-	/**
-	 * Create an image and start rendering it
-	 * 
-	 * @param dx
-	 *            the x coordinate
-	 * @param dy
-	 *            the y coordinate
-	 * @param filename
-	 *            the filename of the image
-	 * @return the created image
-	 */
-	public DrawableImage createAndAddImage(double dx, double dy, String filename) {
-		DrawableImage image = new DrawableImage(dx, dy, filename);
-		add(image);
-		return image;
-	}
-
-	/**
-	 * Create a string and start rendering it
-	 * 
-	 * @param dx
-	 *            the x coordinate
-	 * @param dy
-	 *            the y coordinate
-	 * @param text
-	 *            the text to display
-	 * @return the created string
-	 */
-	public DrawableString createAndAddString(int dx, int dy, String text) {
-		DrawableString ds = new DrawableString(dx, dy, text);
-		add(ds);
-		return ds;
-	}
-
-	public Pane getCanvas() {
-		return canvas;
-	}
-	
-	public BorderPane getPanel() {
-		return panel;
-	}
-	
-	public List<Drawable> getDrawables() {
-		return drawables;
-	}
-}
+package fr.irit.smac.amak.ui;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.locks.ReentrantLock;
+
+import fr.irit.smac.amak.tools.RunLaterHelper;
+import fr.irit.smac.amak.ui.drawables.Drawable;
+import fr.irit.smac.amak.ui.drawables.DrawableImage;
+import fr.irit.smac.amak.ui.drawables.DrawablePoint;
+import fr.irit.smac.amak.ui.drawables.DrawableRectangle;
+import fr.irit.smac.amak.ui.drawables.DrawableString;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.geometry.Insets;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.control.ToolBar;
+import javafx.scene.control.Tooltip;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.input.ScrollEvent;
+import javafx.scene.layout.Background;
+import javafx.scene.layout.BackgroundFill;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.CornerRadii;
+import javafx.scene.layout.Pane;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Rectangle;
+import javafx.scene.text.TextAlignment;
+
+/**
+ * 
+ * Vectorial UI: This class allows to create dynamic rendering with zoom and
+ * move capacities
+ * 
+ * @author of original version (the Swing one) perles
+ *
+ */
+public class VUI {
+	/**
+	 * The toolbar of the VUI.
+	 */
+	public ToolBar toolbar;
+	
+	/**
+	 * The VUI explorer.
+	 * @see VuiExplorer
+	 */
+	private VuiExplorer vuiExplorer;
+	
+	/**
+	 * List of objects currently being drawn by the VUI
+	 */
+	private List<Drawable> drawables = new LinkedList<>();
+	/**
+	 * Lock to avoid concurrent modification on the list {@link #drawables}
+	 */
+	private ReentrantLock drawablesLock = new ReentrantLock();
+
+	/**
+	 * A static map to facilitate access to different instances of VUI
+	 */
+	private static Map<String, VUI> instances = new HashMap<>();
+
+	/**
+	 * The horizontal offset of the drawing zone. Used to allow the user to move the
+	 * view.
+	 */
+	private double worldOffsetX;
+
+	/**
+	 * The vertical offset of the drawing zone. Used to allow the user to move the
+	 * view.
+	 */
+	private double worldOffsetY;
+
+	/**
+	 * The last horizontal position of the mouse when dragging
+	 */
+	protected Double lastDragX;
+
+	/**
+	 * The last vertical position of the mouse when dragging
+	 */
+	protected Double lastDragY;
+
+	/**
+	 * The main panel of the VUI
+	 */
+	private BorderPane panel;
+
+	/**
+	 * The canvas on which all is drawn
+	 */
+	private Pane canvas;
+
+	/**
+	 * Label aiming at showing information about the VUI (zoom and offset)
+	 */
+	private Label statusLabel;
+
+	/**
+	 * The default value of the {@link #zoom}
+	 */
+	private double defaultZoom = 100;
+	/**
+	 * The default horizontal position of the view
+	 */
+	private double defaultWorldCenterX = 0;
+	/**
+	 * The default vertical position of the view
+	 */
+	private double defaultWorldCenterY = 0;
+	/**
+	 * The value of the zoom. 100 means 1/1 scale
+	 */
+	protected double zoom = defaultZoom;
+
+	/**
+	 * The horizontal position of the view
+	 */
+	private double worldCenterX = defaultWorldCenterX;
+
+	/**
+	 * The vertical position of the view
+	 */
+	private double worldCenterY = defaultWorldCenterY;
+
+	/**
+	 * Used to be sure that only one thread at the same time create a VUI
+	 */
+	private static ReentrantLock instanceLock = new ReentrantLock();
+
+	/**
+	 * Get the default VUI
+	 * 
+	 * @return the default VUI
+	 */
+	public static VUI get(AmasWindow amasWindow) {
+		if(!instances.containsKey("Default"))
+			amasWindow.addTabbedPanel("Default VUI", get("Default").getPanel());
+		return get("Default");
+	}
+
+	/**
+	 * Create or get a VUI.<br/>
+	 * You have add its panel to the MainWindow yourself.
+	 * 
+	 * @param id
+	 *            The unique id of the VUI
+	 * @return The VUI with id "id"
+	 */
+	public static VUI get(String id) {
+		instanceLock.lock();
+		if (!instances.containsKey(id)) {
+			VUI value = new VUI(id);
+			instances.put(id, value);
+			instanceLock.unlock();
+			return value;
+		}
+		instanceLock.unlock();
+		return instances.get(id);
+	}
+
+	/**
+	 * Constructor of the VUI. This one is private as it can only be created through
+	 * static method.
+	 * 
+	 * @param title
+	 *            The title used for the vui
+	 */
+	private VUI(String title) {
+		Semaphore done = new Semaphore(0);
+		RunLaterHelper.runLater(() -> {
+			panel = new BorderPane();
+
+			toolbar = new ToolBar();
+			statusLabel = new Label("status");
+			statusLabel.setTextAlignment(TextAlignment.LEFT);
+			toolbar.getItems().add(statusLabel);
+			panel.setBottom(toolbar);
+
+			Button resetButton = new Button("Reset");
+			resetButton.setOnAction(new EventHandler<ActionEvent>() {
+				@Override
+				public void handle(ActionEvent event) {
+					zoom = defaultZoom;
+					worldCenterX = defaultWorldCenterX;
+					worldCenterY = defaultWorldCenterY;
+					updateCanvas();
+				}
+			});
+			toolbar.getItems().add(resetButton);
+
+			canvas = new Pane();
+			canvas.setBackground(new Background(new BackgroundFill(Color.WHITE, CornerRadii.EMPTY, Insets.EMPTY)));
+			// clip the canvas (avoid drawing outside of it)
+			Rectangle clip = new Rectangle(0, 0, 0, 0);
+			clip.widthProperty().bind(canvas.widthProperty());
+			clip.heightProperty().bind(canvas.heightProperty());
+			canvas.setClip(clip);
+			
+			canvas.setOnMousePressed(new EventHandler<MouseEvent>() {
+				@Override
+				public void handle(MouseEvent event) {
+					lastDragX = event.getX();
+					lastDragY = event.getY();
+				}
+			});
+			canvas.setOnMouseExited(new EventHandler<MouseEvent>() {
+				@Override
+				public void handle(MouseEvent event) {
+					lastDragX = null;
+					lastDragY = null;
+				}
+			});
+			canvas.setOnMouseDragged(new EventHandler<MouseEvent>() {
+				@Override
+				public void handle(MouseEvent event) {
+					try {
+						double transX = screenToWorldDistance(event.getX() - lastDragX);
+						double transY = screenToWorldDistance(event.getY() - lastDragY);
+						worldCenterX += transX;
+						worldCenterY += transY;
+						worldOffsetX += transX;
+						worldOffsetY += transY;
+						lastDragX = event.getX();
+						lastDragY = event.getY();
+						updateCanvas();
+					} catch (Exception ez) {
+						// Catch exception occurring when mouse is out of the canvas
+					}
+				}
+			});
+
+			canvas.setOnScroll(new EventHandler<ScrollEvent>() {
+				@Override
+				public void handle(ScrollEvent event) {
+					double wdx = screenToWorldDistance(canvas.getWidth() / 2 - event.getX());
+					double wdy = screenToWorldDistance(canvas.getHeight() / 2 - event.getY());
+					zoom += event.getDeltaY() / event.getMultiplierY() * 10;
+					if (zoom < 10)
+						zoom = 10;
+
+					double wdx2 = screenToWorldDistance(canvas.getWidth() / 2 - event.getX());
+					double wdy2 = screenToWorldDistance(canvas.getHeight() / 2 - event.getY());
+					worldCenterX -= wdx2 - wdx;
+					worldCenterY -= wdy2 - wdy;
+					updateCanvas();
+				}
+			});
+
+			panel.setCenter(canvas);
+			
+			//add VuiExplorer
+			vuiExplorer = new VuiExplorer(this);
+			panel.setLeft(vuiExplorer);
+			Button veButton = new Button("VUI explorer");
+			veButton.setOnAction(new EventHandler<ActionEvent>() {
+				@Override
+				public void handle(ActionEvent event) {
+					panel.setLeft(vuiExplorer);
+				}
+			});
+			veButton.setTooltip(new Tooltip("Show the VUI explorer if it was hidden."));
+			toolbar.getItems().add(veButton);
+			
+			done.release();
+		});
+		try {
+			done.acquire();
+		} catch (InterruptedException e) {
+			System.err.println("Failed to make sure that the VUI is correctly initialized.");
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * Convert a distance in the world to its equivalent on the screen
+	 * 
+	 * @param d
+	 *            the in world distance
+	 * @return the on screen distance
+	 */
+	public double worldToScreenDistance(double d) {
+		return d * getZoomFactor();
+	}
+
+	/**
+	 * Convert a distance on the screen to its equivalent in the world
+	 * 
+	 * @param d
+	 *            the on screen distance
+	 * @return the in world distance
+	 */
+	public double screenToWorldDistance(double d) {
+		return d / getZoomFactor();
+	}
+
+	/**
+	 * Convert a X in the world to its equivalent on the screen
+	 * 
+	 * @param x
+	 *            the X in world
+	 *
+	 * @return the X on screen distance
+	 */
+	public double worldToScreenX(double x) {
+		return (x + getWorldOffsetX()) * getZoomFactor();
+	}
+
+	/**
+	 * A value that must be multiplied to scale objects
+	 * 
+	 * @return the zoom factor
+	 */
+	public double getZoomFactor() {
+		return zoom / 100;
+	}
+
+	/**
+	 * Convert a Y in the world to its equivalent on the screen
+	 * 
+	 * @param y
+	 *            the Y in world
+	 *
+	 * @return the Y on screen distance
+	 */
+	public double worldToScreenY(double y) {
+		return (-y + getWorldOffsetY()) * getZoomFactor();
+	}
+
+	/**
+	 * Convert a X on the screen to its equivalent in the world
+	 * 
+	 * @param x
+	 *            the X on screen
+	 *
+	 * @return the X in the world distance
+	 */
+	public double screenToWorldX(double x) {
+		return x / getZoomFactor() - getWorldOffsetX();
+	}
+
+	/**
+	 * Convert a Y on the screen to its equivalent in the world
+	 * 
+	 * @param y
+	 *            the Y on screen
+	 *
+	 * @return the Y in the world distance
+	 */
+	public double screenToWorldY(double y) {
+		return -y / getZoomFactor() + getWorldOffsetY();
+	}
+
+	/**
+	 * Add a drawable to the VUI.
+	 * 
+	 * @param d
+	 *            the new drawable
+	 */
+	public void add(Drawable d) {
+		d.setVUI(this);
+		RunLaterHelper.runLater(()-> canvas.getChildren().add(d.getNode()));
+		drawablesLock.lock();
+		drawables.add(d);
+		drawablesLock.unlock();
+		updateCanvas();
+	}
+	
+	/**
+	 * Remove a drawable from the VUI.
+	 * 
+	 * @param d
+	 *            the new drawable
+	 */
+	public void remove(Drawable d) {
+		drawablesLock.lock();
+		drawables.remove(d);
+		drawablesLock.unlock();
+		RunLaterHelper.runLater(()-> canvas.getChildren().remove(d.getNode()));
+		updateCanvas();
+	}
+	
+	/**
+	 * Remove all drawables from the VUI.
+	 */
+	public void clear() {
+		drawablesLock.lock();
+		drawables.clear();
+		RunLaterHelper.runLater(()->canvas.getChildren().clear());
+		drawablesLock.unlock();
+	}
+
+	/**
+	 * Refresh the canvas
+	 */
+	public void updateCanvas() {
+		final double w = canvas.getWidth();
+		final double h = canvas.getHeight();
+
+		setWorldOffsetX(worldCenterX + screenToWorldDistance(w / 2));
+		setWorldOffsetY(worldCenterY + screenToWorldDistance(h / 2));
+
+		drawablesLock.lock();
+		Collections.sort(drawables, (o1, o2) -> o1.getLayer() - o2.getLayer());
+		for (Drawable d : drawables)
+			RunLaterHelper.runLater(()-> d.onDraw());
+		drawablesLock.unlock();
+
+		RunLaterHelper.runLater(() -> {
+			statusLabel.setText(String.format("Zoom: %.2f Center: (%.2f,%.2f)", zoom, worldCenterX, worldCenterY));
+		});
+		
+		RunLaterHelper.runLater(()-> vuiExplorer.update(true));
+	}
+
+	/**
+	 * Get the width of the canvas
+	 * 
+	 * @return the canvas width
+	 */
+	public double getCanvasWidth() {
+		return canvas.getWidth();
+	}
+
+	/**
+	 * Get the height of the canvas
+	 * 
+	 * @return the canvas height
+	 */
+	public double getCanvasHeight() {
+		return canvas.getHeight();
+	}
+
+	/**
+	 * Get the value that must be added to the X coordinate of in world object
+	 * 
+	 * @return the X offset
+	 */
+	public double getWorldOffsetX() {
+		return worldOffsetX;
+	}
+
+	/**
+	 * Set the value that must be added to the X coordinate of in world object
+	 * 
+	 * @param offsetX
+	 *            the X offset
+	 */
+	public void setWorldOffsetX(double offsetX) {
+		this.worldOffsetX = offsetX;
+	}
+
+	/**
+	 * Get the value that must be added to the Y coordinate of in world object
+	 * 
+	 * @return the Y offset
+	 */
+	public double getWorldOffsetY() {
+		return worldOffsetY;
+	}
+
+	/**
+	 * Set the value that must be added to the Y coordinate of in world object
+	 * 
+	 * @param offsetY
+	 *            the Y offset
+	 */
+	public void setWorldOffsetY(double offsetY) {
+		this.worldOffsetY = offsetY;
+	}
+
+	/**
+	 * Create a point and start rendering it
+	 * 
+	 * @param dx
+	 *            the x coordinate
+	 * @param dy
+	 *            the y coordinate
+	 * @return the point object
+	 */
+	public DrawablePoint createAndAddPoint(double dx, double dy) {
+		DrawablePoint drawablePoint = new DrawablePoint(dx, dy);
+		add(drawablePoint);
+		return drawablePoint;
+	}
+
+	/**
+	 * Create a rectangle and start rendering it
+	 * 
+	 * @param x
+	 *            the x coordinate
+	 * @param y
+	 *            the y coordinate
+	 * @param w
+	 *            the width
+	 * @param h
+	 *            the height
+	 * @return the rectangle object
+	 */
+	public DrawableRectangle createAndAddRectangle(double x, double y, double w, double h) {
+		DrawableRectangle d = new DrawableRectangle(x, y, w, h);
+		add(d);
+		return d;
+	}
+
+	/**
+	 * Set the default configuration of the view
+	 * 
+	 * @param zoom
+	 *            the initial zoom value
+	 * @param worldCenterX
+	 *            the initial X center value
+	 * @param worldCenterY
+	 *            the initial Y center value
+	 */
+	public void setDefaultView(double zoom, double worldCenterX, double worldCenterY) {
+		this.zoom = zoom;
+		this.worldCenterX = worldCenterX;
+		this.worldCenterY = worldCenterY;
+		this.defaultZoom = zoom;
+		this.defaultWorldCenterX = worldCenterX;
+		this.defaultWorldCenterY = worldCenterY;
+	}
+
+	/**
+	 * Create an image and start rendering it
+	 * 
+	 * @param dx
+	 *            the x coordinate
+	 * @param dy
+	 *            the y coordinate
+	 * @param filename
+	 *            the filename of the image
+	 * @return the created image
+	 */
+	public DrawableImage createAndAddImage(double dx, double dy, String filename) {
+		DrawableImage image = new DrawableImage(dx, dy, filename);
+		add(image);
+		return image;
+	}
+
+	/**
+	 * Create a string and start rendering it
+	 * 
+	 * @param dx
+	 *            the x coordinate
+	 * @param dy
+	 *            the y coordinate
+	 * @param text
+	 *            the text to display
+	 * @return the created string
+	 */
+	public DrawableString createAndAddString(int dx, int dy, String text) {
+		DrawableString ds = new DrawableString(dx, dy, text);
+		add(ds);
+		return ds;
+	}
+
+	public Pane getCanvas() {
+		return canvas;
+	}
+	
+	public BorderPane getPanel() {
+		return panel;
+	}
+	
+	public List<Drawable> getDrawables() {
+		return drawables;
+	}
+}
diff --git a/AMAKFX/tests/agent/TestAgentTwoPhaseScheduling.java b/AMAKFX/tests/agent/TestAgentTwoPhaseScheduling.java
index 5457b79b99c9e4b818496bb87413d1ba1273ac93..31f38213b8e9fb1797667138c983826d755c3e5e 100644
--- a/AMAKFX/tests/agent/TestAgentTwoPhaseScheduling.java
+++ b/AMAKFX/tests/agent/TestAgentTwoPhaseScheduling.java
@@ -95,7 +95,7 @@ public class TestAgentTwoPhaseScheduling {
 
 	public class TestAMAS extends Amas<TestEnv> {
 		public TestAMAS(TestEnv environment) {
-			super(environment, Scheduling.HIDDEN);
+			super(null, environment, Scheduling.HIDDEN);
 		}
 
 		@Override
diff --git a/AMAKFX/tests/testutils/ObjectsForAgentTesting.java b/AMAKFX/tests/testutils/ObjectsForAgentTesting.java
index a029283fb9d31eb6291af84c3594ce5acab782c9..4c4a164578077fdd4fda65d0d695d1adf35a52c0 100644
--- a/AMAKFX/tests/testutils/ObjectsForAgentTesting.java
+++ b/AMAKFX/tests/testutils/ObjectsForAgentTesting.java
@@ -39,13 +39,13 @@ public class ObjectsForAgentTesting {
 
 	public class TestEnv extends Environment {
 		public TestEnv() {
-			super(Scheduling.HIDDEN);
+			super(null, Scheduling.HIDDEN);
 		}
 	}
 
 	public class TestAMAS extends Amas<TestEnv> {
 		public TestAMAS(TestEnv environment) {
-			super(environment, Scheduling.HIDDEN);
+			super(null, environment, Scheduling.HIDDEN);
 		}
 	}
 }