[Arakhnę-Dev] [1] Initial import

[ Thread Index | Date Index | More arakhne.org/dev Archives ]


Revision: 1
Author:   galland
Date:     2009-05-04 20:29:24 +0200 (Mon, 04 May 2009)

Log Message:
-----------
Initial import

Added Paths:
-----------
    branches/
    tags/
    trunk/
    trunk/pom.xml
    trunk/tinymas-demos/
    trunk/tinymas-demos/pom.xml
    trunk/tinymas-demos/src/
    trunk/tinymas-demos/src/main/
    trunk/tinymas-demos/src/main/java/
    trunk/tinymas-demos/src/main/java/org/
    trunk/tinymas-demos/src/main/java/org/arakhne/
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/GUI.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/GUIWindow.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/Game.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/GameMessage.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/MovableAgent.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/MoveDirection.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/Predator.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/Prey.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/TinyMASApplet.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/WorldGrid.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/go-down.png
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/go-next.png
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/go-previous.png
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/go-up.png
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/lion.png
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/rabbit.png
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/snake.png
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/wolf.png
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/AnimalType.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/GUI.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/GUIWindow.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/Game.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/GameMessage.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/Lion.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/MovableAgent.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/MoveDirection.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/PerceptionType.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/PerceptiveAgent.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/Prey.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/Snake.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/TinyMASApplet.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/WorldGrid.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/go-down.png
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/go-next.png
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/go-previous.png
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/go-up.png
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/lion.png
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/rabbit.png
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/snake.png
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/wolf.png
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/Animal.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/AnimalBody.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/AnimalInfluence.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/AnimalPerception.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/AnimalType.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/GUI.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/Game.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/Lion.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/MoveDirection.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/PerceptionType.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/PerceptiveAnimal.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/Rabbit.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/Snake.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/WorldGrid.java
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/go-down.png
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/go-next.png
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/go-previous.png
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/go-up.png
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/lion.png
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/rabbit.png
    trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/snake.png
    trunk/tinymas-environment/
    trunk/tinymas-environment/pom.xml
    trunk/tinymas-environment/src/
    trunk/tinymas-environment/src/main/
    trunk/tinymas-environment/src/main/java/
    trunk/tinymas-environment/src/main/java/org/
    trunk/tinymas-environment/src/main/java/org/arakhne/
    trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/
    trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/
    trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/agent/
    trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/agent/PerceptionInterestFilter.java
    trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/agent/SituatedAgent.java
    trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/body/
    trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/body/AbstractAgentBody.java
    trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/body/AgentBody.java
    trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/environment/
    trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/environment/AbstractSituatedEnvironment.java
    trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/environment/SituatedEnvironment.java
    trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/environment/SituatedObject.java
    trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/influence/
    trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/influence/Influence.java
    trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/perception/
    trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/perception/EntityPerception.java
    trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/perception/Perception.java
    trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/perception/PerceptionBody.java
    trunk/tinymas-kernel/
    trunk/tinymas-kernel/pom.xml
    trunk/tinymas-kernel/src/
    trunk/tinymas-kernel/src/main/
    trunk/tinymas-kernel/src/main/java/
    trunk/tinymas-kernel/src/main/java/org/
    trunk/tinymas-kernel/src/main/java/org/arakhne/
    trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/
    trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/
    trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/AbstractEnvironment.java
    trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/AbstractScheduler.java
    trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/AbstractTimeManager.java
    trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/Agent.java
    trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/AgentIdentifier.java
    trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/ConstantStepTimeManager.java
    trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/DefaultProbe.java
    trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/DefaultScheduler.java
    trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/Environment.java
    trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/FilteringTimeManager.java
    trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/Identifier.java
    trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/Kernel.java
    trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/KernelAdapter.java
    trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/KernelIdentifier.java
    trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/KernelListener.java
    trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/MeasureUtil.java
    trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/Message.java
    trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/MessageBoxManager.java
    trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/MessageTransportService.java
    trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/Probe.java
    trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/ProbeValueNotDefinedException.java
    trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/Scheduler.java
    trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/SimpleIdentifier.java
    trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/SimulationClock.java
    trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/TimeManager.java
    trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/WhitePages.java
    trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/YellowPages.java
    trunk/tinymas-kernel/src/main/resources/
    trunk/tinymas-kernel/src/main/resources/AUTHORS
    trunk/tinymas-kernel/src/main/resources/COPYING
    trunk/tinymas-kernel/src/main/resources/Changelog
    trunk/tinymas-kernel/src/main/resources/LGPL.html
    trunk/tinymas-kernel/src/main/resources/README
    trunk/tinymas-kernel/src/main/resources/VERSION
    trunk/tinymas-network/
    trunk/tinymas-network/pom.xml
    trunk/tinymas-network/src/
    trunk/tinymas-network/src/main/
    trunk/tinymas-network/src/main/java/
    trunk/tinymas-network/src/main/java/org/
    trunk/tinymas-network/src/main/java/org/arakhne/
    trunk/tinymas-network/src/main/java/org/arakhne/tinyMAS/
    trunk/tinymas-network/src/main/java/org/arakhne/tinyMAS/network/
    trunk/tinymas-network/src/main/java/org/arakhne/tinyMAS/network/KernelMessage.java
    trunk/tinymas-network/src/main/java/org/arakhne/tinyMAS/network/MTSBasedYellowPages.java
    trunk/tinymas-network/src/main/java/org/arakhne/tinyMAS/network/NetworkKernel.java
    trunk/tinymas-network/src/main/java/org/arakhne/tinyMAS/network/NetworkMessageTransportService.java


Added: trunk/pom.xml
===================================================================
--- trunk/pom.xml	                        (rev 0)
+++ trunk/pom.xml	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,248 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd";>
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.arakhne.tinymas</groupId>
+  <artifactId>project</artifactId>
+  <packaging>pom</packaging>
+  <version>1.0-SNAPSHOT</version>
+  <name>TinyMas Platform</name>
+  <url>http://www.arakhne.org/tinymas/</url>
+  <description>A tiny multiagent platform.</description>
+  
+
+	<!-- ======================================= -->
+	<!-- ====       Dependencies             === -->
+	<!-- ======================================= -->
+
+	<properties>
+		<version_myjdk>1.6</version_myjdk>
+		<version_tinymas_kernel>6.6-SNAPSHOT</version_tinymas_kernel>
+		<version_tinymas_network>6.6-SNAPSHOT</version_tinymas_network>
+		<version_tinymas_environment>6.6-SNAPSHOT</version_tinymas_environment>
+		<version_tinymas_demos>6.6-SNAPSHOT</version_tinymas_demos>
+	</properties>
+
+	<dependencyManagement>
+		<dependencies>
+			<dependency>
+				<groupId>org.arakhne.afc</groupId>
+				<artifactId>arakhneRefs</artifactId>
+				<version>[5.1-SNAPSHOT,)</version>
+			</dependency>    
+
+			<dependency>
+				<groupId>org.arakhne.tinymas</groupId>
+				<artifactId>tinymas-kernel</artifactId>
+				<version>${version_tinymas_kernel}</version>
+			</dependency>    
+			<dependency>
+				<groupId>org.arakhne.tinymas</groupId>
+				<artifactId>tinymas-network</artifactId>
+				<version>${version_tinymas_network}</version>
+			</dependency>    
+			<dependency>
+				<groupId>org.arakhne.tinymas</groupId>
+				<artifactId>tinymas-environment</artifactId>
+				<version>${version_tinymas_environment}</version>
+			</dependency>    
+			<dependency>
+				<groupId>org.arakhne.tinymas</groupId>
+				<artifactId>tinymas-demos</artifactId>
+				<version>${version_tinymas_demos}</version>
+			</dependency>    
+		</dependencies>
+	</dependencyManagement>
+
+	<!-- ======================================= -->
+	<!-- ====       Project Information      === -->
+	<!-- ======================================= -->
+	
+	<modules>
+		<module>tinymas-kernel</module>
+		<module>tinymas-network</module>
+		<module>tinymas-environment</module>
+		<module>tinymas-demos</module>
+	</modules>
+
+	<licenses>
+		<license>
+			<name>GNU Lesser General Public License v2.0</name>
+			<url>http://www.gnu.org/licenses/lgpl.html</url>
+			<distribution>repo</distribution>
+		</license>
+	</licenses>
+
+	<mailingLists>
+		<mailingList>
+			<name>dev@xxxxxxxxxxx</name>
+			<subscribe>mailto:dev-request@xxxxxxxxxxx</subscribe>
+			<unsubscribe>mailto:dev-request@xxxxxxxxxxx</unsubscribe>
+			<post>mailto:dev@xxxxxxxxxxx</post>
+		</mailingList>
+	</mailingLists>
+
+	<!-- ======================================= -->
+	<!-- ====   Organization Information     === -->
+	<!-- ======================================= -->
+
+	<organization>
+		<name>Arakhnê.org Project</name>
+		<url>http://www.arakhne.org</url>
+	</organization>
+
+	<developers>
+		<developer>
+			<id>galland</id>
+			<name>Stephane Galland</name>
+			<email>galland@xxxxxxxxxxx</email>
+			<url>http://www.arakhne.org/homes/galland.html</url>
+			<organization />
+			<organizationUrl />
+			<roles>
+				<role>Founder</role>
+				<role>Architect</role>
+				<role>Developer</role>
+			</roles>
+			<timezone />
+			<properties />
+		</developer>
+		<developer>
+			<id>gaud</id>
+			<name>Nicolas Gaud</name>
+			<email>gaud@xxxxxxxxxxx</email>
+			<url>http://www.arakhne.org/homes/gaud.html</url>
+			<organization />
+			<organizationUrl />
+			<roles>
+				<role>Developer</role>
+			</roles>
+			<timezone />
+			<properties />
+		</developer>
+	</developers>
+	
+	<!-- ======================================= -->
+	<!-- ====  Devel Configuration           === -->
+	<!-- ======================================= -->
+	
+	<distributionManagement>
+		<repository>
+			<id>repository.arakhne.org</id>
+			<name>Arakhn&amp;ecirc; Snapshots Repository</name>
+			<url>file:///srv/arakhne.org/repository/maven/</url>
+		</repository>
+		<site>
+			<id>afc.site.arakhne.org</id>
+			<name>AFC Project Websites Repository</name>
+			<url>ftp://ftp.tuxfamily.org/arakhne/arakhne-web/htdocs/maven/tinymas/</url>
+		</site>
+	</distributionManagement>
+
+	<scm>
+		<connection>scm:svn:svn://svn.tuxfamily.org/svnroot/arakhne/tinymas/trunk</connection>
+		<!-- connection>scm:svn:http://svn.tuxfamily.org/arakhne/tinymas/trunk?view=co</connection -->
+		<developerConnection>scm:svn:svn+ssh://svn.tuxfamily.org/svnroot/arakhne/tinymas/trunk</developerConnection>
+		<url>http://www.arakhne.org/websvn.php?project=tinymas</url>
+	</scm>
+
+	<build>
+		<plugins> 
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<configuration>
+					<source>${version_myjdk}</source>
+					<target>${version_myjdk}</target>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-scm-plugin</artifactId>
+				<configuration>
+					<goals>install</goals>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-site-plugin</artifactId>
+			</plugin>		
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-deploy-plugin</artifactId>
+			</plugin>
+		</plugins>
+	</build>
+
+	<!-- ======================================= -->
+	<!-- ====       Repositories             === -->
+	<!-- ======================================= -->
+
+	<repositories>
+		<repository>
+			<id>Codehaus Snapshots</id>
+			<url>http://snapshots.repository.codehaus.org/</url>
+		</repository>
+		<repository>
+			<id>Arakhn&amp;ecirc; Maven Repository</id>
+			<url>http://download.tuxfamily.org/arakhne/maven/</url>
+		</repository>
+	</repositories>
+
+	<!-- ======================================= -->
+	<!-- ====        Reports                 === -->
+	<!-- ======================================= -->
+	<reporting>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-javadoc-plugin</artifactId>
+			</plugin>
+			<plugin>
+				<groupId>org.codehaus.mojo</groupId>
+				<artifactId>dashboard-maven-plugin</artifactId>
+			</plugin>
+			<plugin>
+				<artifactId>maven-javadoc-plugin</artifactId>
+			</plugin>
+			<plugin>
+				<groupId>org.codehaus.mojo</groupId>
+				<artifactId>jxr-maven-plugin</artifactId>
+			</plugin>
+			<plugin>
+				<artifactId>maven-surefire-plugin</artifactId>
+			</plugin>
+			<plugin>
+				<groupId>org.codehaus.mojo</groupId>
+				<artifactId>cobertura-maven-plugin</artifactId>
+			</plugin>
+			<plugin>
+				<groupId>org.codehaus.mojo</groupId>
+				<artifactId>taglist-maven-plugin</artifactId>
+			</plugin>
+			<plugin>
+				<groupId>org.codehaus.mojo</groupId>
+				<artifactId>findbugs-maven-plugin</artifactId>
+				<version>1.1.1</version>
+				<configuration>
+					<threshold>Normal</threshold>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-pmd-plugin</artifactId>
+				<configuration>
+					<targetjdk>${version_myjdk}</targetjdk>
+					<rulesets>
+						<ruleset>/rulesets/basic.xml</ruleset>
+						<ruleset>/rulesets/controversial.xml</ruleset>
+					</rulesets>
+					<format>xml</format>
+					<linkXref>true</linkXref>
+					<sourceEncoding>utf-8</sourceEncoding>
+					<minimumTokens>100</minimumTokens>
+				</configuration>
+			</plugin>
+		</plugins>
+	</reporting>
+
+</project>

Added: trunk/tinymas-demos/pom.xml
===================================================================
--- trunk/tinymas-demos/pom.xml	                        (rev 0)
+++ trunk/tinymas-demos/pom.xml	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd";>
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+	<artifactId>project</artifactId>
+	<groupId>org.arakhne.tinymas</groupId>
+	<version>1.0-SNAPSHOT</version>
+  </parent>
+
+  <groupId>org.arakhne.tinymas</groupId>
+  <artifactId>tinymas-demos</artifactId>
+  <packaging>jar</packaging>
+  <version>${version_tinymas_demos}</version>
+  <name>TinyMAS demos</name>
+  <url>http://www.arakhne.org/tinymas/</url>
+
+	<!-- ======================================= -->
+	<!-- ====       Project Information      === -->
+	<!-- ======================================= -->
+		
+	<scm>
+		<url>http://www.arakhne.org/websvn.php?project=tinymas&amp;subproject=demos</url>
+	</scm>
+	
+	<dependencies>
+		<dependency>
+			<groupId>org.arakhne.tinymas</groupId>
+			<artifactId>tinymas-kernel</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.arakhne.tinymas</groupId>
+			<artifactId>tinymas-environment</artifactId>
+		</dependency>
+	</dependencies>
+
+</project>

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/GUI.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/GUI.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/GUI.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,519 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator1;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Toolkit;
+import java.awt.Transparency;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.image.BufferedImage;
+import java.lang.ref.WeakReference;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Map.Entry;
+import java.util.concurrent.Executors;
+
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+
+import org.arakhne.tinyMAS.core.AgentIdentifier;
+import org.arakhne.tinyMAS.core.Kernel;
+import org.arakhne.tinyMAS.core.KernelAdapter;
+import org.arakhne.tinyMAS.core.Probe;
+import org.arakhne.tinyMAS.core.ProbeValueNotDefinedException;
+
+/** 
+ * Afficheur de l'état du monde
+ * <p>
+ * Travaux pratiques d'IA54.<br>
+ * Universit&eacute; de Technologie de Belfort-monb&eacute;liard.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public class GUI extends JPanel {
+
+	private static final long serialVersionUID = 3939643459108505034L;
+	
+	protected static final int ANIMATION_SPEED = 1;
+	protected static final int ANIMATION_STEPS = 10;
+	
+	protected static final Icon PREY_ICON;
+	protected static final Icon PREDATOR_ICON;	
+	protected static final Icon UP_ICON;
+	protected static final Icon DOWN_ICON;	
+	protected static final Icon LEFT_ICON;
+	protected static final Icon RIGHT_ICON;	
+	protected static final int ICON_WIDTH;
+	protected static final int ICON_HEIGHT;
+	
+	static {
+		URL url = GUI.class.getResource("/org/arakhne/tinyMAS/demo/preypredator1/rabbit.png"); //$NON-NLS-1$
+		assert(url!=null);
+		PREY_ICON = new ImageIcon(url);
+		url = GUI.class.getResource("/org/arakhne/tinyMAS/demo/preypredator1/lion.png"); //$NON-NLS-1$
+		assert(url!=null);
+		PREDATOR_ICON = new ImageIcon(url);
+		url = GUI.class.getResource("/org/arakhne/tinyMAS/demo/preypredator1/go-up.png"); //$NON-NLS-1$
+		assert(url!=null);
+		UP_ICON = new ImageIcon(url);
+		url = GUI.class.getResource("/org/arakhne/tinyMAS/demo/preypredator1/go-down.png"); //$NON-NLS-1$
+		assert(url!=null);
+		DOWN_ICON = new ImageIcon(url);
+		url = GUI.class.getResource("/org/arakhne/tinyMAS/demo/preypredator1/go-previous.png"); //$NON-NLS-1$
+		assert(url!=null);
+		LEFT_ICON = new ImageIcon(url);
+		url = GUI.class.getResource("/org/arakhne/tinyMAS/demo/preypredator1/go-next.png"); //$NON-NLS-1$
+		assert(url!=null);
+		RIGHT_ICON = new ImageIcon(url);
+		
+		ICON_WIDTH = Math.max(PREY_ICON.getIconWidth(), PREDATOR_ICON.getIconWidth());
+		ICON_HEIGHT = Math.max(PREY_ICON.getIconHeight(), PREDATOR_ICON.getIconHeight());
+	}
+	
+    public static Image mergeImages(Image top_icon, Image bottom_icon, int x, int y) {
+    	int imgWidth = bottom_icon.getWidth(null);
+    	int imgHeight = bottom_icon.getHeight(null);
+    	BufferedImage img = new BufferedImage(
+    			imgWidth, imgHeight,
+    			Transparency.BITMASK);
+    	Graphics g = img.getGraphics();
+    	g.setClip(0,0,imgWidth,imgHeight);
+    	g.drawImage(bottom_icon,0,0,null);
+    	if (x<0) x = imgWidth + x;
+    	if (y<0) y = imgHeight + y;
+    	g.drawImage(top_icon,x,y,null);
+    	return Toolkit.getDefaultToolkit().createImage(img.getSource());
+    }
+
+    public static Icon mergeIcons(Icon top_icon, Icon bottom_icon, int x, int y) {
+        if ((top_icon instanceof ImageIcon)&&(bottom_icon instanceof ImageIcon)) {
+        	Image new_image = mergeImages(
+    				((ImageIcon)top_icon).getImage(),
+    				((ImageIcon)bottom_icon).getImage(),
+    				x, y);
+        	if (new_image!=null)
+        		return new ImageIcon(new_image);        	
+        }
+        return null;
+    }                       
+
+    protected final Grid grid;
+	protected final RefreshThread refresher;
+	private WeakReference<Kernel<?,?,?,?>> kernel;	
+	protected Probe worldProbe;
+	protected Map<AgentIdentifier,Dimension> positions;
+	protected Map<AgentIdentifier,Dimension> nextPositions;
+	
+	public GUI() {
+		this.refresher = new RefreshThread();
+		
+		this.kernel = null;
+		
+		setLayout(new BorderLayout());
+		
+		this.grid = new Grid();
+
+		JScrollPane scroll = new JScrollPane(this.grid);
+		add(BorderLayout.CENTER,scroll);
+		
+		JButton closeBt = new JButton("Quit"); //$NON-NLS-1$
+		closeBt.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				Kernel<?,?,?,?> kernel = getKernel();
+				if (kernel!=null) kernel.stop();
+			}
+		});
+		add(BorderLayout.SOUTH, closeBt);
+		
+		setPreferredSize(new Dimension(300,350));
+	}
+	
+	public void setKernel(Kernel<?,?,?,?> kernel) {
+		if (kernel==null) {
+			this.kernel = null;
+		}
+		else {
+			this.kernel = new WeakReference<Kernel<?,?,?,?>>(kernel);
+			kernel.addKernelListener(new KernelAdapter() {
+				@Override
+				public void kernelRefreshAllowed(Kernel<?, ?, ?, ?> kernel) {
+					if (kernel==GUI.this.getKernel()) {
+						changeState();
+					}
+				}
+				@Override
+				public void kernelStarted(Kernel<?, ?, ?, ?> kernel) {
+					if (kernel==GUI.this.getKernel()) {
+						changeState();
+					}
+				}			
+			});
+		}
+	}
+	
+	public void launchRefresher() {
+		Executors.newSingleThreadExecutor().execute(this.refresher);
+	}
+	
+	public void stopRefresher() {
+		this.refresher.stop();
+	}
+
+	@SuppressWarnings("unchecked")
+	protected void changeState() {
+		Kernel<?,?,?,?> kernel = getKernel();
+		if (kernel!=null && this.worldProbe==null) {
+			AgentIdentifier[] world = kernel.getServiceProviders("WORLD_GRID"); //$NON-NLS-1$
+			if (world.length>0) {
+				this.worldProbe = kernel.getProbe(world[0]);
+			}
+		}
+		this.refresher.addMoves(this.worldProbe.getProbeValue("WORLD_STATE",Map.class)); //$NON-NLS-1$
+	}
+	
+	protected void refreshGUI(Map<AgentIdentifier,Dimension> moves) {
+		this.positions = moves;
+		this.grid.setStep(-1);
+		this.grid.repaint();
+	}
+
+	protected void refreshGUI(int moveStep, Map<AgentIdentifier,Dimension> moves) {
+		this.nextPositions = moves;
+		this.grid.setStep(moveStep);
+		this.grid.repaint();
+	}
+	
+	protected void refreshGUI(int moveStep) {
+		if (moveStep<0) {
+			this.positions = this.nextPositions;
+			//debugPositions(getKernel(), this.positions, "NEW POSITION"); //$NON-NLS-1$
+		}
+		this.grid.setStep(moveStep);
+		this.grid.repaint();
+	}
+	
+	protected Kernel<?,?,?,?> getKernel() {
+		return this.kernel==null ? null : this.kernel.get();
+	}
+	
+	protected static void debugPositions(Kernel<?,?,?,?> kernel, Map<AgentIdentifier,Dimension> positions, String str) {
+		AgentIdentifier[] world = kernel.getServiceProviders("WORLD_GRID"); //$NON-NLS-1$
+		if (world.length>0) {
+			Probe probe = kernel.getProbe(world[0]);
+			try {
+				int width = probe.getProbeInt("WIDTH"); //$NON-NLS-1$
+				int height = probe.getProbeInt("HEIGHT"); //$NON-NLS-1$
+				
+				int[] size = new int[width];
+				Arrays.fill(size, 0);
+				
+				AgentIdentifier[][] grid = new AgentIdentifier[height][width];
+				for (Entry<AgentIdentifier, Dimension> entry : positions.entrySet()) {
+					int h = entry.getValue().height;
+					int w = entry.getValue().width;
+					assert(grid[h][w]==null);
+					grid[h][w] = entry.getKey();
+					if (size[w]<grid[h][w].getString().length())
+						size[w] = grid[h][w].getString().length();
+				}
+				
+				System.out.println(">>"+str+"<<"); //$NON-NLS-1$ //$NON-NLS-2$
+				for(int r=0; r<height; r++) {
+					System.out.print("| "); //$NON-NLS-1$
+					for(int c=0; c<width; c++) {
+						int s = grid[r][c]==null ? 0 : grid[r][c].getString().length();
+						if (grid[r][c]!=null) System.out.print(grid[r][c].getString());
+						for(int k=s; k<size[c]; k++)
+							System.out.print(" "); //$NON-NLS-1$
+						System.out.print(" |"); //$NON-NLS-1$
+					}
+					System.out.println(""); //$NON-NLS-1$
+				}
+				
+				return;
+			}
+			catch(ProbeValueNotDefinedException _) {
+				//
+			}			
+		}
+		throw new Error("UNABLE TO OBTAIN A PROBE"); //$NON-NLS-1$
+	}
+	
+	private class RefreshThread implements Runnable {
+
+		private final Queue<Map<AgentIdentifier,Dimension>> queue = new LinkedList<Map<AgentIdentifier,Dimension>>(); 
+		
+		private boolean run = true;
+		private int moveStep = -2;
+
+		public RefreshThread() {
+			//
+		}
+		
+		public void stop() {
+			this.run = false;
+		}
+		
+		public void run() {
+			while (this.run) {
+				if (this.moveStep<0) {
+					Map<AgentIdentifier,Dimension> moves = this.queue.poll();
+					if (moves!=null) {
+						if (this.moveStep==-1) {
+							this.moveStep = 0;
+							GUI.this.refreshGUI(this.moveStep, moves);
+						}
+						else if (this.moveStep==-2) {
+							this.moveStep = -1;
+							GUI.this.refreshGUI(moves);
+						}
+					}
+				}
+				else {
+					try {
+						Thread.sleep((1000*ANIMATION_SPEED)/ANIMATION_STEPS);
+					}
+					catch (InterruptedException e) {
+						//
+					}
+					if (this.moveStep>=ANIMATION_STEPS) {
+						this.moveStep = -1;
+					}
+					else {
+						this.moveStep++;
+					}
+					GUI.this.refreshGUI(this.moveStep);
+				}
+				Thread.yield();
+			}
+		}
+		
+		public void addMoves(Map<AgentIdentifier,Dimension> moves) {
+			if (moves!=null) {
+				Map<AgentIdentifier,Dimension> old = this.queue.peek();
+				if ((old==null)||(!old.equals(moves))) {
+					this.queue.offer(moves);
+				}
+			}
+		}
+		
+	}
+	
+	private class Grid extends JPanel {
+		
+		private static final long serialVersionUID = 4361140442107583935L;
+		
+		private int moveStep = -1;
+		
+		public Grid() {
+			//
+		}
+		
+		public void setStep(int step) {
+			this.moveStep = step;
+		}
+		
+		@Override
+		public void paint(Graphics g) {
+			super.paint(g);
+			Graphics2D g2d = (Graphics2D)g;
+			
+			Dimension currentDim = getPreferredSize();
+			Dimension desiredDim = computeDesiredDim();
+			
+			if ((desiredDim!=null)&&(!currentDim.equals(desiredDim))) {
+				setPreferredSize(desiredDim);
+				revalidate();
+				repaint();
+				return;
+			}
+			
+			if (this.moveStep>=0) {
+				drawMovingAgents(g2d, currentDim);
+			}
+			else {
+				drawAgents(g2d, currentDim);					
+			}
+			
+			drawGrid(g2d, currentDim);
+		}
+		
+		private void drawMovingAgents(Graphics2D g2d, Dimension currentDim) {
+			if ((this.moveStep<0)||
+				(GUI.this.nextPositions==null)||
+				(GUI.this.positions==null)) drawAgents(g2d, currentDim);
+			
+			int x, y, deltaX, deltaY;
+			Dimension d;
+			Dimension nextD;
+			AgentIdentifier id;
+			
+			Probe probe = getProbe();
+			if (probe==null) return;
+			AgentIdentifier prey = probe.getProbeValue("PREY", AgentIdentifier.class); //$NON-NLS-1$
+			deltaX = ((this.moveStep * ICON_WIDTH) / ANIMATION_STEPS);
+			deltaY = ((this.moveStep * ICON_HEIGHT) / ANIMATION_STEPS);
+			
+			Icon ic;
+
+			for (Entry<AgentIdentifier, Dimension> entry : GUI.this.positions.entrySet()) {
+				id = entry.getKey();
+				d = entry.getValue();
+				if (GUI.this.nextPositions.containsKey(id)) {
+					nextD = GUI.this.nextPositions.get(id);
+					x = d.width * ICON_WIDTH;
+					y = d.height * ICON_HEIGHT;
+					
+					if (nextD.width<d.width) {
+						x -= deltaX;
+					}
+					else if (nextD.width>d.width) {
+						x += deltaX;
+					}
+										
+					if (nextD.height<d.height) {
+						y -= deltaY;
+					}
+					else if (nextD.height>d.height) {
+						y += deltaY;
+					}
+
+					ic = getIcon(id.equals(prey), getLastDirection(id));
+					assert(ic!=null);
+					ic.paintIcon(this, g2d, x, y);
+				}
+			}
+		}
+		
+		private void drawAgents(Graphics2D g2d, Dimension currentDim) {
+			if (GUI.this.positions==null) return;
+			int x, y;
+			Dimension d;
+			Probe probe = getProbe();
+			if (probe==null) return;
+			AgentIdentifier prey = probe.getProbeValue("PREY", AgentIdentifier.class); //$NON-NLS-1$
+			Icon ic;
+			for (Entry<AgentIdentifier, Dimension> entry : GUI.this.positions.entrySet()) {
+				d = entry.getValue();
+				x = d.width * ICON_WIDTH;
+				y = d.height * ICON_HEIGHT;
+				
+				ic = getIcon(entry.getKey().equals(prey), getLastDirection(entry.getKey()));
+				assert(ic!=null);
+				ic.paintIcon(this, g2d, x, y);
+			}
+		}
+		
+		private void drawGrid(Graphics2D g2d, Dimension currentDim) {
+			int x, y;
+			g2d.setColor(Color.BLACK);
+			for(x=0; x<=currentDim.width; x+=ICON_WIDTH) {
+				g2d.drawLine(x, 0, x, currentDim.height); 
+			}
+			for(y=0; y<=currentDim.height; y+=ICON_WIDTH) {
+				g2d.drawLine(0, y, currentDim.width, y); 
+			}
+		}
+		
+		private Probe getProbe() {
+			Kernel<?,?,?,?> kernel = GUI.this.getKernel();
+			if (kernel!=null) {
+				AgentIdentifier[] world = kernel.getServiceProviders("WORLD_GRID"); //$NON-NLS-1$
+				if (world.length>0) {
+					return kernel.getProbe(world[0]);
+				}
+			}
+			return null;
+		}
+		
+		private Dimension computeDesiredDim() {
+			Probe probe = getProbe();
+			if (probe!=null) {
+				try {
+					int width = probe.getProbeInt("WIDTH"); //$NON-NLS-1$
+					int height = probe.getProbeInt("HEIGHT"); //$NON-NLS-1$
+					
+					return new Dimension(width*GUI.ICON_WIDTH, height*GUI.ICON_HEIGHT);
+				}
+				catch(ProbeValueNotDefinedException _) {
+					//
+				}
+			}
+			return null;
+		}
+		
+		private MoveDirection getLastDirection(AgentIdentifier id) {
+			Kernel<?,?,?,?> kernel = GUI.this.getKernel();
+			if (kernel==null) return MoveDirection.NONE;
+			Probe probe = kernel.getProbe(id);
+			return probe.getProbeValue("LAST_MOVE", MoveDirection.class); //$NON-NLS-1$
+		}
+		
+		private Icon getIcon(boolean isPrey, MoveDirection direction) {
+			Icon ic;
+			if (isPrey) {
+				ic = PREY_ICON;
+			}
+			else {
+				ic = PREDATOR_ICON;
+			}
+			
+			switch(direction) {
+			case UP:
+				ic = mergeIcons(UP_ICON, ic, 
+						(ic.getIconWidth()-UP_ICON.getIconWidth())/2, 0);
+				break;
+			case DOWN:
+				ic = mergeIcons(DOWN_ICON, ic, 
+						(ic.getIconWidth()-DOWN_ICON.getIconWidth())/2,
+						ic.getIconHeight() - DOWN_ICON.getIconHeight());
+				break;
+			case LEFT:
+				ic = mergeIcons(LEFT_ICON, ic,
+						0,
+						(ic.getIconHeight()-LEFT_ICON.getIconHeight())/2);
+				break;
+			case RIGHT:
+				ic = mergeIcons(RIGHT_ICON, ic, 
+						ic.getIconWidth() - RIGHT_ICON.getIconWidth(),
+						(ic.getIconHeight()-RIGHT_ICON.getIconHeight())/2);
+				break;
+			case NONE:
+			}
+			
+			return ic;
+		}
+	}
+	
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/GUIWindow.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/GUIWindow.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/GUIWindow.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,85 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator1;
+
+import java.awt.BorderLayout;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+
+import javax.swing.JFrame;
+import javax.swing.WindowConstants;
+
+import org.arakhne.tinyMAS.core.Kernel;
+
+/** 
+ * Afficheur de l'état du monde
+ * <p>
+ * Travaux pratiques d'IA54.<br>
+ * Universit&eacute; de Technologie de Belfort-monb&eacute;liard.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public class GUIWindow extends JFrame {
+
+	private static final long serialVersionUID = 3939643459108505034L;
+	
+    protected final GUI gui;
+	
+	public GUIWindow(Kernel<?,?,?,?> kernel) {
+		this.gui = new GUI();
+		this.gui.setKernel(kernel);
+		
+		Container content = getContentPane();
+		
+		content.setLayout(new BorderLayout());
+		
+		content.add(BorderLayout.CENTER,this.gui);
+		
+		setPreferredSize(new Dimension(300,350));
+		
+		addWindowListener(new WindowAdapter() {
+			@Override
+			public void windowClosed(WindowEvent e) {
+				Kernel<?,?,?,?> kernel = GUIWindow.this.getKernel();
+				kernel.stop();
+			}
+			@Override
+			public void windowClosing(WindowEvent e) {
+				Kernel<?,?,?,?> kernel = GUIWindow.this.getKernel();
+				kernel.stop();
+			}
+		});
+		
+		setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+		
+		pack();
+		
+		this.gui.launchRefresher();
+	}
+	
+	protected Kernel<?,?,?,?> getKernel() {
+		return this.gui.getKernel();
+	}
+	
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/Game.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/Game.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/Game.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,102 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator1;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.arakhne.tinyMAS.core.AbstractScheduler;
+import org.arakhne.tinyMAS.core.Agent;
+import org.arakhne.tinyMAS.core.Kernel;
+
+/** JEU DE LA PROIE ET DES PREDATEURS.
+ * <p>
+ * Travaux pratiques d'IA54.<br>
+ * Universit&eacute; de Technologie de Belfort-monb&eacute;liard.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+@SuppressWarnings("unchecked")
+public class Game extends Kernel {
+
+	private static final int PREDATOR_COUNT = 10;
+	
+	public Game() {
+		super(new AbstractScheduler<Agent>() {
+			public void schedule(List<Agent> agents) {
+				Agent world = null;
+				ArrayList<Agent> animats = new ArrayList<Agent>();
+				for (Agent agent : agents) {
+					if (agent instanceof WorldGrid)
+						world = agent;
+					else
+						animats.add(agent);
+				}
+
+				Collections.shuffle(animats);
+				for (Agent agent : animats) {
+					agent.live();
+				}
+				
+				if (world!=null)
+					world.live();
+			}
+		});
+	}
+	
+	/** Programme Principal
+	 */	
+	public static void main(String[] argv) {
+		
+		System.out.println("Prey and Predator demonstrator #1"); //$NON-NLS-1$
+		System.out.println("Copyright (c) 2005-2009 Stéphane GALLAND and Nicolas GAUD "); //$NON-NLS-1$
+		System.out.println("Thanks to Julia Nikolaeva aka. Flameia for the icons <flameia@xxxxxxxxxxxx>"); //$NON-NLS-1$
+		
+		Game j = new Game() ;
+		
+		j.setWaitingDuration(3000);
+		
+		WorldGrid g = new WorldGrid(5,5) ;
+		j.addAgent(g) ;
+
+		Agent a = new Prey() ;		
+		j.addAgent(a) ;
+		g.addAgent(a.getId(),true) ;		 
+
+		for(int i=0; i<PREDATOR_COUNT; i++) {
+			a = new Predator() ;		
+			j.addAgent(a) ;
+			g.addAgent(a.getId(),false) ;
+		}
+
+		GUIWindow gui = new GUIWindow(j);
+		gui.setVisible(true);
+		
+		j.run() ;
+		
+		// Force quit
+		System.exit(0);
+		
+	}
+
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/GameMessage.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/GameMessage.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/GameMessage.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,36 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator1;
+
+/** 
+ * Message de gestion du jeu
+ * <p>
+ * Travaux pratiques d'IA54.<br>
+ * Universit&eacute; de Technologie de Belfort-monb&eacute;liard.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public enum GameMessage {
+
+	END_OF_GAME,
+	
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/MovableAgent.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/MovableAgent.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/MovableAgent.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,67 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator1;
+
+import org.arakhne.tinyMAS.core.Agent;
+import org.arakhne.tinyMAS.core.AgentIdentifier;
+import org.arakhne.tinyMAS.core.Kernel;
+
+/** Un agent capable de se deplacer dans le monde du
+ *  jeu "Proie et Predateurs".
+ * <p>
+ * Travaux pratiques d'IA54.<br>
+ * Universit&eacute; de Technologie de Belfort-monb&eacute;liard.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public abstract class MovableAgent extends Agent {
+
+	/** Deplace l'agent dans la direction indiquee.
+	 * 
+	 * @param direction  
+	 * @return <code>true</code> si le mouvement est envoye.
+	 */	
+	protected boolean moveTo(MoveDirection direction) {
+		// Get the agent that provide a world grid service 
+		AgentIdentifier id = Kernel.getSingleton().getYellowPageSystem().getAgentFor("WORLD_GRID"); //$NON-NLS-1$
+		assert(id!=null);
+		// Send the message to the agent
+		setProbe("LAST_MOVE", direction); //$NON-NLS-1$
+		return sendMessage(id, direction) ;
+	}
+	
+	/** Tire au hasard une direction.
+	 */
+	protected MoveDirection computeMove(boolean allow_no_move) {
+		int tries = 0;
+		MoveDirection[] values = MoveDirection.values();
+		MoveDirection selected;
+		do {
+			int direction = (int)(Math.random() * values.length * 10.)/10 ;
+			selected = values[direction];
+			tries++;
+		}
+		while ((!allow_no_move)&&(selected==MoveDirection.NONE)&&(tries<10));
+		return selected;
+	}
+	
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/MoveDirection.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/MoveDirection.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/MoveDirection.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,44 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator1;
+
+/** 
+ * Direction de deplacement pour les proies et les predateurs
+ * <p>
+ * Travaux pratiques d'IA54.<br>
+ * Universit&eacute; de Technologie de Belfort-monb&eacute;liard.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public enum MoveDirection {
+
+	NONE,
+	
+	UP,
+	
+	DOWN,
+	
+	LEFT,
+	
+	RIGHT;
+	
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/Predator.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/Predator.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/Predator.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,77 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator1;
+
+import org.arakhne.tinyMAS.core.Message;
+
+/** AGENT PREDATEUR
+ * <p>
+ * Travaux pratiques d'IA54.<br>
+ * Universit&eacute; de Technologie de Belfort-monb&eacute;liard.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public class Predator extends MovableAgent {
+
+	private static int PREDATOR_COUNT = 0;
+	
+	private final int number;
+	
+	public Predator() {
+		this.number = PREDATOR_COUNT++;
+	}
+	
+	@Override
+	public String toString() {
+		return "Predator #"+this.number; //$NON-NLS-1$
+	}
+
+	@Override
+	public void start() {
+		forceIdentifierStringRepresentation();
+	}
+
+	/** L'agent predateur se deplace aleatoirement.
+	 */ 	
+	@Override
+	public void live() {
+		boolean eog = false;
+		
+		while (hasMessage()) {
+			Message msg = getNextMessage();
+			if (msg.CONTENT instanceof GameMessage) {
+				GameMessage gmsg = (GameMessage)(msg.CONTENT);
+				if (gmsg==GameMessage.END_OF_GAME) {
+					eog = true;
+				}
+			}
+		}
+
+		if (eog) {
+			killMe();
+		}
+		else {
+			moveTo(computeMove(true));
+		}
+	}
+	
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/Prey.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/Prey.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/Prey.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,73 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator1;
+
+import org.arakhne.tinyMAS.core.Message;
+
+/** AGENT PROIE
+ * <p>
+ * Travaux pratiques d'IA54.<br>
+ * Universit&eacute; de Technologie de Belfort-monb&eacute;liard.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public class Prey extends MovableAgent {
+
+	@Override
+	public String toString() {
+		return "Prey"; //$NON-NLS-1$
+	}
+
+	@Override
+	public void start() {
+		setProbe("CATCHED", false); //$NON-NLS-1$
+		forceIdentifierStringRepresentation();
+	}
+	
+	/** L'agent se deplace aleatoirement.
+	 *  Mais s'il ne peut plus bouger, la simulation
+	 *  doit s'arretee.
+	 */	
+	@Override
+	public void live() {
+		boolean eog = false;
+		
+		while (hasMessage()) {
+			Message msg = getNextMessage();
+			if (msg.CONTENT instanceof GameMessage) {
+				GameMessage gmsg = (GameMessage)(msg.CONTENT);
+				if (gmsg==GameMessage.END_OF_GAME) {
+					eog = true;
+				}
+			}
+		}
+
+		if (eog) {
+			setProbe("CATCHED", true); //$NON-NLS-1$
+			killMe();
+		}
+		else {
+			moveTo(computeMove(false));
+		}
+	}
+	
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/TinyMASApplet.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/TinyMASApplet.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/TinyMASApplet.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,118 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator1;
+
+import java.awt.BorderLayout;
+
+import javax.swing.JApplet;
+
+import org.arakhne.tinyMAS.core.Agent;
+
+/** 
+ * Afficheur de l'état du monde
+ * <p>
+ * Travaux pratiques d'IA54.<br>
+ * Universit&eacute; de Technologie de Belfort-monb&eacute;liard.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public class TinyMASApplet extends JApplet {
+
+	private static final long serialVersionUID = 1L;
+
+	private static final int PREDATOR_COUNT = 10;
+	
+	volatile Game game;
+	final GUI gui;
+	
+	public TinyMASApplet() {
+		this.game = null;
+		this.gui = new GUI();
+		setLayout(new BorderLayout());
+		add(this.gui, BorderLayout.CENTER);
+	}
+	
+	void initGame() {
+		this.game = new Game() ;
+		
+		this.game.setWaitingDuration(3000);
+		
+		WorldGrid g = new WorldGrid(5,5) ;
+		this.game.addAgent(g) ;
+
+		Agent a = new Prey() ;		
+		this.game.addAgent(a) ;
+		g.addAgent(a.getId(),true) ;		 
+
+		for(int i=0; i<PREDATOR_COUNT; i++) {
+			a = new Predator() ;		
+			this.game.addAgent(a) ;
+			g.addAgent(a.getId(),false) ;
+		}
+		
+		this.gui.setKernel(this.game);
+		this.gui.launchRefresher();
+		
+		new Thread() {
+			@Override
+			public void run() {
+				Game game = TinyMASApplet.this.game;
+				game.run();
+				destroyGame();
+			}
+		}.start();
+	}
+	
+	void destroyGame() {
+		this.gui.stopRefresher();
+		this.gui.setKernel(null);
+		this.game = null;
+	}
+
+	@Override
+	public void destroy() {
+		if (this.game==null) this.game.stop();
+		super.destroy();
+	}
+
+	@Override
+	public void start() {
+		super.start();
+		if (this.game==null) {
+			initGame();
+		}
+		else {
+			this.game.pause();
+		}
+	}
+
+	@Override
+	public void stop() {
+		if (this.game!=null) {
+			this.game.stop();
+		}
+		super.stop();
+	}
+	
+	
+	
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/WorldGrid.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/WorldGrid.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/WorldGrid.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,350 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator1;
+
+import java.awt.Dimension;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.Map.Entry;
+
+import org.arakhne.tinyMAS.core.Agent;
+import org.arakhne.tinyMAS.core.AgentIdentifier;
+import org.arakhne.tinyMAS.core.Message;
+
+/** 
+ * AGENT GRILLE.
+ * L'environnement de notre simulation.
+ * <p>
+ * Travaux pratiques d'IA54.<br>
+ * Universit&eacute; de Technologie de Belfort-monb&eacute;liard.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public class WorldGrid extends Agent {
+
+	private final AgentIdentifier[][] world;
+	private final int width;
+	private final int height;
+	private AgentIdentifier prey;
+	private final Map<AgentIdentifier,Dimension> locations = new TreeMap<AgentIdentifier,Dimension>();
+	
+	private final Map<AgentIdentifier,MoveDirection> awaitingMessages = new TreeMap<AgentIdentifier,MoveDirection>();
+	
+	/** Construit un monde.
+	 * @param x taille du monde
+	 * @param y taille du monde
+	 */	
+	public WorldGrid(int x, int y) {
+		this.world = new AgentIdentifier[y][x];
+		this.width = x;
+		this.height = y;
+	}
+	
+	/** Informe l'agent qu'il demarre sa vie.
+	 *  <p>
+	 *  Cette methode initialise les attributs de l'agent.
+	 */
+	@Override
+	public void start() {
+		forceIdentifierStringRepresentation();
+		registerService("WORLD_GRID"); //$NON-NLS-1$
+		setProbe("CATCHED", false); //$NON-NLS-1$
+		setProbe("WIDTH", this.width); //$NON-NLS-1$
+		setProbe("HEIGHT", this.height); //$NON-NLS-1$
+		setStateProbe();
+	}
+
+	/** Ajoute aleatoirement un agent dans le monde.
+	 * 
+	 * @param id est l'identificateur de l'agent a ajouter.
+	 * @param is_prey indique si l'ajout est la proie
+	 */
+	public void addAgent(AgentIdentifier id, boolean is_prey) {
+		if ((is_prey)&&(this.prey!=null))
+			throw new IllegalArgumentException("is_prey"); //$NON-NLS-1$
+		
+		int x, y;
+		Random rnd = new Random();
+		do {
+			x = rnd.nextInt(this.width);
+			y = rnd.nextInt(this.height);
+		}
+		while (this.world[y][x]!=null);
+		
+		this.world[y][x] = id;
+		this.locations.put(id, new Dimension(x,y));
+		if (is_prey) {
+			this.prey = id;
+			setProbe("PREY", id); //$NON-NLS-1$
+		}
+	}
+	
+	/** Traite les messages provenant des agents et deplace
+	 *  les si cela est possible.
+	 */
+	@Override
+	public void live() {
+		while (hasMessage()) {
+			Message msg = getNextMessage();
+			if ((!this.awaitingMessages.containsKey(msg.FROM))&&
+				(msg.CONTENT instanceof MoveDirection)) {
+				this.awaitingMessages.put(msg.FROM, (MoveDirection)msg.CONTENT);
+			}
+			else {
+				System.err.println("Le monde vient d'ignorer un message provenant de "+msg.FROM); //$NON-NLS-1$
+			}
+		}
+		
+		if (this.awaitingMessages.size()==this.locations.size()) {
+			// Tous les agents ont envoye un message
+			
+			// Calcul les positions desirees par les agents
+			Map<AgentIdentifier, Dimension> desiredPositions = new TreeMap<AgentIdentifier,Dimension>();
+			for (Entry<AgentIdentifier,MoveDirection> entry : this.awaitingMessages.entrySet()) {
+				desiredPositions.put(entry.getKey(), predictMove(entry.getKey(), entry.getValue()));
+			}
+				
+			// Detection de conflits
+			Map<Dimension, Set<AgentIdentifier>> conflicts = new HashMap<Dimension,Set<AgentIdentifier>>();
+			for (Entry<AgentIdentifier,Dimension> entry1 : desiredPositions.entrySet()) {
+				for (Entry<AgentIdentifier,Dimension> entry2 : desiredPositions.entrySet()) {
+					if (!entry1.getKey().equals(entry2.getKey())) {
+						if (entry1.getValue().equals(entry2.getValue())) {
+							// Conflit
+							Set<AgentIdentifier> conflictedAgents = conflicts.get(entry1.getValue());
+							if (conflictedAgents==null) {
+								conflictedAgents = new HashSet<AgentIdentifier>();
+								conflicts.put(entry1.getValue(), conflictedAgents);
+							}
+							conflictedAgents.add(entry1.getKey());
+							conflictedAgents.add(entry2.getKey());
+						}
+					}
+				}
+			}
+			
+			// Resolution des conflits
+			// Choix aleatoire d'un des agents
+			Random rnd = new Random();
+			int idx;
+			AgentIdentifier[] tab;
+			for (Entry<Dimension,Set<AgentIdentifier>> entry : conflicts.entrySet()) {
+				tab = new AgentIdentifier[entry.getValue().size()];
+				entry.getValue().toArray(tab);
+				idx = rnd.nextInt(tab.length);
+				moveAgent(tab[idx], this.awaitingMessages.get(tab[idx]));
+				for (AgentIdentifier agentId : tab) {
+					desiredPositions.remove(agentId);
+				}
+			}
+			
+			// Changement de position des agents n'ayant pas provoque de conflit
+			for (AgentIdentifier agentId : desiredPositions.keySet()) {
+				moveAgent(agentId,this.awaitingMessages.get(agentId));
+			}
+						
+			// Vide les tampons
+			desiredPositions.clear();
+			conflicts.clear();
+			this.awaitingMessages.clear();
+			
+			setStateProbe();
+			
+			//debugPositions(this.width, this.height, this.world);
+			
+			// Verification de l'etat du jeu
+			if (verifyifPreyCatched()) {
+				setProbe("CATCHED", true); //$NON-NLS-1$
+				System.out.println("The prey was catched"); //$NON-NLS-1$
+				debugPositions(this.width, this.height, this.world);
+				endOfGame();
+			}
+		}
+	}
+	
+	/** Calcul la position de la cellule dans laquelle un agent veut se deplacer.
+	 */
+	private Dimension predictMove(AgentIdentifier id, MoveDirection direction) {
+		Dimension pos = this.locations.get(id);
+		assert(pos!=null);
+
+		int x = pos.width;
+		int y = pos.height;
+		int nx = x;
+		int ny = y;
+		
+		switch(direction) {
+		case UP:
+			ny--;
+			break;
+		case DOWN:
+			ny++;
+			break;
+		case LEFT:
+			nx--;
+			break;
+		case RIGHT:
+			nx++;
+			break;
+		case NONE:
+			break;
+		}
+
+		if (((nx!=x)||(ny!=y))&&
+			(nx>=0)&&(nx<this.width)&&
+			(ny>=0)&&(ny<this.height)) {
+			x = nx;
+			y = ny;
+		}
+		
+		return new Dimension(x,y);
+	}
+
+	/** Fin du jeu
+	 */
+	private void endOfGame() {
+		for (AgentIdentifier id : this.locations.keySet()) {
+			sendMessage(id, GameMessage.END_OF_GAME);
+		}
+		killMe();
+	}
+	
+	/** Modification de la sonde sur l'état du jeu
+	 */
+	private void setStateProbe() {
+		Map<AgentIdentifier,Dimension> probedLocations = new TreeMap<AgentIdentifier,Dimension>();
+		for (Entry<AgentIdentifier,Dimension> entry : this.locations.entrySet()) {
+			probedLocations.put(entry.getKey(), 
+					new Dimension(entry.getValue()));
+		}
+		setProbe("WORLD_STATE", probedLocations); //$NON-NLS-1$
+	}
+	
+	/** Deplace un agent si possible.
+	 */
+	private void moveAgent(AgentIdentifier id, MoveDirection direction) {
+		Dimension pos = this.locations.get(id);
+		if (pos==null) return;
+
+		int x = pos.width;
+		int y = pos.height;
+		int nx = x;
+		int ny = y;
+		
+		switch(direction) {
+		case UP:
+			ny--;
+			break;
+		case DOWN:
+			ny++;
+			break;
+		case LEFT:
+			nx--;
+			break;
+		case RIGHT:
+			nx++;
+			break;
+		case NONE:
+			break;
+		}
+
+		if (((nx!=x)||(ny!=y))&&
+			(nx>=0)&&(nx<this.width)&&
+			(ny>=0)&&(ny<this.height)&&
+			(this.world[ny][nx]==null)) {
+			this.world[ny][nx] = id;
+			this.world[y][x] = null;
+			this.locations.put(id, new Dimension(nx,ny));
+		}
+	}
+	
+	/**
+	 * Cette fonction teste si la proie est encerclé (bas,haut,gauche,droite) par des prédateurs
+	 * @return vrai si la proie est encerclée
+	 */
+	private boolean verifyifPreyCatched() {
+		if (this.prey==null) return false;
+		
+		// Recherche la proie
+		Dimension pos = this.locations.get(this.prey);
+		if (pos==null) return false;
+		
+		int xPrey = pos.width;
+		int yPrey = pos.height;
+		
+		assert(xPrey>=0 && xPrey<this.width);
+		assert(yPrey>=0 && yPrey<this.height);
+		
+		// Test des quatres directions
+		int catched = 0;
+		
+		// Haut
+		if ((yPrey<=0)||(this.world[yPrey-1][xPrey]!=null))
+			catched++;
+		// Bas
+		if ((yPrey>=(this.height-1))||(this.world[yPrey+1][xPrey]!=null))
+			catched++;
+		// Gauchge
+		if ((xPrey<=0)||(this.world[yPrey][xPrey-1]!=null))
+			catched++;
+		// Bas
+		if ((xPrey>=(this.width-1))||(this.world[yPrey][xPrey+1]!=null))
+			catched++;
+		
+		return catched==4;
+	}
+	
+	@Override
+	public String toString() {
+		return "World"; //$NON-NLS-1$
+	}
+	
+	protected static void debugPositions(int width, int height, AgentIdentifier[][] grid) {
+		int[] size = new int[width];
+		Arrays.fill(size, 0);
+		
+		for (int c=0; c<width; c++) {
+			for (int r=0; r<height; r++) {
+				if ((grid[r][c]!=null)&&(size[c]<grid[r][c].getString().length()))
+					size[c] = grid[r][c].getString().length();
+			}
+		}
+		
+		for(int r=0; r<height; r++) {
+			System.out.print("| "); //$NON-NLS-1$
+			for(int c=0; c<width; c++) {
+				int s = grid[r][c]==null ? 0 : grid[r][c].getString().length();
+				if (grid[r][c]!=null) System.out.print(grid[r][c].getString());
+				for(int k=s; k<size[c]; k++)
+					System.out.print(" "); //$NON-NLS-1$
+				System.out.print(" |"); //$NON-NLS-1$
+			}
+			System.out.println(""); //$NON-NLS-1$
+		}
+	}
+
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/go-down.png
===================================================================
(Binary files differ)


Property changes on: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/go-down.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/go-next.png
===================================================================
(Binary files differ)


Property changes on: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/go-next.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/go-previous.png
===================================================================
(Binary files differ)


Property changes on: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/go-previous.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/go-up.png
===================================================================
(Binary files differ)


Property changes on: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/go-up.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/lion.png
===================================================================
(Binary files differ)


Property changes on: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/lion.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/rabbit.png
===================================================================
(Binary files differ)


Property changes on: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/rabbit.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/snake.png
===================================================================
(Binary files differ)


Property changes on: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/snake.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/wolf.png
===================================================================
(Binary files differ)


Property changes on: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator1/wolf.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/AnimalType.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/AnimalType.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/AnimalType.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,35 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator2;
+
+/** JEU DE LA PROIE ET DES PREDATEURS.
+ * <p>
+ * Travaux pratiques d'IA54.<br>
+ * Universit&eacute; de Technologie de Belfort-monb&eacute;liard.
+ * <p>
+ * Type supportes d'animaux.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+enum AnimalType {
+	PREY, LION, SNAKE
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/GUI.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/GUI.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/GUI.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,519 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator2;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Toolkit;
+import java.awt.Transparency;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.image.BufferedImage;
+import java.lang.ref.WeakReference;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Map.Entry;
+import java.util.concurrent.Executors;
+
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+
+import org.arakhne.tinyMAS.core.AgentIdentifier;
+import org.arakhne.tinyMAS.core.Kernel;
+import org.arakhne.tinyMAS.core.KernelAdapter;
+import org.arakhne.tinyMAS.core.Probe;
+import org.arakhne.tinyMAS.core.ProbeValueNotDefinedException;
+
+/** 
+ * Afficheur de l'état du monde
+ * <p>
+ * Travaux pratiques d'IA54.<br>
+ * Universit&eacute; de Technologie de Belfort-monb&eacute;liard.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public class GUI extends JPanel {
+
+	private static final long serialVersionUID = 3939643459108505034L;
+	
+	protected static final int ANIMATION_SPEED = 1;
+	protected static final int ANIMATION_STEPS = 10;
+	
+	protected static final Icon PREY_ICON;
+	protected static final Icon PREDATOR_ICON;	
+	protected static final Icon UP_ICON;
+	protected static final Icon DOWN_ICON;	
+	protected static final Icon LEFT_ICON;
+	protected static final Icon RIGHT_ICON;	
+	protected static final int ICON_WIDTH;
+	protected static final int ICON_HEIGHT;
+	
+	static {
+		URL url = GUI.class.getResource("/org/arakhne/tinyMAS/demo/preypredator1/rabbit.png"); //$NON-NLS-1$
+		assert(url!=null);
+		PREY_ICON = new ImageIcon(url);
+		url = GUI.class.getResource("/org/arakhne/tinyMAS/demo/preypredator1/lion.png"); //$NON-NLS-1$
+		assert(url!=null);
+		PREDATOR_ICON = new ImageIcon(url);
+		url = GUI.class.getResource("/org/arakhne/tinyMAS/demo/preypredator1/go-up.png"); //$NON-NLS-1$
+		assert(url!=null);
+		UP_ICON = new ImageIcon(url);
+		url = GUI.class.getResource("/org/arakhne/tinyMAS/demo/preypredator1/go-down.png"); //$NON-NLS-1$
+		assert(url!=null);
+		DOWN_ICON = new ImageIcon(url);
+		url = GUI.class.getResource("/org/arakhne/tinyMAS/demo/preypredator1/go-previous.png"); //$NON-NLS-1$
+		assert(url!=null);
+		LEFT_ICON = new ImageIcon(url);
+		url = GUI.class.getResource("/org/arakhne/tinyMAS/demo/preypredator1/go-next.png"); //$NON-NLS-1$
+		assert(url!=null);
+		RIGHT_ICON = new ImageIcon(url);
+		
+		ICON_WIDTH = Math.max(PREY_ICON.getIconWidth(), PREDATOR_ICON.getIconWidth());
+		ICON_HEIGHT = Math.max(PREY_ICON.getIconHeight(), PREDATOR_ICON.getIconHeight());
+	}
+	
+    public static Image mergeImages(Image top_icon, Image bottom_icon, int x, int y) {
+    	int imgWidth = bottom_icon.getWidth(null);
+    	int imgHeight = bottom_icon.getHeight(null);
+    	BufferedImage img = new BufferedImage(
+    			imgWidth, imgHeight,
+    			Transparency.BITMASK);
+    	Graphics g = img.getGraphics();
+    	g.setClip(0,0,imgWidth,imgHeight);
+    	g.drawImage(bottom_icon,0,0,null);
+    	if (x<0) x = imgWidth + x;
+    	if (y<0) y = imgHeight + y;
+    	g.drawImage(top_icon,x,y,null);
+    	return Toolkit.getDefaultToolkit().createImage(img.getSource());
+    }
+
+    public static Icon mergeIcons(Icon top_icon, Icon bottom_icon, int x, int y) {
+        if ((top_icon instanceof ImageIcon)&&(bottom_icon instanceof ImageIcon)) {
+        	Image new_image = mergeImages(
+    				((ImageIcon)top_icon).getImage(),
+    				((ImageIcon)bottom_icon).getImage(),
+    				x, y);
+        	if (new_image!=null)
+        		return new ImageIcon(new_image);        	
+        }
+        return null;
+    }                       
+
+    protected final Grid grid;
+	protected final RefreshThread refresher;
+	private WeakReference<Kernel<?,?,?,?>> kernel;	
+	protected Probe worldProbe;
+	protected Map<AgentIdentifier,Dimension> positions;
+	protected Map<AgentIdentifier,Dimension> nextPositions;
+	
+	public GUI() {
+		this.refresher = new RefreshThread();
+		
+		this.kernel = null;
+		
+		setLayout(new BorderLayout());
+		
+		this.grid = new Grid();
+
+		JScrollPane scroll = new JScrollPane(this.grid);
+		add(BorderLayout.CENTER,scroll);
+		
+		JButton closeBt = new JButton("Quit"); //$NON-NLS-1$
+		closeBt.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				Kernel<?,?,?,?> kernel = getKernel();
+				if (kernel!=null) kernel.stop();
+			}
+		});
+		add(BorderLayout.SOUTH, closeBt);
+		
+		setPreferredSize(new Dimension(300,350));
+	}
+	
+	public void setKernel(Kernel<?,?,?,?> kernel) {
+		if (kernel==null) {
+			this.kernel = null;
+		}
+		else {
+			this.kernel = new WeakReference<Kernel<?,?,?,?>>(kernel);
+			kernel.addKernelListener(new KernelAdapter() {
+				@Override
+				public void kernelRefreshAllowed(Kernel<?, ?, ?, ?> kernel) {
+					if (kernel==GUI.this.getKernel()) {
+						changeState();
+					}
+				}
+				@Override
+				public void kernelStarted(Kernel<?, ?, ?, ?> kernel) {
+					if (kernel==GUI.this.getKernel()) {
+						changeState();
+					}
+				}			
+			});
+		}
+	}
+	
+	public void launchRefresher() {
+		Executors.newSingleThreadExecutor().execute(this.refresher);
+	}
+	
+	public void stopRefresher() {
+		this.refresher.stop();
+	}
+
+	@SuppressWarnings("unchecked")
+	protected void changeState() {
+		Kernel<?,?,?,?> kernel = getKernel();
+		if (kernel!=null && this.worldProbe==null) {
+			AgentIdentifier[] world = kernel.getServiceProviders("WORLD_GRID"); //$NON-NLS-1$
+			if (world.length>0) {
+				this.worldProbe = kernel.getProbe(world[0]);
+			}
+		}
+		this.refresher.addMoves(this.worldProbe.getProbeValue("WORLD_STATE",Map.class)); //$NON-NLS-1$
+	}
+	
+	protected void refreshGUI(Map<AgentIdentifier,Dimension> moves) {
+		this.positions = moves;
+		this.grid.setStep(-1);
+		this.grid.repaint();
+	}
+
+	protected void refreshGUI(int moveStep, Map<AgentIdentifier,Dimension> moves) {
+		this.nextPositions = moves;
+		this.grid.setStep(moveStep);
+		this.grid.repaint();
+	}
+	
+	protected void refreshGUI(int moveStep) {
+		if (moveStep<0) {
+			this.positions = this.nextPositions;
+			//debugPositions(getKernel(), this.positions, "NEW POSITION"); //$NON-NLS-1$
+		}
+		this.grid.setStep(moveStep);
+		this.grid.repaint();
+	}
+	
+	protected Kernel<?,?,?,?> getKernel() {
+		return this.kernel==null ? null : this.kernel.get();
+	}
+	
+	protected static void debugPositions(Kernel<?,?,?,?> kernel, Map<AgentIdentifier,Dimension> positions, String str) {
+		AgentIdentifier[] world = kernel.getServiceProviders("WORLD_GRID"); //$NON-NLS-1$
+		if (world.length>0) {
+			Probe probe = kernel.getProbe(world[0]);
+			try {
+				int width = probe.getProbeInt("WIDTH"); //$NON-NLS-1$
+				int height = probe.getProbeInt("HEIGHT"); //$NON-NLS-1$
+				
+				int[] size = new int[width];
+				Arrays.fill(size, 0);
+				
+				AgentIdentifier[][] grid = new AgentIdentifier[height][width];
+				for (Entry<AgentIdentifier, Dimension> entry : positions.entrySet()) {
+					int h = entry.getValue().height;
+					int w = entry.getValue().width;
+					assert(grid[h][w]==null);
+					grid[h][w] = entry.getKey();
+					if (size[w]<grid[h][w].getString().length())
+						size[w] = grid[h][w].getString().length();
+				}
+				
+				System.out.println(">>"+str+"<<"); //$NON-NLS-1$ //$NON-NLS-2$
+				for(int r=0; r<height; r++) {
+					System.out.print("| "); //$NON-NLS-1$
+					for(int c=0; c<width; c++) {
+						int s = grid[r][c]==null ? 0 : grid[r][c].getString().length();
+						if (grid[r][c]!=null) System.out.print(grid[r][c].getString());
+						for(int k=s; k<size[c]; k++)
+							System.out.print(" "); //$NON-NLS-1$
+						System.out.print(" |"); //$NON-NLS-1$
+					}
+					System.out.println(""); //$NON-NLS-1$
+				}
+				
+				return;
+			}
+			catch(ProbeValueNotDefinedException _) {
+				//
+			}			
+		}
+		throw new Error("UNABLE TO OBTAIN A PROBE"); //$NON-NLS-1$
+	}
+	
+	private class RefreshThread implements Runnable {
+
+		private final Queue<Map<AgentIdentifier,Dimension>> queue = new LinkedList<Map<AgentIdentifier,Dimension>>(); 
+		
+		private boolean run = true;
+		private int moveStep = -2;
+
+		public RefreshThread() {
+			//
+		}
+		
+		public void stop() {
+			this.run = false;
+		}
+		
+		public void run() {
+			while (this.run) {
+				if (this.moveStep<0) {
+					Map<AgentIdentifier,Dimension> moves = this.queue.poll();
+					if (moves!=null) {
+						if (this.moveStep==-1) {
+							this.moveStep = 0;
+							GUI.this.refreshGUI(this.moveStep, moves);
+						}
+						else if (this.moveStep==-2) {
+							this.moveStep = -1;
+							GUI.this.refreshGUI(moves);
+						}
+					}
+				}
+				else {
+					try {
+						Thread.sleep((1000*ANIMATION_SPEED)/ANIMATION_STEPS);
+					}
+					catch (InterruptedException e) {
+						//
+					}
+					if (this.moveStep>=ANIMATION_STEPS) {
+						this.moveStep = -1;
+					}
+					else {
+						this.moveStep++;
+					}
+					GUI.this.refreshGUI(this.moveStep);
+				}
+				Thread.yield();
+			}
+		}
+		
+		public void addMoves(Map<AgentIdentifier,Dimension> moves) {
+			if (moves!=null) {
+				Map<AgentIdentifier,Dimension> old = this.queue.peek();
+				if ((old==null)||(!old.equals(moves))) {
+					this.queue.offer(moves);
+				}
+			}
+		}
+		
+	}
+	
+	private class Grid extends JPanel {
+		
+		private static final long serialVersionUID = 4361140442107583935L;
+		
+		private int moveStep = -1;
+		
+		public Grid() {
+			//
+		}
+		
+		public void setStep(int step) {
+			this.moveStep = step;
+		}
+		
+		@Override
+		public void paint(Graphics g) {
+			super.paint(g);
+			Graphics2D g2d = (Graphics2D)g;
+			
+			Dimension currentDim = getPreferredSize();
+			Dimension desiredDim = computeDesiredDim();
+			
+			if ((desiredDim!=null)&&(!currentDim.equals(desiredDim))) {
+				setPreferredSize(desiredDim);
+				revalidate();
+				repaint();
+				return;
+			}
+			
+			if (this.moveStep>=0) {
+				drawMovingAgents(g2d, currentDim);
+			}
+			else {
+				drawAgents(g2d, currentDim);					
+			}
+			
+			drawGrid(g2d, currentDim);
+		}
+		
+		private void drawMovingAgents(Graphics2D g2d, Dimension currentDim) {
+			if ((this.moveStep<0)||
+				(GUI.this.nextPositions==null)||
+				(GUI.this.positions==null)) drawAgents(g2d, currentDim);
+			
+			int x, y, deltaX, deltaY;
+			Dimension d;
+			Dimension nextD;
+			AgentIdentifier id;
+			
+			Probe probe = getProbe();
+			if (probe==null) return;
+			AgentIdentifier prey = probe.getProbeValue("PREY", AgentIdentifier.class); //$NON-NLS-1$
+			deltaX = ((this.moveStep * ICON_WIDTH) / ANIMATION_STEPS);
+			deltaY = ((this.moveStep * ICON_HEIGHT) / ANIMATION_STEPS);
+			
+			Icon ic;
+
+			for (Entry<AgentIdentifier, Dimension> entry : GUI.this.positions.entrySet()) {
+				id = entry.getKey();
+				d = entry.getValue();
+				if (GUI.this.nextPositions.containsKey(id)) {
+					nextD = GUI.this.nextPositions.get(id);
+					x = d.width * ICON_WIDTH;
+					y = d.height * ICON_HEIGHT;
+					
+					if (nextD.width<d.width) {
+						x -= deltaX;
+					}
+					else if (nextD.width>d.width) {
+						x += deltaX;
+					}
+										
+					if (nextD.height<d.height) {
+						y -= deltaY;
+					}
+					else if (nextD.height>d.height) {
+						y += deltaY;
+					}
+
+					ic = getIcon(id.equals(prey), getLastDirection(id));
+					assert(ic!=null);
+					ic.paintIcon(this, g2d, x, y);
+				}
+			}
+		}
+		
+		private void drawAgents(Graphics2D g2d, Dimension currentDim) {
+			if (GUI.this.positions==null) return;
+			int x, y;
+			Dimension d;
+			Probe probe = getProbe();
+			if (probe==null) return;
+			AgentIdentifier prey = probe.getProbeValue("PREY", AgentIdentifier.class); //$NON-NLS-1$
+			Icon ic;
+			for (Entry<AgentIdentifier, Dimension> entry : GUI.this.positions.entrySet()) {
+				d = entry.getValue();
+				x = d.width * ICON_WIDTH;
+				y = d.height * ICON_HEIGHT;
+				
+				ic = getIcon(entry.getKey().equals(prey), getLastDirection(entry.getKey()));
+				assert(ic!=null);
+				ic.paintIcon(this, g2d, x, y);
+			}
+		}
+		
+		private void drawGrid(Graphics2D g2d, Dimension currentDim) {
+			int x, y;
+			g2d.setColor(Color.BLACK);
+			for(x=0; x<=currentDim.width; x+=ICON_WIDTH) {
+				g2d.drawLine(x, 0, x, currentDim.height); 
+			}
+			for(y=0; y<=currentDim.height; y+=ICON_WIDTH) {
+				g2d.drawLine(0, y, currentDim.width, y); 
+			}
+		}
+		
+		private Probe getProbe() {
+			Kernel<?,?,?,?> kernel = GUI.this.getKernel();
+			if (kernel!=null) {
+				AgentIdentifier[] world = kernel.getServiceProviders("WORLD_GRID"); //$NON-NLS-1$
+				if (world.length>0) {
+					return kernel.getProbe(world[0]);
+				}
+			}
+			return null;
+		}
+		
+		private Dimension computeDesiredDim() {
+			Probe probe = getProbe();
+			if (probe!=null) {
+				try {
+					int width = probe.getProbeInt("WIDTH"); //$NON-NLS-1$
+					int height = probe.getProbeInt("HEIGHT"); //$NON-NLS-1$
+					
+					return new Dimension(width*GUI.ICON_WIDTH, height*GUI.ICON_HEIGHT);
+				}
+				catch(ProbeValueNotDefinedException _) {
+					//
+				}
+			}
+			return null;
+		}
+		
+		private MoveDirection getLastDirection(AgentIdentifier id) {
+			Kernel<?,?,?,?> kernel = GUI.this.getKernel();
+			if (kernel==null) return MoveDirection.NONE;
+			Probe probe = kernel.getProbe(id);
+			return probe.getProbeValue("LAST_MOVE", MoveDirection.class); //$NON-NLS-1$
+		}
+		
+		private Icon getIcon(boolean isPrey, MoveDirection direction) {
+			Icon ic;
+			if (isPrey) {
+				ic = PREY_ICON;
+			}
+			else {
+				ic = PREDATOR_ICON;
+			}
+			
+			switch(direction) {
+			case UP:
+				ic = mergeIcons(UP_ICON, ic, 
+						(ic.getIconWidth()-UP_ICON.getIconWidth())/2, 0);
+				break;
+			case DOWN:
+				ic = mergeIcons(DOWN_ICON, ic, 
+						(ic.getIconWidth()-DOWN_ICON.getIconWidth())/2,
+						ic.getIconHeight() - DOWN_ICON.getIconHeight());
+				break;
+			case LEFT:
+				ic = mergeIcons(LEFT_ICON, ic,
+						0,
+						(ic.getIconHeight()-LEFT_ICON.getIconHeight())/2);
+				break;
+			case RIGHT:
+				ic = mergeIcons(RIGHT_ICON, ic, 
+						ic.getIconWidth() - RIGHT_ICON.getIconWidth(),
+						(ic.getIconHeight()-RIGHT_ICON.getIconHeight())/2);
+				break;
+			case NONE:
+			}
+			
+			return ic;
+		}
+	}
+	
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/GUIWindow.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/GUIWindow.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/GUIWindow.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,85 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator2;
+
+import java.awt.BorderLayout;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+
+import javax.swing.JFrame;
+import javax.swing.WindowConstants;
+
+import org.arakhne.tinyMAS.core.Kernel;
+
+/** 
+ * Afficheur de l'état du monde
+ * <p>
+ * Travaux pratiques d'IA54.<br>
+ * Universit&eacute; de Technologie de Belfort-monb&eacute;liard.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public class GUIWindow extends JFrame {
+
+	private static final long serialVersionUID = 3939643459108505034L;
+	
+    protected final GUI gui;
+	
+	public GUIWindow(Kernel<?,?,?,?> kernel) {
+		this.gui = new GUI();
+		this.gui.setKernel(kernel);
+		
+		Container content = getContentPane();
+		
+		content.setLayout(new BorderLayout());
+		
+		content.add(BorderLayout.CENTER,this.gui);
+		
+		setPreferredSize(new Dimension(300,350));
+		
+		addWindowListener(new WindowAdapter() {
+			@Override
+			public void windowClosed(WindowEvent e) {
+				Kernel<?,?,?,?> kernel = GUIWindow.this.getKernel();
+				kernel.stop();
+			}
+			@Override
+			public void windowClosing(WindowEvent e) {
+				Kernel<?,?,?,?> kernel = GUIWindow.this.getKernel();
+				kernel.stop();
+			}
+		});
+		
+		setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+		
+		pack();
+		
+		this.gui.launchRefresher();
+	}
+	
+	protected Kernel<?,?,?,?> getKernel() {
+		return this.gui.getKernel();
+	}
+	
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/Game.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/Game.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/Game.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,112 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator2;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.arakhne.tinyMAS.core.AbstractScheduler;
+import org.arakhne.tinyMAS.core.Agent;
+import org.arakhne.tinyMAS.core.Kernel;
+
+/** JEU DE LA PROIE ET DES PREDATEURS.
+ * <p>
+ * Travaux pratiques d'IA54.<br>
+ * Universit&eacute; de Technologie de Belfort-monb&eacute;liard.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+@SuppressWarnings("unchecked")
+public class Game extends Kernel {
+
+	private static final int SNAKE_COUNT = 5;
+	private static final int LION_COUNT = 5;
+	
+	private static final int WORLD_SIZE_X = 10;
+	private static final int WORLD_SIZE_Y = 10;
+	
+	public Game() {
+	super(new AbstractScheduler<Agent>() {
+			public void schedule(List<Agent> agents) {
+				Agent world = null;
+				ArrayList<Agent> animats = new ArrayList<Agent>();
+				for (Agent agent : agents) {
+					if (agent instanceof WorldGrid)
+						world = agent;
+					else
+						animats.add(agent);
+				}
+
+				Collections.shuffle(animats);
+				for (Agent agent : animats) {
+					agent.live();
+				}
+				
+				if (world!=null)
+					world.live();
+			}
+		});
+	}
+	
+	/** Programme Principal
+	 */	
+	public static void main(String[] argv) {
+		
+		System.out.println("Prey and Predator demonstrator #2"); //$NON-NLS-1$
+		System.out.println("Copyright (c) 2005-2009 Stéphane GALLAND and Nicolas GAUD "); //$NON-NLS-1$
+		System.out.println("Thanks to Julia Nikolaeva aka. Flameia for the icons <flameia@xxxxxxxxxxxx>"); //$NON-NLS-1$
+		
+		Game j = new Game() ;
+		
+		j.setWaitingDuration(3000);
+		
+		WorldGrid g = new WorldGrid(WORLD_SIZE_X,WORLD_SIZE_Y) ;
+		j.addAgent(g) ;
+
+		Agent a = new Prey() ;		
+		j.addAgent(a) ;
+		g.addAgent(a.getId(),AnimalType.PREY) ;		 
+
+		for(int i=0; i<SNAKE_COUNT; i++) {
+			a = new Snake() ;		
+			j.addAgent(a) ;
+			g.addAgent(a.getId(),AnimalType.SNAKE) ;
+		}
+
+		for(int i=0; i<LION_COUNT; i++) {
+			a = new Lion() ;		
+			j.addAgent(a) ;
+			g.addAgent(a.getId(),AnimalType.LION) ;
+		}
+
+		GUIWindow gui = new GUIWindow(j);
+		gui.setVisible(true);
+		
+		j.run() ;
+		
+		// Force quit
+		System.exit(0);
+		
+	}
+
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/GameMessage.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/GameMessage.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/GameMessage.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,36 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator2;
+
+/** 
+ * Message de gestion du jeu
+ * <p>
+ * Travaux pratiques d'IA54.<br>
+ * Universit&eacute; de Technologie de Belfort-monb&eacute;liard.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public enum GameMessage {
+
+	END_OF_GAME,
+	
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/Lion.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/Lion.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/Lion.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,125 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator2;
+
+/** AGENT PREDATEUR
+ * <p>
+ * Travaux pratiques d'IA54.<br>
+ * Universit&eacute; de Technologie de Belfort-monb&eacute;liard.
+ * <p>
+ * Un lion essaye de coincer une proie.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public class Lion extends PerceptiveAgent {
+
+	private static int PREDATOR_COUNT = 0;
+	
+	private final int number;
+	
+	public Lion() {
+		this.number = PREDATOR_COUNT++;
+	}
+	
+	@Override
+	public String toString() {
+		return "Lion #"+this.number; //$NON-NLS-1$
+	}
+
+	@Override
+	public void start() {
+		forceIdentifierStringRepresentation();
+		setProbe("ANIMAL_TYPE", AnimalType.LION); //$NON-NLS-1$
+	}
+
+	/** L'agent predateur se deplace en fonction de ses perceptions.
+	 */ 	
+	@Override
+	protected void live(PerceptionType[][] percepts) {
+		// Analyse les perception afin de detecter la proie
+		int preyX = 0, preyY = 0;
+		boolean preyFound = false;
+		for(int r=0; r<percepts.length; r++) {
+			for(int c=0; c<percepts[r].length; c++) {
+				if (percepts[r][c]==PerceptionType.PREY) {
+					preyX = -2+c;
+					preyY = -2+r;
+					preyFound = true;
+					break;
+				}
+			}
+		}
+		
+		MoveDirection direction;
+
+		if (!preyFound) {
+			// Le lion se déplace au hasard
+			direction = computeMove(true);
+		}
+		else if ((preyX==0)&&(preyY<-1)) {
+			// Le lion suit la proie 
+			direction = MoveDirection.UP;
+		}
+		else if ((preyX==0)&&(preyY>1)) {
+			// Le lion suit la proie 
+			direction = MoveDirection.DOWN;
+		}
+		else if ((preyX<-1)&&(preyY==0)) {
+			// Le lion suit la proie 
+			direction = MoveDirection.LEFT;
+		}
+		else if ((preyX>1)&&(preyY==0)) {
+			// Le lion suit la proie 
+			direction = MoveDirection.RIGHT;
+		}
+		else if ((preyX<0)&&(preyY<0)) {
+			// Le lion suit la proie 
+			direction = computeMove(MoveDirection.LEFT, MoveDirection.UP);
+		}
+		else if ((preyX<0)&&(preyY>0)) {
+			// Le lion suit la proie 
+			direction = computeMove(MoveDirection.LEFT, MoveDirection.DOWN);
+		}
+		else if ((preyX>0)&&(preyY<0)) {
+			// Le lion suit la proie 
+			direction = computeMove(MoveDirection.RIGHT, MoveDirection.UP);
+		}
+		else if ((preyX>0)&&(preyY>0)) {
+			// Le lion suit la proie 
+			direction = computeMove(MoveDirection.RIGHT, MoveDirection.DOWN);
+		}
+		else {
+			// Le lion se trouve prêt de la proie, il ne veut pas bouger
+			direction = MoveDirection.NONE;
+		}
+
+		/*drawPercepts(percepts);
+		
+		System.out.print("found prey="+preyFound);
+		System.out.print(";preyX="+preyX);
+		System.out.print(";preyY="+preyY);
+		System.out.println(";direction="+direction);*/
+		
+		moveTo(direction);
+	}
+	
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/MovableAgent.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/MovableAgent.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/MovableAgent.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,74 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator2;
+
+import org.arakhne.tinyMAS.core.Agent;
+import org.arakhne.tinyMAS.core.AgentIdentifier;
+import org.arakhne.tinyMAS.core.Kernel;
+
+/** Un agent capable de se deplacer dans le monde du
+ *  jeu "Proie et Predateurs".
+ * <p>
+ * Travaux pratiques d'IA54.<br>
+ * Universit&eacute; de Technologie de Belfort-monb&eacute;liard.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public abstract class MovableAgent extends Agent {
+
+	/** Deplace l'agent dans la direction indiquee.
+	 * 
+	 * @param direction  
+	 * @return <code>true</code> si le mouvement est envoye.
+	 */	
+	protected boolean moveTo(MoveDirection direction) {
+		// Get the agent that provide a world grid service 
+		AgentIdentifier id = Kernel.getSingleton().getYellowPageSystem().getAgentFor("WORLD_GRID"); //$NON-NLS-1$
+		assert(id!=null);
+		// Send the message to the agent
+		setProbe("LAST_MOVE", direction); //$NON-NLS-1$
+		return sendMessage(id, direction) ;
+	}
+	
+	/** Tire au hasard une direction.
+	 */
+	protected MoveDirection computeMove(boolean allow_no_move) {
+		int tries = 0;
+		MoveDirection[] values = MoveDirection.values();
+		MoveDirection selected;
+		do {
+			int direction = (int)(Math.random() * values.length * 10.)/10 ;
+			selected = values[direction];
+			tries++;
+		}
+		while ((!allow_no_move)&&(selected==MoveDirection.NONE)&&(tries<10));
+		return selected;
+	}
+	
+	/** Tire au hasard une direction parmi celles fournies.
+	 */
+	protected MoveDirection computeMove(MoveDirection... allowedDirections) {
+		int direction = (int)(Math.random() * allowedDirections.length * 10.)/10 ;
+		return allowedDirections[direction];
+	}
+
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/MoveDirection.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/MoveDirection.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/MoveDirection.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,44 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator2;
+
+/** 
+ * Direction de deplacement pour les proies et les predateurs
+ * <p>
+ * Travaux pratiques d'IA54.<br>
+ * Universit&eacute; de Technologie de Belfort-monb&eacute;liard.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public enum MoveDirection {
+
+	NONE,
+	
+	UP,
+	
+	DOWN,
+	
+	LEFT,
+	
+	RIGHT;
+	
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/PerceptionType.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/PerceptionType.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/PerceptionType.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,48 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator2;
+
+/** JEU DE LA PROIE ET DES PREDATEURS.
+ * <p>
+ * Travaux pratiques d'IA54.<br>
+ * Universit&eacute; de Technologie de Belfort-monb&eacute;liard.
+ * <p>
+ * Type de perceptions.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+enum PerceptionType {
+	PREY, LION, SNAKE, THENEANT;
+	
+	public static PerceptionType fromAnimalType(AnimalType type) {
+		switch(type) {
+		case LION:
+			return LION;
+		case SNAKE:
+			return SNAKE;
+		case PREY:
+			return PREY;
+		default:
+			return null;
+		}
+	}
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/PerceptiveAgent.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/PerceptiveAgent.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/PerceptiveAgent.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,86 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator2;
+
+import org.arakhne.tinyMAS.core.Message;
+
+/** Un agent capable de se deplacer dans le monde du
+ *  jeu "Proie et Predateurs".
+ * <p>
+ * Travaux pratiques d'IA54.<br>
+ * Universit&eacute; de Technologie de Belfort-monb&eacute;liard.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public abstract class PerceptiveAgent extends MovableAgent {
+	
+	/** L'agent predateur se deplace en fonction de ses perceptions.
+	 */ 	
+	@Override
+	public final void live() {
+		boolean eog = false;
+		PerceptionType[][] percepts = new PerceptionType[5][5];
+		
+		while (hasMessage()) {
+			Message msg = getNextMessage();
+			if (msg.CONTENT instanceof GameMessage) {
+				GameMessage gmsg = (GameMessage)(msg.CONTENT);
+				if (gmsg==GameMessage.END_OF_GAME) {
+					eog = true;
+				}
+			}
+			else if (msg.CONTENT instanceof PerceptionType[][]) {
+				PerceptionType[][] worldPercepts = (PerceptionType[][])(msg.CONTENT);
+				for(int r=0; (r<worldPercepts.length)&&(r<5); r++) {
+					for(int c=0; (c<worldPercepts[r].length)&&(c<5); c++) {
+						percepts[r][c] = worldPercepts[r][c];
+					}
+				}
+				percepts[2][2] = null;
+			}
+		}
+
+		if (eog) {
+			killMe();
+		}
+		else {
+			live(percepts);
+		}
+	}
+
+	/** L'agent predateur se deplace en fonction de ses perceptions.
+	 */ 	
+	protected abstract void live(PerceptionType[][] percepts);
+
+	/** Draw the specified percepts.
+	 */
+	protected void drawPercepts(PerceptionType[][] percepts) {
+		System.out.println(getId().getString());
+		for(int r=0; r<5; r++) {
+			for(int c=0; c<5; c++) {
+				System.out.print("\t"+percepts[r][c]); //$NON-NLS-1$
+			}
+			System.out.print("\n"); //$NON-NLS-1$
+		}
+	}
+	
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/Prey.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/Prey.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/Prey.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,165 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator2;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/** AGENT PROIE
+ * <p>
+ * Travaux pratiques d'IA54.<br>
+ * Universit&eacute; de Technologie de Belfort-monb&eacute;liard.
+ * <p>
+ * Une proie essaye de fuir les predateurs.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public class Prey extends PerceptiveAgent {
+
+	/** Draw the specified percepts.
+	 */
+	protected void drawDangerMatrix(int[][] percepts) {
+		System.out.println(getId().getString());
+		for(int r=0; r<5; r++) {
+			for(int c=0; c<5; c++) {
+				System.out.print("\t"+percepts[r][c]); //$NON-NLS-1$
+			}
+			System.out.print("\n"); //$NON-NLS-1$
+		}
+	}
+
+	@Override
+	public String toString() {
+		return "Prey"; //$NON-NLS-1$
+	}
+
+	@Override
+	public void start() {
+		setProbe("CATCHED", false); //$NON-NLS-1$
+		setProbe("ANIMAL_TYPE", AnimalType.PREY); //$NON-NLS-1$
+		forceIdentifierStringRepresentation();
+	}
+	
+	private int computeLength(PerceptionType[][] percepts) {
+		int max = 0;
+		for(int r=0; r<percepts.length; r++) {
+			if (max<percepts[r].length)
+				max = percepts[r].length;
+		}
+		return max;
+	}
+	
+	private void fillDangerGrid(int[][] grid, int x, int y, int maxX, int maxY, int cellDanger) {
+		assert(x>=0 && x<maxX);
+		assert(y>=0 && y<maxY);
+		
+		if (grid[y][x]<cellDanger) {
+			grid[y][x] = cellDanger;
+			if (x>0) fillDangerGrid(grid,x-1,y,maxX,maxY,cellDanger-1);
+			if (x<maxX-1) fillDangerGrid(grid,x+1,y,maxX,maxY,cellDanger-1);
+			if (y>0) fillDangerGrid(grid,x,y-1,maxX,maxY,cellDanger-1);
+			if (y<maxY-1) fillDangerGrid(grid,x,y+1,maxX,maxY,cellDanger-1);
+		}
+	}
+		
+	private int[][] computeDanger(PerceptionType[][] percepts) {
+		int size = computeLength(percepts);
+		int maxDistance = size*percepts.length;
+
+		// Initialize
+		int[][] danger = new int[percepts.length][size];		
+		for(int r=0; r<percepts.length; r++) {
+			danger[r] = new int[percepts[r].length];
+			Arrays.fill(danger[r], 0);
+		}
+		
+		// Compute the dangerousity of each cell
+		for(int r=0; r<percepts.length; r++) {
+			for(int c=0; c<percepts[r].length; c++) {
+				if (percepts[r][c]!=null) {
+					int cellDanger = (percepts[r][c]==PerceptionType.THENEANT) ? maxDistance/2 : maxDistance;
+					fillDangerGrid(danger,c,r,size,percepts.length,cellDanger);
+				}
+			}
+		}
+		
+		
+		return danger;
+	}
+	
+	/** L'agent se deplace aleatoirement en fonction de ses perceptions.
+	 */	
+	@Override
+	protected void live(PerceptionType[][] percepts) {
+		
+		//drawPercepts(percepts);
+
+		int[][] dangerMatrix = computeDanger(percepts);
+		
+		//drawDangerMatrix(dangerMatrix);
+
+		int[] dangers = new int[] {
+				percepts[1][2]==PerceptionType.THENEANT ? Integer.MAX_VALUE : dangerMatrix[1][2], // haut
+				percepts[3][2]==PerceptionType.THENEANT ? Integer.MAX_VALUE : dangerMatrix[3][2], // bas
+				percepts[2][1]==PerceptionType.THENEANT ? Integer.MAX_VALUE : dangerMatrix[2][1], // left
+				percepts[2][3]==PerceptionType.THENEANT ? Integer.MAX_VALUE : dangerMatrix[2][3], // right
+		};
+		
+		ArrayList<Integer> mins = new ArrayList<Integer>();
+		int minDanger = dangers[0];
+		mins.add(0);
+		for(int i=1; i<4; i++) {
+			if (minDanger>dangers[i]) {
+				minDanger = dangers[i];
+				mins.clear();
+				mins.add(i);
+			}
+			else if (minDanger==dangers[i]) {
+				mins.add(i);
+			}
+		}
+		
+		MoveDirection[] directions = new MoveDirection[mins.size()];
+		for(int i=0; i<mins.size(); i++) {
+			switch(mins.get(i)) {
+			case 0:
+				directions[i] = MoveDirection.UP;
+				break;
+			case 1:
+				directions[i] = MoveDirection.DOWN;
+				break;
+			case 2:
+				directions[i] = MoveDirection.LEFT;
+				break;
+			case 3:
+				directions[i] = MoveDirection.RIGHT;
+				break;
+			default:
+				directions[i] = MoveDirection.NONE;
+				break;
+			}
+		}
+		
+		moveTo(computeMove(directions));
+	}
+	
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/Snake.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/Snake.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/Snake.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,80 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator2;
+
+import org.arakhne.tinyMAS.core.Message;
+
+/** AGENT PREDATEUR
+ * <p>
+ * Travaux pratiques d'IA54.<br>
+ * Universit&eacute; de Technologie de Belfort-monb&eacute;liard.
+ * <p>
+ * Un serpent se déplace au hasard.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public class Snake extends MovableAgent {
+
+	private static int PREDATOR_COUNT = 0;
+	
+	private final int number;
+	
+	public Snake() {
+		this.number = PREDATOR_COUNT++;
+	}
+	
+	@Override
+	public String toString() {
+		return "Snake #"+this.number; //$NON-NLS-1$
+	}
+
+	@Override
+	public void start() {
+		forceIdentifierStringRepresentation();
+		setProbe("ANIMAL_TYPE", AnimalType.SNAKE); //$NON-NLS-1$
+	}
+
+	/** L'agent predateur se deplace aleatoirement.
+	 */ 	
+	@Override
+	public void live() {
+		boolean eog = false;
+		
+		while (hasMessage()) {
+			Message msg = getNextMessage();
+			if (msg.CONTENT instanceof GameMessage) {
+				GameMessage gmsg = (GameMessage)(msg.CONTENT);
+				if (gmsg==GameMessage.END_OF_GAME) {
+					eog = true;
+				}
+			}
+		}
+
+		if (eog) {
+			killMe();
+		}
+		else {
+			moveTo(computeMove(true));
+		}
+	}
+	
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/TinyMASApplet.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/TinyMASApplet.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/TinyMASApplet.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,128 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator2;
+
+import java.awt.BorderLayout;
+
+import javax.swing.JApplet;
+
+import org.arakhne.tinyMAS.core.Agent;
+
+/** 
+ * Afficheur de l'état du monde
+ * <p>
+ * Travaux pratiques d'IA54.<br>
+ * Universit&eacute; de Technologie de Belfort-monb&eacute;liard.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public class TinyMASApplet extends JApplet {
+
+	private static final long serialVersionUID = 1L;
+
+	private static final int SNAKE_COUNT = 5;
+	private static final int LION_COUNT = 5;
+	
+	private static final int WORLD_SIZE_X = 10;
+	private static final int WORLD_SIZE_Y = 10;
+	
+	volatile Game game;
+	final GUI gui;
+	
+	public TinyMASApplet() {
+		this.game = null;
+		this.gui = new GUI();
+		setLayout(new BorderLayout());
+		add(this.gui, BorderLayout.CENTER);
+	}
+	
+	void initGame() {
+		this.game = new Game() ;
+		
+		this.game.setWaitingDuration(3000);
+		
+		WorldGrid g = new WorldGrid(WORLD_SIZE_X,WORLD_SIZE_Y) ;
+		this.game.addAgent(g) ;
+
+		Agent a = new Prey() ;		
+		this.game.addAgent(a) ;
+		g.addAgent(a.getId(),AnimalType.PREY) ;		 
+
+		for(int i=0; i<SNAKE_COUNT; i++) {
+			a = new Snake() ;		
+			this.game.addAgent(a) ;
+			g.addAgent(a.getId(),AnimalType.SNAKE) ;
+		}
+
+		for(int i=0; i<LION_COUNT; i++) {
+			a = new Lion() ;		
+			this.game.addAgent(a) ;
+			g.addAgent(a.getId(),AnimalType.LION) ;
+		}
+		
+		this.gui.setKernel(this.game);
+		this.gui.launchRefresher();
+		
+		new Thread() {
+			@Override
+			public void run() {
+				Game game = TinyMASApplet.this.game;
+				game.run();
+				destroyGame();
+			}
+		}.start();
+	}
+	
+	void destroyGame() {
+		this.gui.stopRefresher();
+		this.gui.setKernel(null);
+		this.game = null;
+	}
+
+	@Override
+	public void destroy() {
+		if (this.game==null) this.game.stop();
+		super.destroy();
+	}
+
+	@Override
+	public void start() {
+		super.start();
+		if (this.game==null) {
+			initGame();
+		}
+		else {
+			this.game.pause();
+		}
+	}
+
+	@Override
+	public void stop() {
+		if (this.game!=null) {
+			this.game.stop();
+		}
+		super.stop();
+	}
+	
+	
+	
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/WorldGrid.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/WorldGrid.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/WorldGrid.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,379 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator2;
+
+import java.awt.Dimension;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.Map.Entry;
+
+import org.arakhne.tinyMAS.core.Agent;
+import org.arakhne.tinyMAS.core.AgentIdentifier;
+import org.arakhne.tinyMAS.core.Message;
+
+/** 
+ * AGENT GRILLE.
+ * L'environnement de notre simulation.
+ * <p>
+ * Travaux pratiques d'IA54.<br>
+ * Universit&eacute; de Technologie de Belfort-monb&eacute;liard.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public class WorldGrid extends Agent {
+
+	private final AgentIdentifier[][] world;
+	private final int width;
+	private final int height;
+	private AgentIdentifier prey;
+	private final Map<AgentIdentifier,Dimension> locations = new TreeMap<AgentIdentifier,Dimension>();
+	private final Map<AgentIdentifier,AnimalType> types = new TreeMap<AgentIdentifier,AnimalType>();
+	
+	private final Map<AgentIdentifier,MoveDirection> awaitingMessages = new TreeMap<AgentIdentifier,MoveDirection>();
+	
+	/** Construit un monde.
+	 * @param x taille du monde
+	 * @param y taille du monde
+	 */	
+	public WorldGrid(int x, int y) {
+		this.world = new AgentIdentifier[y][x];
+		this.width = x;
+		this.height = y;
+	}
+	
+	/** Informe l'agent qu'il demarre sa vie.
+	 *  <p>
+	 *  Cette methode initialise les attributs de l'agent.
+	 */
+	@Override
+	public void start() {
+		forceIdentifierStringRepresentation();
+		registerService("WORLD_GRID"); //$NON-NLS-1$
+		setProbe("CATCHED", false); //$NON-NLS-1$
+		setProbe("WIDTH", this.width); //$NON-NLS-1$
+		setProbe("HEIGHT", this.height); //$NON-NLS-1$
+		setStateProbe();
+	}
+
+	/** Ajoute aleatoirement un agent dans le monde.
+	 * 
+	 * @param id est l'identificateur de l'agent a ajouter.
+	 * @param type est le type de l'animal a ajouter.
+	 */
+	public void addAgent(AgentIdentifier id, AnimalType type) {
+		if ((type==AnimalType.PREY)&&(this.prey!=null))
+			throw new IllegalArgumentException("is_prey"); //$NON-NLS-1$
+		
+		int x, y;
+		Random rnd = new Random();
+		do {
+			x = rnd.nextInt(this.width);
+			y = rnd.nextInt(this.height);
+		}
+		while (this.world[y][x]!=null);
+		
+		this.world[y][x] = id;
+		this.locations.put(id, new Dimension(x,y));
+		this.types.put(id, type);
+		if (type==AnimalType.PREY) {
+			this.prey = id;
+			setProbe("PREY", id); //$NON-NLS-1$
+		}
+	}
+	
+	/** Traite les messages provenant des agents et deplace
+	 *  les si cela est possible.
+	 */
+	@Override
+	public void live() {
+		while (hasMessage()) {
+			Message msg = getNextMessage();
+			if ((!this.awaitingMessages.containsKey(msg.FROM))&&
+				(msg.CONTENT instanceof MoveDirection)) {
+				this.awaitingMessages.put(msg.FROM, (MoveDirection)msg.CONTENT);
+			}
+			else {
+				System.err.println("Le monde vient d'ignorer un message provenant de "+msg.FROM); //$NON-NLS-1$
+			}
+		}
+		
+		if (this.awaitingMessages.size()==this.locations.size()) {
+			// Tous les agents ont envoye un message
+			
+			// Calcul les positions desirees par les agents
+			Map<AgentIdentifier, Dimension> desiredPositions = new TreeMap<AgentIdentifier,Dimension>();
+			for (Entry<AgentIdentifier,MoveDirection> entry : this.awaitingMessages.entrySet()) {
+				desiredPositions.put(entry.getKey(), predictMove(entry.getKey(), entry.getValue()));
+			}
+				
+			// Detection de conflits
+			Map<Dimension, Set<AgentIdentifier>> conflicts = new HashMap<Dimension,Set<AgentIdentifier>>();
+			for (Entry<AgentIdentifier,Dimension> entry1 : desiredPositions.entrySet()) {
+				for (Entry<AgentIdentifier,Dimension> entry2 : desiredPositions.entrySet()) {
+					if (!entry1.getKey().equals(entry2.getKey())) {
+						if (entry1.getValue().equals(entry2.getValue())) {
+							// Conflit
+							Set<AgentIdentifier> conflictedAgents = conflicts.get(entry1.getValue());
+							if (conflictedAgents==null) {
+								conflictedAgents = new HashSet<AgentIdentifier>();
+								conflicts.put(entry1.getValue(), conflictedAgents);
+							}
+							conflictedAgents.add(entry1.getKey());
+							conflictedAgents.add(entry2.getKey());
+						}
+					}
+				}
+			}
+			
+			// Resolution des conflits
+			// Choix aleatoire d'un des agents
+			Random rnd = new Random();
+			int idx;
+			AgentIdentifier[] tab;
+			for (Entry<Dimension,Set<AgentIdentifier>> entry : conflicts.entrySet()) {
+				tab = new AgentIdentifier[entry.getValue().size()];
+				entry.getValue().toArray(tab);
+				idx = rnd.nextInt(tab.length);
+				moveAgent(tab[idx], this.awaitingMessages.get(tab[idx]));
+				for (AgentIdentifier agentId : tab) {
+					desiredPositions.remove(agentId);
+				}
+			}
+			
+			// Changement de position des agents n'ayant pas provoque de conflit
+			for (AgentIdentifier agentId : desiredPositions.keySet()) {
+				moveAgent(agentId,this.awaitingMessages.get(agentId));
+			}
+						
+			// Vide les tampons
+			desiredPositions.clear();
+			conflicts.clear();
+			this.awaitingMessages.clear();
+			
+			setStateProbe();
+			
+			//debugPositions(this.width, this.height, this.world);
+			
+			// Verification de l'etat du jeu
+			if (verifyifPreyCatched()) {
+				setProbe("CATCHED", true); //$NON-NLS-1$
+				System.out.println("The prey was catched"); //$NON-NLS-1$
+				debugPositions(this.width, this.height, this.world);
+				endOfGame();
+			}
+			
+			// Calcul les perceptions
+			for (Entry<AgentIdentifier,Dimension> entry : this.locations.entrySet()) {
+				AgentIdentifier id = entry.getKey();
+				Dimension position = entry.getValue();
+				
+				PerceptionType[][] percepts = new PerceptionType[5][5];
+				for(int r=0; r<5; r++)
+					Arrays.fill(percepts[r], PerceptionType.THENEANT);
+				
+				for(int r=Math.max(0, position.height-2); r<=Math.min(this.height-1,position.height+2); r++) {
+					int animalRow = r-position.height+2;
+					for(int c=Math.max(0, position.width-2); c<=Math.min(this.width-1,position.width+2); c++) {
+						if (this.world[r][c]!=null) {
+							percepts[animalRow][c-position.width+2] = 
+								PerceptionType.fromAnimalType(this.types.get(this.world[r][c]));
+						}
+						else {
+							percepts[animalRow][c-position.width+2] = null;
+						}
+					}
+				}
+				
+				
+				
+				sendMessage(id, percepts);
+			}
+		}
+	}
+	
+	/** Calcul la position de la cellule dans laquelle un agent veut se deplacer.
+	 */
+	private Dimension predictMove(AgentIdentifier id, MoveDirection direction) {
+		Dimension pos = this.locations.get(id);
+		assert(pos!=null);
+
+		int x = pos.width;
+		int y = pos.height;
+		int nx = x;
+		int ny = y;
+		
+		switch(direction) {
+		case UP:
+			ny--;
+			break;
+		case DOWN:
+			ny++;
+			break;
+		case LEFT:
+			nx--;
+			break;
+		case RIGHT:
+			nx++;
+			break;
+		case NONE:
+			break;
+		}
+
+		if (((nx!=x)||(ny!=y))&&
+			(nx>=0)&&(nx<this.width)&&
+			(ny>=0)&&(ny<this.height)) {
+			x = nx;
+			y = ny;
+		}
+		
+		return new Dimension(x,y);
+	}
+
+	/** Fin du jeu
+	 */
+	private void endOfGame() {
+		for (AgentIdentifier id : this.locations.keySet()) {
+			sendMessage(id, GameMessage.END_OF_GAME);
+		}
+		killMe();
+	}
+	
+	/** Modification de la sonde sur l'état du jeu
+	 */
+	private void setStateProbe() {
+		Map<AgentIdentifier,Dimension> probedLocations = new TreeMap<AgentIdentifier,Dimension>();
+		for (Entry<AgentIdentifier,Dimension> entry : this.locations.entrySet()) {
+			probedLocations.put(entry.getKey(), 
+					new Dimension(entry.getValue()));
+		}
+		setProbe("WORLD_STATE", probedLocations); //$NON-NLS-1$
+	}
+	
+	/** Deplace un agent si possible.
+	 */
+	private void moveAgent(AgentIdentifier id, MoveDirection direction) {
+		Dimension pos = this.locations.get(id);
+		if (pos==null) return;
+
+		int x = pos.width;
+		int y = pos.height;
+		int nx = x;
+		int ny = y;
+		
+		switch(direction) {
+		case UP:
+			ny--;
+			break;
+		case DOWN:
+			ny++;
+			break;
+		case LEFT:
+			nx--;
+			break;
+		case RIGHT:
+			nx++;
+			break;
+		case NONE:
+			break;
+		}
+
+		if (((nx!=x)||(ny!=y))&&
+			(nx>=0)&&(nx<this.width)&&
+			(ny>=0)&&(ny<this.height)&&
+			(this.world[ny][nx]==null)) {
+			this.world[ny][nx] = id;
+			this.world[y][x] = null;
+			this.locations.put(id, new Dimension(nx,ny));
+		}
+	}
+	
+	/**
+	 * Cette fonction teste si la proie est encerclé (bas,haut,gauche,droite) par des prédateurs
+	 * @return vrai si la proie est encerclée
+	 */
+	private boolean verifyifPreyCatched() {
+		if (this.prey==null) return false;
+		
+		// Recherche la proie
+		Dimension pos = this.locations.get(this.prey);
+		if (pos==null) return false;
+		
+		int xPrey = pos.width;
+		int yPrey = pos.height;
+		
+		assert(xPrey>=0 && xPrey<this.width);
+		assert(yPrey>=0 && yPrey<this.height);
+		
+		// Test des quatres directions
+		int catched = 0;
+		
+		// Haut
+		if ((yPrey<=0)||(this.world[yPrey-1][xPrey]!=null))
+			catched++;
+		// Bas
+		if ((yPrey>=(this.height-1))||(this.world[yPrey+1][xPrey]!=null))
+			catched++;
+		// Gauchge
+		if ((xPrey<=0)||(this.world[yPrey][xPrey-1]!=null))
+			catched++;
+		// Bas
+		if ((xPrey>=(this.width-1))||(this.world[yPrey][xPrey+1]!=null))
+			catched++;
+		
+		return catched==4;
+	}
+	
+	@Override
+	public String toString() {
+		return "World"; //$NON-NLS-1$
+	}
+	
+	protected static void debugPositions(int width, int height, AgentIdentifier[][] grid) {
+		int[] size = new int[width];
+		Arrays.fill(size, 0);
+		
+		for (int c=0; c<width; c++) {
+			for (int r=0; r<height; r++) {
+				if ((grid[r][c]!=null)&&(size[c]<grid[r][c].getString().length()))
+					size[c] = grid[r][c].getString().length();
+			}
+		}
+		
+		for(int r=0; r<height; r++) {
+			System.out.print("| "); //$NON-NLS-1$
+			for(int c=0; c<width; c++) {
+				int s = grid[r][c]==null ? 0 : grid[r][c].getString().length();
+				if (grid[r][c]!=null) System.out.print(grid[r][c].getString());
+				for(int k=s; k<size[c]; k++)
+					System.out.print(" "); //$NON-NLS-1$
+				System.out.print(" |"); //$NON-NLS-1$
+			}
+			System.out.println(""); //$NON-NLS-1$
+		}
+	}
+
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/go-down.png
===================================================================
(Binary files differ)


Property changes on: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/go-down.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/go-next.png
===================================================================
(Binary files differ)


Property changes on: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/go-next.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/go-previous.png
===================================================================
(Binary files differ)


Property changes on: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/go-previous.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/go-up.png
===================================================================
(Binary files differ)


Property changes on: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/go-up.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/lion.png
===================================================================
(Binary files differ)


Property changes on: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/lion.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/rabbit.png
===================================================================
(Binary files differ)


Property changes on: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/rabbit.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/snake.png
===================================================================
(Binary files differ)


Property changes on: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/snake.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/wolf.png
===================================================================
(Binary files differ)


Property changes on: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator2/wolf.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/Animal.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/Animal.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/Animal.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,66 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator3;
+
+import org.arakhne.tinyMAS.situatedEnvironment.agent.SituatedAgent;
+import org.arakhne.tinyMAS.situatedEnvironment.environment.SituatedObject;
+
+/** Un animal
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public abstract class Animal extends SituatedAgent<AnimalBody, SituatedObject, AnimalPerception, AnimalInfluence> {
+	
+	/** Deplace l'agent dans la direction indiquee.
+	 * 
+	 * @param direction  
+	 * @return <code>true</code> si le mouvement est envoye.
+	 */	
+	protected boolean moveTo(final MoveDirection direction) {
+		getAgentBody().influence(direction);
+		setProbe("LAST_MOVE", direction); //$NON-NLS-1$
+		return true;
+	}
+	
+	/** Tire au hasard une direction.
+	 */
+	protected MoveDirection computeMove(boolean allow_no_move) {
+		int tries = 0;
+		MoveDirection[] values = MoveDirection.values();
+		MoveDirection selected;
+		do {
+			int direction = (int)(Math.random() * values.length * 10.)/10 ;
+			selected = values[direction];
+			tries++;
+		}
+		while ((!allow_no_move)&&(selected==MoveDirection.NONE)&&(tries<10));
+		return selected;
+	}
+	
+	/** Tire au hasard une direction parmi celles fournies.
+	 */
+	protected MoveDirection computeMove(MoveDirection... allowedDirections) {
+		int direction = (int)(Math.random() * allowedDirections.length * 10.)/10 ;
+		return allowedDirections[direction];
+	}
+	
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/AnimalBody.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/AnimalBody.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/AnimalBody.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,49 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator3;
+
+import org.arakhne.tinyMAS.situatedEnvironment.agent.SituatedAgent;
+import org.arakhne.tinyMAS.situatedEnvironment.body.AbstractAgentBody;
+import org.arakhne.tinyMAS.situatedEnvironment.perception.PerceptionBody;
+
+/** Corps d'un animal
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public class AnimalBody extends AbstractAgentBody<PerceptionBody, AnimalInfluence> {
+
+	private final AnimalType type;
+	
+	public AnimalBody(SituatedAgent<?,?,?,?> agent, AnimalType type) {
+		super(agent);
+		this.type = type;
+	}
+	
+	public AnimalType getType() {
+		return this.type;
+	}
+	
+	public void influence(MoveDirection direction) {
+		influence(new AnimalInfluence(getAgent(),direction));
+	}
+	
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/AnimalInfluence.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/AnimalInfluence.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/AnimalInfluence.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,44 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator3;
+
+import org.arakhne.tinyMAS.core.AgentIdentifier;
+import org.arakhne.tinyMAS.situatedEnvironment.influence.Influence;
+
+/** Corps d'un animal
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public class AnimalInfluence extends Influence {
+
+	private final MoveDirection direction;
+	
+	protected AnimalInfluence(AgentIdentifier emitter, MoveDirection direction) {
+		super(emitter);
+		this.direction = direction;
+	}
+	
+	public MoveDirection getDirection() {
+		return this.direction;
+	}
+	
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/AnimalPerception.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/AnimalPerception.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/AnimalPerception.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,36 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator3;
+
+import org.arakhne.tinyMAS.situatedEnvironment.perception.Perception;
+
+/** Corps d'un animal
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public class AnimalPerception extends Perception<PerceptionType[][]> {
+
+	public AnimalPerception(PerceptionType[][] percepts) {
+		super(percepts);
+	}
+	
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/AnimalType.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/AnimalType.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/AnimalType.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,35 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator3;
+
+/** JEU DE LA PROIE ET DES PREDATEURS.
+ * <p>
+ * Travaux pratiques d'IA54.<br>
+ * Universit&eacute; de Technologie de Belfort-monb&eacute;liard.
+ * <p>
+ * Type supportes d'animaux.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+enum AnimalType {
+	RABBIT, LION, SNAKE
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/GUI.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/GUI.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/GUI.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,522 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator3;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Toolkit;
+import java.awt.Transparency;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.image.BufferedImage;
+import java.lang.ref.WeakReference;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Map.Entry;
+import java.util.concurrent.Executors;
+
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.WindowConstants;
+
+import org.arakhne.tinyMAS.core.AgentIdentifier;
+import org.arakhne.tinyMAS.core.Kernel;
+import org.arakhne.tinyMAS.core.KernelAdapter;
+import org.arakhne.tinyMAS.core.Probe;
+import org.arakhne.tinyMAS.core.ProbeValueNotDefinedException;
+
+/** 
+ * Afficheur de l'état du monde
+ * <p>
+ * Travaux pratiques d'IA54.<br>
+ * Universit&eacute; de Technologie de Belfort-monb&eacute;liard.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public class GUI extends JFrame {
+
+	private static final long serialVersionUID = 3939643459108505034L;
+	
+	protected static final int ANIMATION_SPEED = 1;
+	protected static final int ANIMATION_STEPS = 10;
+	
+	protected static final Icon RABBIT_ICON;
+	protected static final Icon LION_ICON;	
+	protected static final Icon SNAKE_ICON;	
+	protected static final Icon UP_ICON;
+	protected static final Icon DOWN_ICON;	
+	protected static final Icon LEFT_ICON;
+	protected static final Icon RIGHT_ICON;	
+	protected static final int ICON_WIDTH;
+	protected static final int ICON_HEIGHT;
+	
+	static {
+		URL url = GUI.class.getResource("/org/arakhne/tinyMAS/demo/preypredator1/rabbit.png"); //$NON-NLS-1$
+		assert(url!=null);
+		RABBIT_ICON = new ImageIcon(url);
+		url = GUI.class.getResource("/org/arakhne/tinyMAS/demo/preypredator1/lion.png"); //$NON-NLS-1$
+		assert(url!=null);
+		LION_ICON = new ImageIcon(url);
+		url = GUI.class.getResource("/org/arakhne/tinyMAS/demo/preypredator1/snake.png"); //$NON-NLS-1$
+		assert(url!=null);
+		SNAKE_ICON = new ImageIcon(url);
+		url = GUI.class.getResource("/org/arakhne/tinyMAS/demo/preypredator1/go-up.png"); //$NON-NLS-1$
+		assert(url!=null);
+		UP_ICON = new ImageIcon(url);
+		url = GUI.class.getResource("/org/arakhne/tinyMAS/demo/preypredator1/go-down.png"); //$NON-NLS-1$
+		assert(url!=null);
+		DOWN_ICON = new ImageIcon(url);
+		url = GUI.class.getResource("/org/arakhne/tinyMAS/demo/preypredator1/go-previous.png"); //$NON-NLS-1$
+		assert(url!=null);
+		LEFT_ICON = new ImageIcon(url);
+		url = GUI.class.getResource("/org/arakhne/tinyMAS/demo/preypredator1/go-next.png"); //$NON-NLS-1$
+		assert(url!=null);
+		RIGHT_ICON = new ImageIcon(url);
+		
+		ICON_WIDTH = Math.max(SNAKE_ICON.getIconWidth(),
+				Math.max(RABBIT_ICON.getIconWidth(), LION_ICON.getIconWidth()));
+		ICON_HEIGHT = Math.max(SNAKE_ICON.getIconHeight(),
+				Math.max(RABBIT_ICON.getIconHeight(), LION_ICON.getIconHeight()));
+	}
+	
+    public static Image mergeImages(Image top_icon, Image bottom_icon, int x, int y) {
+    	int imgWidth = bottom_icon.getWidth(null);
+    	int imgHeight = bottom_icon.getHeight(null);
+    	BufferedImage img = new BufferedImage(
+    			imgWidth, imgHeight,
+    			Transparency.BITMASK);
+    	Graphics g = img.getGraphics();
+    	g.setClip(0,0,imgWidth,imgHeight);
+    	g.drawImage(bottom_icon,0,0,null);
+    	if (x<0) x = imgWidth + x;
+    	if (y<0) y = imgHeight + y;
+    	g.drawImage(top_icon,x,y,null);
+    	return Toolkit.getDefaultToolkit().createImage(img.getSource());
+    }
+
+    public static Icon mergeIcons(Icon top_icon, Icon bottom_icon, int x, int y) {
+        if ((top_icon instanceof ImageIcon)&&(bottom_icon instanceof ImageIcon)) {
+        	Image new_image = mergeImages(
+    				((ImageIcon)top_icon).getImage(),
+    				((ImageIcon)bottom_icon).getImage(),
+    				x, y);
+        	if (new_image!=null)
+        		return new ImageIcon(new_image);        	
+        }
+        return null;
+    }                       
+
+    protected final Grid grid;
+	protected final RefreshThread refresher;
+	private final WeakReference<Kernel<?,?,?,?>> kernel;	
+	protected Map<AgentIdentifier,Dimension> positions;
+	protected Map<AgentIdentifier,Dimension> nextPositions;
+	
+	public GUI(Kernel<?,?,?,?> kernel) {
+		this.refresher = new RefreshThread();
+		
+		setTitle("Prey and Predators v3"); //$NON-NLS-1$
+		this.kernel = new WeakReference<Kernel<?,?,?,?>>(kernel);
+		
+		Container content = getContentPane();
+		
+		content.setLayout(new BorderLayout());
+		
+		this.grid = new Grid();
+
+		JScrollPane scroll = new JScrollPane(this.grid);
+		content.add(BorderLayout.CENTER,scroll);
+		
+		JButton closeBt = new JButton("Quit"); //$NON-NLS-1$
+		closeBt.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				getKernel().stop();
+			}
+		});
+		content.add(BorderLayout.SOUTH, closeBt);
+		
+		setPreferredSize(new Dimension(11*50,12*50));
+		
+		kernel.addKernelListener(new KernelAdapter() {
+			@Override
+			public void kernelRefreshAllowed(Kernel<?, ?, ?, ?> kernel) {
+				if (kernel==GUI.this.getKernel()) {
+					changeState();
+				}
+			}
+			@Override
+			public void kernelStarted(Kernel<?, ?, ?, ?> kernel) {
+				if (kernel==GUI.this.getKernel()) {
+					changeState();
+				}
+			}			
+		});
+		
+		addWindowListener(new WindowAdapter() {
+			@Override
+			public void windowClosed(WindowEvent e) {
+				Kernel<?,?,?,?> kernel = GUI.this.getKernel();
+				kernel.stop();
+			}
+			@Override
+			public void windowClosing(WindowEvent e) {
+				Kernel<?,?,?,?> kernel = GUI.this.getKernel();
+				kernel.stop();
+			}
+		});
+		
+		setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+		
+		Executors.newSingleThreadExecutor().execute(this.refresher);
+		
+		pack();
+	}
+	
+	protected WorldGrid getEnvironment() {
+		return (WorldGrid)getKernel().getEnvironment();
+	}
+	
+	protected void changeState() {
+		WorldGrid world = getEnvironment();
+		if (world!=null) {
+			this.refresher.addMoves(world.getState());
+		}
+	}
+	
+	protected void refreshGUI(Map<AgentIdentifier,Dimension> moves) {
+		this.positions = moves;
+		this.grid.setStep(-1);
+		this.grid.repaint();
+	}
+
+	protected void refreshGUI(int moveStep, Map<AgentIdentifier,Dimension> moves) {
+		this.nextPositions = moves;
+		this.grid.setStep(moveStep);
+		this.grid.repaint();
+	}
+	
+	protected void refreshGUI(int moveStep) {
+		if (moveStep<0) {
+			this.positions = this.nextPositions;
+			//debugPositions(getKernel(), this.positions, "NEW POSITION"); //$NON-NLS-1$
+		}
+		this.grid.setStep(moveStep);
+		this.grid.repaint();
+	}
+	
+	protected Kernel<?,?,?,?> getKernel() {
+		return this.kernel.get();
+	}
+	
+	protected static void debugPositions(Kernel<?,?,?,?> kernel, Map<AgentIdentifier,Dimension> positions, String str) {
+		AgentIdentifier[] world = kernel.getServiceProviders("WORLD_GRID"); //$NON-NLS-1$
+		if (world.length>0) {
+			Probe probe = kernel.getProbe(world[0]);
+			try {
+				int width = probe.getProbeInt("WIDTH"); //$NON-NLS-1$
+				int height = probe.getProbeInt("HEIGHT"); //$NON-NLS-1$
+				
+				int[] size = new int[width];
+				Arrays.fill(size, 0);
+				
+				AgentIdentifier[][] grid = new AgentIdentifier[height][width];
+				for (Entry<AgentIdentifier, Dimension> entry : positions.entrySet()) {
+					int h = entry.getValue().height;
+					int w = entry.getValue().width;
+					assert(grid[h][w]==null);
+					grid[h][w] = entry.getKey();
+					if (size[w]<grid[h][w].getString().length())
+						size[w] = grid[h][w].getString().length();
+				}
+				
+				System.out.println(">>"+str+"<<"); //$NON-NLS-1$ //$NON-NLS-2$
+				for(int r=0; r<height; r++) {
+					System.out.print("| "); //$NON-NLS-1$
+					for(int c=0; c<width; c++) {
+						int s = grid[r][c]==null ? 0 : grid[r][c].getString().length();
+						if (grid[r][c]!=null) System.out.print(grid[r][c].getString());
+						for(int k=s; k<size[c]; k++)
+							System.out.print(" "); //$NON-NLS-1$
+						System.out.print(" |"); //$NON-NLS-1$
+					}
+					System.out.println(""); //$NON-NLS-1$
+				}
+				
+				return;
+			}
+			catch(ProbeValueNotDefinedException _) {
+				//
+			}			
+		}
+		throw new Error("UNABLE TO OBTAIN A PROBE"); //$NON-NLS-1$
+	}
+	
+	private class RefreshThread implements Runnable {
+
+		private final Queue<Map<AgentIdentifier,Dimension>> queue = new LinkedList<Map<AgentIdentifier,Dimension>>(); 
+		
+		private int moveStep = -2;
+
+		public RefreshThread() {
+			//
+		}
+		
+		public void run() {
+			while (true) {
+				if (this.moveStep<0) {
+					Map<AgentIdentifier,Dimension> moves = this.queue.poll();
+					if (moves!=null) {
+						if (this.moveStep==-1) {
+							this.moveStep = 0;
+							GUI.this.refreshGUI(this.moveStep, moves);
+						}
+						else if (this.moveStep==-2) {
+							this.moveStep = -1;
+							GUI.this.refreshGUI(moves);
+						}
+					}
+				}
+				else {
+					try {
+						Thread.sleep((1000*ANIMATION_SPEED)/ANIMATION_STEPS);
+					}
+					catch (InterruptedException e) {
+						//
+					}
+					if (this.moveStep>=ANIMATION_STEPS) {
+						this.moveStep = -1;
+					}
+					else {
+						this.moveStep++;
+					}
+					GUI.this.refreshGUI(this.moveStep);
+				}
+				Thread.yield();
+			}
+		}
+		
+		public void addMoves(Map<AgentIdentifier,Dimension> moves) {
+			if (moves!=null) {
+				Map<AgentIdentifier,Dimension> old = this.queue.peek();
+				if ((old==null)||(!old.equals(moves))) {
+					this.queue.offer(moves);
+				}
+			}
+		}
+		
+	}
+	
+	private class Grid extends JPanel {
+		
+		private static final long serialVersionUID = 4361140442107583935L;
+		
+		private int moveStep = -1;
+		
+		public Grid() {
+			//
+		}
+		
+		public void setStep(int step) {
+			this.moveStep = step;
+		}
+		
+		@Override
+		public void paint(Graphics g) {
+			super.paint(g);
+			Graphics2D g2d = (Graphics2D)g;
+			
+			Dimension currentDim = getPreferredSize();
+			Dimension desiredDim = computeDesiredDim();
+			
+			if ((desiredDim!=null)&&(!currentDim.equals(desiredDim))) {
+				setPreferredSize(desiredDim);
+				revalidate();
+				repaint();
+				return;
+			}
+			
+			if (this.moveStep>=0) {
+				drawMovingAgents(g2d, currentDim);
+			}
+			else {
+				drawAgents(g2d, currentDim);					
+			}
+			
+			drawGrid(g2d, currentDim);
+		}
+		
+		private void drawMovingAgents(Graphics2D g2d, Dimension currentDim) {
+			if ((this.moveStep<0)||
+				(GUI.this.nextPositions==null)||
+				(GUI.this.positions==null)) drawAgents(g2d, currentDim);
+			
+			int x, y, deltaX, deltaY;
+			Dimension d;
+			Dimension nextD;
+			AgentIdentifier id;
+			
+			deltaX = ((this.moveStep * ICON_WIDTH) / ANIMATION_STEPS);
+			deltaY = ((this.moveStep * ICON_HEIGHT) / ANIMATION_STEPS);
+			
+			Icon ic;
+
+			for (Entry<AgentIdentifier, Dimension> entry : GUI.this.positions.entrySet()) {
+				id = entry.getKey();
+				d = entry.getValue();
+				WorldGrid grid = getEnvironment();
+				if ((grid!=null)&&(GUI.this.nextPositions.containsKey(id))) {
+					nextD = GUI.this.nextPositions.get(id);
+					x = d.width * ICON_WIDTH;
+					y = d.height * ICON_HEIGHT;
+					
+					if (nextD.width<d.width) {
+						x -= deltaX;
+					}
+					else if (nextD.width>d.width) {
+						x += deltaX;
+					}
+										
+					if (nextD.height<d.height) {
+						y -= deltaY;
+					}
+					else if (nextD.height>d.height) {
+						y += deltaY;
+					}
+
+					ic = getIcon(grid.getAgentBody(id).getType(), getLastDirection(id));
+					assert(ic!=null);
+					ic.paintIcon(this, g2d, x, y);
+				}
+			}
+		}
+		
+		private void drawAgents(Graphics2D g2d, Dimension currentDim) {
+			if (GUI.this.positions==null) return;
+			int x, y;
+			Dimension d;
+			AgentIdentifier id;
+			Icon ic;
+			WorldGrid grid = getEnvironment();
+			if ((grid!=null)&&(grid.isAlive())&&(!Kernel.getSingleton().isShutdown())) {
+				for (Entry<AgentIdentifier, Dimension> entry : GUI.this.positions.entrySet()) {
+					d = entry.getValue();
+					id = entry.getKey();
+					x = d.width * ICON_WIDTH;
+					y = d.height * ICON_HEIGHT;
+					
+					ic = getIcon(grid.getAgentBody(id).getType(), getLastDirection(entry.getKey()));
+					assert(ic!=null);
+					ic.paintIcon(this, g2d, x, y);
+				}
+			}
+		}
+		
+		private void drawGrid(Graphics2D g2d, Dimension currentDim) {
+			int x, y;
+			g2d.setColor(Color.BLACK);
+			for(x=0; x<=currentDim.width; x+=ICON_WIDTH) {
+				g2d.drawLine(x, 0, x, currentDim.height); 
+			}
+			for(y=0; y<=currentDim.height; y+=ICON_WIDTH) {
+				g2d.drawLine(0, y, currentDim.width, y); 
+			}
+		}
+		
+		private Dimension computeDesiredDim() {
+			WorldGrid world = getEnvironment();
+			if (world!=null) {
+				int width = world.getWidth();
+				int height = world.getHeight();
+				
+				return new Dimension(width*GUI.ICON_WIDTH, height*GUI.ICON_HEIGHT);
+			}
+			return null;
+		}
+		
+		private MoveDirection getLastDirection(AgentIdentifier id) {
+			Kernel<?,?,?,?> kernel = GUI.this.getKernel();
+			Probe probe = kernel.getProbe(id);
+			if (probe==null) return MoveDirection.NONE;
+			MoveDirection d = probe.getProbeValue("LAST_MOVE", MoveDirection.class); //$NON-NLS-1$
+			return (d==null) ? MoveDirection.NONE : d;
+		}
+		
+		private Icon getIcon(AnimalType animalType, MoveDirection direction) {
+			Icon ic = null;
+			switch(animalType) {
+			case RABBIT:
+				ic = RABBIT_ICON;
+				break;
+			case LION:
+				ic = LION_ICON;
+				break;
+			case SNAKE:
+				ic = SNAKE_ICON;
+				break;
+			}
+			
+			assert(ic!=null);
+			
+			if (direction!=null) {
+				switch(direction) {
+				case UP:
+					ic = mergeIcons(UP_ICON, ic, 
+							(ic.getIconWidth()-UP_ICON.getIconWidth())/2, 0);
+					break;
+				case DOWN:
+					ic = mergeIcons(DOWN_ICON, ic, 
+							(ic.getIconWidth()-DOWN_ICON.getIconWidth())/2,
+							ic.getIconHeight() - DOWN_ICON.getIconHeight());
+					break;
+				case LEFT:
+					ic = mergeIcons(LEFT_ICON, ic,
+							0,
+							(ic.getIconHeight()-LEFT_ICON.getIconHeight())/2);
+					break;
+				case RIGHT:
+					ic = mergeIcons(RIGHT_ICON, ic, 
+							ic.getIconWidth() - RIGHT_ICON.getIconWidth(),
+							(ic.getIconHeight()-RIGHT_ICON.getIconHeight())/2);
+					break;
+				case NONE:
+				}
+			}
+			
+			return ic;
+		}
+	}
+	
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/Game.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/Game.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/Game.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,85 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator3;
+
+import org.arakhne.tinyMAS.core.Agent;
+import org.arakhne.tinyMAS.core.Kernel;
+
+/** JEU DE LA PROIE ET DES PREDATEURS.
+ * <p>
+ * Travaux pratiques d'IA54.<br>
+ * Universit&eacute; de Technologie de Belfort-monb&eacute;liard.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+@SuppressWarnings("unchecked")
+public class Game extends Kernel {
+
+	private static final int SNAKE_COUNT = 5;
+	private static final int LION_COUNT = 5;
+	
+	private static final int WORLD_SIZE_X = 10;
+	private static final int WORLD_SIZE_Y = 10;
+	
+	public Game() {
+		super();
+	}
+	
+	/** Programme Principal
+	 */	
+	public static void main(String[] argv) {
+		
+		System.out.println("Prey and Predator demonstrator #3"); //$NON-NLS-1$
+		System.out.println("Copyright (c) 2005-2009 Stéphane GALLAND and Nicolas GAUD "); //$NON-NLS-1$
+		System.out.println("Thanks to Julia Nikolaeva aka. Flameia for the icons <flameia@xxxxxxxxxxxx>"); //$NON-NLS-1$
+		
+		Game j = new Game() ;
+		
+		j.setWaitingDuration(1500);
+		
+		WorldGrid g = new WorldGrid(WORLD_SIZE_X,WORLD_SIZE_Y) ;
+		j.setEnvironment(g) ;
+
+		Agent a = new Rabbit() ;		
+		j.addAgent(a) ;
+
+		for(int i=0; i<SNAKE_COUNT; i++) {
+			a = new Snake() ;		
+			j.addAgent(a) ;
+		}
+
+		for(int i=0; i<LION_COUNT; i++) {
+			a = new Lion() ;		
+			j.addAgent(a) ;
+		}
+
+		GUI gui = new GUI(j);
+		gui.setVisible(true);
+		
+		j.run() ;
+		
+		// Force quit
+		System.exit(0);
+		
+	}
+
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/Lion.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/Lion.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/Lion.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,109 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator3;
+
+import org.arakhne.tinyMAS.situatedEnvironment.agent.SituatedAgent;
+import org.arakhne.tinyMAS.situatedEnvironment.environment.SituatedEnvironment;
+import org.arakhne.tinyMAS.situatedEnvironment.environment.SituatedObject;
+
+/** Un lion
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public class Lion extends PerceptiveAnimal {
+
+	@Override
+	public AnimalBody createDefaultBody(SituatedEnvironment<? extends SituatedAgent<AnimalBody, SituatedObject, AnimalPerception, AnimalInfluence>, AnimalBody, SituatedObject, AnimalPerception, AnimalInfluence> in) {
+		return new AnimalBody(this,AnimalType.LION);
+	}
+
+	@Override
+	protected void doDecision(PerceptionType[][] percepts) {
+		// Analyse les perception afin de detecter la proie
+		int preyX = 0, preyY = 0;
+		boolean preyFound = false;
+		for(int r=0; r<percepts.length; r++) {
+			for(int c=0; c<percepts[r].length; c++) {
+				if (percepts[r][c]==PerceptionType.RABBIT) {
+					preyX = -2+c;
+					preyY = -2+r;
+					preyFound = true;
+					break;
+				}
+			}
+		}
+		
+		MoveDirection direction;
+
+		if (!preyFound) {
+			// Le lion se déplace au hasard
+			direction = computeMove(true);
+		}
+		else if ((preyX==0)&&(preyY<-1)) {
+			// Le lion suit la proie 
+			direction = MoveDirection.UP;
+		}
+		else if ((preyX==0)&&(preyY>1)) {
+			// Le lion suit la proie 
+			direction = MoveDirection.DOWN;
+		}
+		else if ((preyX<-1)&&(preyY==0)) {
+			// Le lion suit la proie 
+			direction = MoveDirection.LEFT;
+		}
+		else if ((preyX>1)&&(preyY==0)) {
+			// Le lion suit la proie 
+			direction = MoveDirection.RIGHT;
+		}
+		else if ((preyX<0)&&(preyY<0)) {
+			// Le lion suit la proie 
+			direction = computeMove(MoveDirection.LEFT, MoveDirection.UP);
+		}
+		else if ((preyX<0)&&(preyY>0)) {
+			// Le lion suit la proie 
+			direction = computeMove(MoveDirection.LEFT, MoveDirection.DOWN);
+		}
+		else if ((preyX>0)&&(preyY<0)) {
+			// Le lion suit la proie 
+			direction = computeMove(MoveDirection.RIGHT, MoveDirection.UP);
+		}
+		else if ((preyX>0)&&(preyY>0)) {
+			// Le lion suit la proie 
+			direction = computeMove(MoveDirection.RIGHT, MoveDirection.DOWN);
+		}
+		else {
+			// Le lion se trouve prêt de la proie, il ne veut pas bouger
+			direction = MoveDirection.NONE;
+		}
+
+		/*drawPercepts(percepts);
+		
+		System.out.print("found prey="+preyFound);
+		System.out.print(";preyX="+preyX);
+		System.out.print(";preyY="+preyY);
+		System.out.println(";direction="+direction);*/
+		
+		moveTo(direction);
+	}
+
+	
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/MoveDirection.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/MoveDirection.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/MoveDirection.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,44 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator3;
+
+/** 
+ * Direction de deplacement pour les proies et les predateurs
+ * <p>
+ * Travaux pratiques d'IA54.<br>
+ * Universit&eacute; de Technologie de Belfort-monb&eacute;liard.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public enum MoveDirection {
+
+	NONE,
+	
+	UP,
+	
+	DOWN,
+	
+	LEFT,
+	
+	RIGHT;
+	
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/PerceptionType.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/PerceptionType.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/PerceptionType.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,48 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator3;
+
+/** JEU DE LA PROIE ET DES PREDATEURS.
+ * <p>
+ * Travaux pratiques d'IA54.<br>
+ * Universit&eacute; de Technologie de Belfort-monb&eacute;liard.
+ * <p>
+ * Type de perceptions.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+enum PerceptionType {
+	RABBIT, LION, SNAKE, THENEANT;
+	
+	public static PerceptionType fromAnimalType(AnimalType type) {
+		switch(type) {
+		case LION:
+			return LION;
+		case SNAKE:
+			return SNAKE;
+		case RABBIT:
+			return RABBIT;
+		default:
+			return null;
+		}
+	}
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/PerceptiveAnimal.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/PerceptiveAnimal.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/PerceptiveAnimal.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,68 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator3;
+
+import java.util.List;
+
+/** Un animal ayant des perceptions.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public abstract class PerceptiveAnimal extends Animal {
+	
+
+	@Override
+	protected void doDecisionAndAction() {
+		PerceptionType[][] percepts = new PerceptionType[5][5];
+
+		List<AnimalPerception> rawPercepts = getPerceptionFilter().getPerceivedObjects();
+		
+		if ((rawPercepts!=null)&&(rawPercepts.size()>0)) {
+			PerceptionType[][] worldPercepts = rawPercepts.get(0).getData();
+			for(int r=0; (r<worldPercepts.length)&&(r<5); r++) {
+				for(int c=0; (c<worldPercepts[r].length)&&(c<5); c++) {
+					percepts[r][c] = worldPercepts[r][c];
+				}
+			}
+			percepts[2][2] = null;
+		}
+
+		doDecision(percepts);
+	}	
+	
+	/** L'agent predateur se deplace en fonction de ses perceptions.
+	 */ 	
+	protected abstract void doDecision(PerceptionType[][] percepts);
+
+	/** Draw the specified percepts.
+	 */
+	protected void drawPercepts(PerceptionType[][] percepts) {
+		System.out.println(getId().getString());
+		for(int r=0; r<5; r++) {
+			for(int c=0; c<5; c++) {
+				System.out.print("\t"+percepts[r][c]); //$NON-NLS-1$
+			}
+			System.out.print("\n"); //$NON-NLS-1$
+		}
+	}
+
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/Rabbit.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/Rabbit.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/Rabbit.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,143 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator3;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import org.arakhne.tinyMAS.situatedEnvironment.agent.SituatedAgent;
+import org.arakhne.tinyMAS.situatedEnvironment.environment.SituatedEnvironment;
+import org.arakhne.tinyMAS.situatedEnvironment.environment.SituatedObject;
+
+/** Un lapin
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public class Rabbit extends PerceptiveAnimal {
+
+	@Override
+	public AnimalBody createDefaultBody(SituatedEnvironment<? extends SituatedAgent<AnimalBody, SituatedObject, AnimalPerception, AnimalInfluence>, AnimalBody, SituatedObject, AnimalPerception, AnimalInfluence> in) {
+		return new AnimalBody(this,AnimalType.RABBIT);
+	}
+
+	@Override
+	protected void doDecision(PerceptionType[][] percepts) {
+		
+		//drawPercepts(percepts);
+
+		int[][] dangerMatrix = computeDanger(percepts);
+		
+		//drawDangerMatrix(dangerMatrix);
+
+		int[] dangers = new int[] {
+				percepts[1][2]==PerceptionType.THENEANT ? Integer.MAX_VALUE : dangerMatrix[1][2], // haut
+				percepts[3][2]==PerceptionType.THENEANT ? Integer.MAX_VALUE : dangerMatrix[3][2], // bas
+				percepts[2][1]==PerceptionType.THENEANT ? Integer.MAX_VALUE : dangerMatrix[2][1], // left
+				percepts[2][3]==PerceptionType.THENEANT ? Integer.MAX_VALUE : dangerMatrix[2][3], // right
+		};
+		
+		ArrayList<Integer> mins = new ArrayList<Integer>();
+		int minDanger = dangers[0];
+		mins.add(0);
+		for(int i=1; i<4; i++) {
+			if (minDanger>dangers[i]) {
+				minDanger = dangers[i];
+				mins.clear();
+				mins.add(i);
+			}
+			else if (minDanger==dangers[i]) {
+				mins.add(i);
+			}
+		}
+		
+		MoveDirection[] directions = new MoveDirection[mins.size()];
+		for(int i=0; i<mins.size(); i++) {
+			switch(mins.get(i)) {
+			case 0:
+				directions[i] = MoveDirection.UP;
+				break;
+			case 1:
+				directions[i] = MoveDirection.DOWN;
+				break;
+			case 2:
+				directions[i] = MoveDirection.LEFT;
+				break;
+			case 3:
+				directions[i] = MoveDirection.RIGHT;
+				break;
+			default:
+				directions[i] = MoveDirection.NONE;
+				break;
+			}
+		}
+		
+		moveTo(computeMove(directions));
+	}	
+	
+	private int computeLength(PerceptionType[][] percepts) {
+		int max = 0;
+		for(int r=0; r<percepts.length; r++) {
+			if (max<percepts[r].length)
+				max = percepts[r].length;
+		}
+		return max;
+	}
+	
+	private void fillDangerGrid(int[][] grid, int x, int y, int maxX, int maxY, int cellDanger) {
+		assert(x>=0 && x<maxX);
+		assert(y>=0 && y<maxY);
+		
+		if (grid[y][x]<cellDanger) {
+			grid[y][x] = cellDanger;
+			if (x>0) fillDangerGrid(grid,x-1,y,maxX,maxY,cellDanger-1);
+			if (x<maxX-1) fillDangerGrid(grid,x+1,y,maxX,maxY,cellDanger-1);
+			if (y>0) fillDangerGrid(grid,x,y-1,maxX,maxY,cellDanger-1);
+			if (y<maxY-1) fillDangerGrid(grid,x,y+1,maxX,maxY,cellDanger-1);
+		}
+	}
+		
+	private int[][] computeDanger(PerceptionType[][] percepts) {
+		int size = computeLength(percepts);
+		int maxDistance = size*percepts.length;
+
+		// Initialize
+		int[][] danger = new int[percepts.length][size];		
+		for(int r=0; r<percepts.length; r++) {
+			danger[r] = new int[percepts[r].length];
+			Arrays.fill(danger[r], 0);
+		}
+		
+		// Compute the dangerousity of each cell
+		for(int r=0; r<percepts.length; r++) {
+			for(int c=0; c<percepts[r].length; c++) {
+				if (percepts[r][c]!=null) {
+					int cellDanger = (percepts[r][c]==PerceptionType.THENEANT) ? maxDistance/2 : maxDistance;
+					fillDangerGrid(danger,c,r,size,percepts.length,cellDanger);
+				}
+			}
+		}
+		
+		
+		return danger;
+	}
+
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/Snake.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/Snake.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/Snake.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,44 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator3;
+
+import org.arakhne.tinyMAS.situatedEnvironment.agent.SituatedAgent;
+import org.arakhne.tinyMAS.situatedEnvironment.environment.SituatedEnvironment;
+import org.arakhne.tinyMAS.situatedEnvironment.environment.SituatedObject;
+
+/** Un serpent
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public class Snake extends Animal {
+
+	@Override
+	public AnimalBody createDefaultBody(SituatedEnvironment<? extends SituatedAgent<AnimalBody, SituatedObject, AnimalPerception, AnimalInfluence>, AnimalBody, SituatedObject, AnimalPerception, AnimalInfluence> in) {
+		return new AnimalBody(this,AnimalType.SNAKE);
+	}
+
+	@Override
+	protected void doDecisionAndAction() {
+		moveTo(computeMove(true));
+	}	
+	
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/WorldGrid.java
===================================================================
--- trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/WorldGrid.java	                        (rev 0)
+++ trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/WorldGrid.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,276 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.demo.preypredator3;
+
+import java.awt.Dimension;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.Map.Entry;
+import java.util.concurrent.TimeUnit;
+
+import org.arakhne.tinyMAS.core.AgentIdentifier;
+import org.arakhne.tinyMAS.core.ConstantStepTimeManager;
+import org.arakhne.tinyMAS.situatedEnvironment.environment.AbstractSituatedEnvironment;
+import org.arakhne.tinyMAS.situatedEnvironment.environment.SituatedObject;
+
+/** 
+ * GRILLE.
+ * L'environnement de notre simulation.
+ * <p>
+ * Travaux pratiques d'IA54.<br>
+ * Universit&eacute; de Technologie de Belfort-monb&eacute;liard.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public class WorldGrid extends AbstractSituatedEnvironment<Animal, AnimalBody, SituatedObject, AnimalPerception, AnimalInfluence> {
+
+	private final AnimalBody[][] world;
+	private final int width;
+	private final int height;
+	private AnimalBody prey;
+	private final Map<AgentIdentifier,Dimension> locations = new TreeMap<AgentIdentifier,Dimension>();
+	private final Map<AgentIdentifier,AnimalType> types = new TreeMap<AgentIdentifier,AnimalType>();
+	private final Map<AgentIdentifier,AnimalBody> bodies = new TreeMap<AgentIdentifier,AnimalBody>();
+
+	
+	public WorldGrid(int x, int y) {
+		super(new ConstantStepTimeManager(1, TimeUnit.SECONDS));
+		this.world = new AnimalBody[y][x];
+		this.width = x;
+		this.height = y;
+	}
+	
+	public int getWidth() {
+		return this.width;
+	}
+	
+	public int getHeight() {
+		return this.height;
+	}
+	
+	public Map<AgentIdentifier,Dimension> getState() {
+		return new TreeMap<AgentIdentifier,Dimension>(this.locations);
+	}
+
+	@Override
+	protected void onAgentBodyAdded(AnimalBody body) {
+		if ((body.getType()==AnimalType.RABBIT)&&(this.prey!=null))
+			throw new IllegalArgumentException("is_prey"); //$NON-NLS-1$
+		
+		int x, y;
+		Random rnd = new Random();
+		do {
+			x = rnd.nextInt(this.width);
+			y = rnd.nextInt(this.height);
+		}
+		while (this.world[y][x]!=null);
+		
+		this.world[y][x] = body;
+		this.locations.put(body.getAgent(), new Dimension(x,y));
+		this.types.put(body.getAgent(), body.getType());
+		this.bodies.put(body.getAgent(),body);
+		if (body.getType()==AnimalType.RABBIT) {
+			this.prey = body;
+		}
+	}
+
+	@Override
+	protected void onAgentBodyRemoved(AnimalBody body) {
+		//
+	}
+
+	public AnimalPerception[] perceive(AgentIdentifier agent) {
+		Dimension position = this.locations.get(agent);
+			
+		PerceptionType[][] percepts = new PerceptionType[5][5];
+		for(int r=0; r<5; r++)
+			Arrays.fill(percepts[r], PerceptionType.THENEANT);
+		
+		for(int r=Math.max(0, position.height-2); r<=Math.min(this.height-1,position.height+2); r++) {
+			int animalRow = r-position.height+2;
+			for(int c=Math.max(0, position.width-2); c<=Math.min(this.width-1,position.width+2); c++) {
+				if (this.world[r][c]!=null) {
+					percepts[animalRow][c-position.width+2] = 
+						PerceptionType.fromAnimalType(this.types.get(this.world[r][c].getAgent()));
+				}
+				else {
+					percepts[animalRow][c-position.width+2] = null;
+				}
+			}
+		}
+		
+		return new AnimalPerception[] {new AnimalPerception(percepts)};
+	}
+
+	/** Calcul la position de la cellule dans laquelle un agent veut se deplacer.
+	 */
+	private Dimension predictMove(AgentIdentifier id, MoveDirection direction) {
+		Dimension pos = this.locations.get(id);
+		assert(pos!=null);
+
+		int x = pos.width;
+		int y = pos.height;
+		int nx = x;
+		int ny = y;
+		
+		switch(direction) {
+		case UP:
+			ny--;
+			break;
+		case DOWN:
+			ny++;
+			break;
+		case LEFT:
+			nx--;
+			break;
+		case RIGHT:
+			nx++;
+			break;
+		case NONE:
+			break;
+		}
+
+		if (((nx!=x)||(ny!=y))&&
+			(nx>=0)&&(nx<this.width)&&
+			(ny>=0)&&(ny<this.height)) {
+			x = nx;
+			y = ny;
+		}
+		
+		return new Dimension(x,y);
+	}
+
+	@Override
+	protected boolean applyInfluences(Collection<AnimalInfluence> influences) {
+		// Calcul les positions desirees par les agents
+		Map<AgentIdentifier, Dimension> desiredPositions = new TreeMap<AgentIdentifier,Dimension>();
+		for (AnimalInfluence influence : influences) {
+			AgentIdentifier id = influence.getEmitter();
+			desiredPositions.put(id, predictMove(id, influence.getDirection()));
+		}
+			
+		// Detection de conflits
+		Map<Dimension, Set<AgentIdentifier>> conflicts = new HashMap<Dimension,Set<AgentIdentifier>>();
+		for (Entry<AgentIdentifier,Dimension> entry1 : desiredPositions.entrySet()) {
+			for (Entry<AgentIdentifier,Dimension> entry2 : desiredPositions.entrySet()) {
+				if (!entry1.getKey().equals(entry2.getKey())) {
+					if (entry1.getValue().equals(entry2.getValue())) {
+						// Conflit
+						Set<AgentIdentifier> conflictedAgents = conflicts.get(entry1.getValue());
+						if (conflictedAgents==null) {
+							conflictedAgents = new HashSet<AgentIdentifier>();
+							conflicts.put(entry1.getValue(), conflictedAgents);
+						}
+						conflictedAgents.add(entry1.getKey());
+						conflictedAgents.add(entry2.getKey());
+					}
+				}
+			}
+		}
+		
+		// Resolution des conflits
+		// Choix aleatoire d'un des agents
+		Random rnd = new Random();
+		int idx;
+		AgentIdentifier[] tab;
+		Dimension current, nouvel;
+		for (Entry<Dimension,Set<AgentIdentifier>> entry : conflicts.entrySet()) {
+			tab = new AgentIdentifier[entry.getValue().size()];
+			entry.getValue().toArray(tab);
+			idx = rnd.nextInt(tab.length);
+			
+			current = this.locations.get(tab[idx]);
+			nouvel = desiredPositions.get(tab[idx]);
+			applyReaction(tab[idx],current.width, current.height,nouvel.width, nouvel.height);
+			
+			for (AgentIdentifier agentId : tab) {
+				desiredPositions.remove(agentId);
+			}
+		}
+
+		// Changement de position des agents n'ayant pas provoque de conflit
+		for (Entry<AgentIdentifier,Dimension> entry : desiredPositions.entrySet()) {
+			current = this.locations.get(entry.getKey());
+			nouvel = entry.getValue();
+			applyReaction(entry.getKey(),current.width, current.height,nouvel.width, nouvel.height);
+		}
+		
+		conflicts.clear();
+		desiredPositions.clear();
+		
+		analyzeEnvironmentState();
+		
+		return true;
+	}
+
+	private void applyReaction(AgentIdentifier id, int x, int y, int nx, int ny) {
+		if (((nx!=x)||(ny!=y))&&
+			(nx>=0)&&(nx<this.width)&&
+			(ny>=0)&&(ny<this.height)&&
+			(this.world[ny][nx]==null)) {
+			this.world[ny][nx] = this.bodies.get(id);
+			this.world[y][x] = null;
+			this.locations.put(id, new Dimension(nx,ny));
+		}			
+	}
+
+	private void analyzeEnvironmentState() {
+		if (this.prey==null) return;
+		
+		// Recherche la proie
+		Dimension pos = this.locations.get(this.prey.getAgent());
+		if (pos==null) return;
+		
+		int xPrey = pos.width;
+		int yPrey = pos.height;
+		
+		assert(xPrey>=0 && xPrey<this.width);
+		assert(yPrey>=0 && yPrey<this.height);
+		
+		// Test des quatres directions
+		int catched = 0;
+		
+		// Haut
+		if ((yPrey<=0)||(this.world[yPrey-1][xPrey]!=null))
+			catched++;
+		// Bas
+		if ((yPrey>=(this.height-1))||(this.world[yPrey+1][xPrey]!=null))
+			catched++;
+		// Gauchge
+		if ((xPrey<=0)||(this.world[yPrey][xPrey-1]!=null))
+			catched++;
+		// Bas
+		if ((xPrey>=(this.width-1))||(this.world[yPrey][xPrey+1]!=null))
+			catched++;
+		
+		if (catched==4) {
+			killMe();
+		}
+	}
+
+}
\ No newline at end of file

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/go-down.png
===================================================================
(Binary files differ)


Property changes on: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/go-down.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/go-next.png
===================================================================
(Binary files differ)


Property changes on: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/go-next.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/go-previous.png
===================================================================
(Binary files differ)


Property changes on: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/go-previous.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/go-up.png
===================================================================
(Binary files differ)


Property changes on: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/go-up.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/lion.png
===================================================================
(Binary files differ)


Property changes on: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/lion.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/rabbit.png
===================================================================
(Binary files differ)


Property changes on: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/rabbit.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/snake.png
===================================================================
(Binary files differ)


Property changes on: trunk/tinymas-demos/src/main/java/org/arakhne/tinyMAS/demo/preypredator3/snake.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/tinymas-environment/pom.xml
===================================================================
--- trunk/tinymas-environment/pom.xml	                        (rev 0)
+++ trunk/tinymas-environment/pom.xml	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd";>
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+	<artifactId>project</artifactId>
+	<groupId>org.arakhne.tinymas</groupId>
+	<version>1.0-SNAPSHOT</version>
+  </parent>
+
+  <groupId>org.arakhne.tinymas</groupId>
+  <artifactId>tinymas-environment</artifactId>
+  <packaging>jar</packaging>
+  <version>${version_tinymas_environment}</version>
+  <name>TinyMAS Situated Environment</name>
+  <url>http://www.arakhne.org/tinymas/</url>
+
+	<!-- ======================================= -->
+	<!-- ====       Project Information      === -->
+	<!-- ======================================= -->
+		
+	<scm>
+		<url>http://www.arakhne.org/websvn.php?project=tinymas&amp;subproject=environment</url>
+	</scm>
+	
+	<dependencies>
+		<dependency>
+			<groupId>org.arakhne.tinymas</groupId>
+			<artifactId>tinymas-kernel</artifactId>
+		</dependency>
+	</dependencies>
+
+</project>

Added: trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/agent/PerceptionInterestFilter.java
===================================================================
--- trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/agent/PerceptionInterestFilter.java	                        (rev 0)
+++ trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/agent/PerceptionInterestFilter.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,161 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.situatedEnvironment.agent;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.arakhne.tinyMAS.core.AgentIdentifier;
+import org.arakhne.tinyMAS.situatedEnvironment.perception.EntityPerception;
+import org.arakhne.tinyMAS.situatedEnvironment.perception.Perception;
+
+/** This class defines a filter for agent's perceptions.
+ * <p>
+ * This filter is mainly used to focus the perception of
+ * the agent on objects/agents that are directly under
+ * interest.
+ * <p>
+ * This 
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public abstract class PerceptionInterestFilter<PT extends Perception<?>> {
+	
+	private PerceptionInterestFilter<PT> __parent;
+	
+	private List<PT> __objects = null;
+	
+	/** Describes the filtering state of the percepts.
+	 * 
+	 * @author Stephane GALLAND
+	 */
+	protected enum PerceptionState {
+		/** The percept is for an agent */
+		AGENT,
+		/** The percept is for an object (not an agent) */
+		OBJECT,
+		/** The percept must be ignored */
+		IGNORE,
+	}
+	
+	/** Called each time this filter must be re-init.
+	 */
+	protected void initFilter() {
+		this.__objects = null;
+	}
+	
+	public PerceptionInterestFilter() {
+		this.__parent = null;
+	}
+	
+	void setParent(PerceptionInterestFilter<PT> parent) {
+		this.__parent = parent;
+	}
+
+	PerceptionInterestFilter<PT> getParent() {
+		return this.__parent;
+	}
+
+	/** Make a filter of the percepts.
+	 * 
+	 * @param percepts is the percepts replied by the environment. It could be
+	 * <code>null</code> or empty.
+	 */
+	public final void filter(PT[] percepts) {
+		initFilter();
+		
+		if (percepts!=null && percepts.length>0) {
+			final ArrayList<PT> objects = new ArrayList<PT>();
+			
+			for (PT pt : percepts) {
+				if (pt!=null) {
+					
+					// Initialize the default state of the percept
+					// => OBJECT or AGENT
+					PerceptionState st = PerceptionState.OBJECT;
+					if ((pt instanceof EntityPerception)&&
+						(((EntityPerception)pt).getPerceivedObject() instanceof AgentIdentifier)) {
+						st = PerceptionState.AGENT;
+					}
+					
+					// Call the filtering function of the parent
+					if (this.__parent!=null) {
+						st = this.__parent.filter(pt);
+					}
+					
+					// Do the local filtering
+					boolean saveAsGeneralObject = false;
+					if (st!=PerceptionState.IGNORE) {
+						st = filter(pt);
+						
+						if (st!=PerceptionState.IGNORE)
+							saveAsGeneralObject = !savePerception(pt,st);
+					}
+					
+					// Save the percept if it must not be ignored
+					if (saveAsGeneralObject) {
+						objects.add(pt);
+					}
+				}
+			}
+			
+			this.__objects = objects;
+		}
+	}
+	
+	/** Make a filter of the percepts.
+	 * <p>
+	 * The system already make a filtering depending
+	 * on the agent's body.
+	 * 
+	 * @param percept is the percept replied by the environment.
+	 * @return the state of the given percept.
+	 */
+	protected abstract PerceptionState filter(PT percept);
+	
+	/** Save the given perception inside internal structures.
+	 * 
+	 * @param percept is the perception to save
+	 * @param state is the detected state of the given perception. It
+	 * will permit to this function to know what to do with the
+	 * perception.
+	 * @return <code>true</code> if the specified percept was saved by
+	 * this function, otherwise <code>false</code>. In this last
+	 * case, the percept will be save inside the generic data structure
+	 * that containing perceived objects.
+	 */
+	protected abstract boolean savePerception(PT percept, PerceptionState state);
+	
+	/** Replied the perceived objects.
+	 */
+	public List<PT> getPerceivedObjects() {
+		return this.__objects;
+	}
+
+	/** Replies if objects were perceived.
+	 */
+	public boolean hasPerceivedObjects() {
+		return ((this.__objects!=null)&&(this.__objects.size()>0));
+	}
+
+}
\ No newline at end of file

Added: trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/agent/SituatedAgent.java
===================================================================
--- trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/agent/SituatedAgent.java	                        (rev 0)
+++ trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/agent/SituatedAgent.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,129 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.situatedEnvironment.agent;
+
+
+import org.arakhne.tinyMAS.core.Agent;
+import org.arakhne.tinyMAS.core.Environment;
+import org.arakhne.tinyMAS.core.Kernel;
+import org.arakhne.tinyMAS.situatedEnvironment.body.AgentBody;
+import org.arakhne.tinyMAS.situatedEnvironment.environment.SituatedEnvironment;
+import org.arakhne.tinyMAS.situatedEnvironment.environment.SituatedObject;
+import org.arakhne.tinyMAS.situatedEnvironment.influence.Influence;
+import org.arakhne.tinyMAS.situatedEnvironment.perception.Perception;
+
+/** Situated agent.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public abstract class SituatedAgent<AB extends AgentBody<?,IT>, OB extends SituatedObject, PT extends Perception<?>, IT extends Influence> extends Agent {
+
+	private PerceptionInterestFilter<PT> __perceptionFilter = null;
+	
+	/** Register the specified filter for the perceptions.
+	 */
+	protected void registerPerceptionFilter(PerceptionInterestFilter<PT> filter) {
+		assert(filter!=null);
+		filter.setParent(this.__perceptionFilter);
+		this.__perceptionFilter = filter;
+	}
+
+	/** Replace the specified filter for the perceptions.
+	 */
+	protected void replacePerceptionFilter(PerceptionInterestFilter<PT> filter) {
+		assert(filter!=null);
+		if (this.__perceptionFilter!=null)
+			filter.setParent(this.__perceptionFilter.getParent());
+		this.__perceptionFilter = filter;
+	}
+
+	/** Replies the current perception filter.
+	 */
+	@SuppressWarnings("unchecked")
+	protected <T extends PerceptionInterestFilter<PT>> T getPerceptionFilter() {
+		return (T)this.__perceptionFilter;
+	}
+
+	/** The function live() implements the classical
+	 * perception-decision-action cycle.
+	 */
+	@Override
+	public final void live() {
+		doPerception();
+		doDecisionAndAction();
+	}
+	
+	/** Replies the situated environment.
+	 */
+	@SuppressWarnings("unchecked")
+	protected final SituatedEnvironment<?,AB,OB,PT,IT> getEnvironment() {
+		Environment env = Kernel.getSingleton().getEnvironment();
+		if (env instanceof SituatedEnvironment) {
+			return (SituatedEnvironment<?,AB,OB,PT,IT>)env;
+		}
+		return null;
+	}
+	
+	/** Do the perception.
+	 */
+	protected void doPerception() {
+		SituatedEnvironment<?,?,?,PT,?> env = getEnvironment();
+		if (env!=null) {
+			if (this.__perceptionFilter==null) {
+				this.__perceptionFilter = new PerceptionInterestFilter<PT>() {
+						@Override
+						protected PerceptionState filter(PT percept) {
+							return PerceptionState.OBJECT;
+						}
+						@Override
+						protected boolean savePerception(PT percept, PerceptionState state) {
+							return false;
+						}
+					};
+			}
+			PT[] percepts = env.perceive(getId());
+			this.__perceptionFilter.filter(percepts);
+		}
+	}
+	
+	/** Replies the body of the agent.
+	 */
+	public final <T extends AB> T getAgentBody() {
+		SituatedEnvironment<?,AB,?,?,?> env = getEnvironment();
+		if (env!=null) {
+			return env.<T>getAgentBody(getId());
+		}
+		return null;
+	}
+
+	/** Do the decision.
+	 */
+	protected abstract void doDecisionAndAction();
+
+	/** Replies the default body for this agent.
+	 * <p>
+	 * This method must be called by the environment when
+	 * the agent arrived inside a situated environment.
+	 */
+	public abstract AB createDefaultBody(SituatedEnvironment<? extends SituatedAgent<AB,OB,PT,IT>,AB,OB,PT,IT> in);
+			
+}
\ No newline at end of file

Added: trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/body/AbstractAgentBody.java
===================================================================
--- trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/body/AbstractAgentBody.java	                        (rev 0)
+++ trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/body/AbstractAgentBody.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,188 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.situatedEnvironment.body;
+
+import java.lang.ref.WeakReference;
+import java.util.concurrent.TimeUnit;
+
+import org.arakhne.tinyMAS.core.AgentIdentifier;
+import org.arakhne.tinyMAS.core.Environment;
+import org.arakhne.tinyMAS.core.Kernel;
+import org.arakhne.tinyMAS.core.Probe;
+import org.arakhne.tinyMAS.situatedEnvironment.agent.SituatedAgent;
+import org.arakhne.tinyMAS.situatedEnvironment.environment.SituatedEnvironment;
+import org.arakhne.tinyMAS.situatedEnvironment.influence.Influence;
+import org.arakhne.tinyMAS.situatedEnvironment.perception.PerceptionBody;
+
+/** Agent body.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public abstract class AbstractAgentBody<PB extends PerceptionBody, IT extends Influence> implements AgentBody<PB,IT> {
+
+	/** This is the identifier of the agent owns this body.
+	 */
+	private final WeakReference<SituatedAgent<?,?,?,?>> __agent;
+	
+	/** Description of the perception characteristics.
+	 */
+	private PB __perception_body;
+
+	/** Indicates if the body was freezed.
+	 * A freezed body can not be moved.
+	 */
+	private boolean __freezed = false;
+
+	public AbstractAgentBody(SituatedAgent<?,?,?,?> agent, PB percepts) {
+		assert(agent!=null);
+		this.__agent = new WeakReference<SituatedAgent<?,?,?,?>>(agent);
+		this.__perception_body = percepts;
+	}
+	
+	public AbstractAgentBody(SituatedAgent<?,?,?,?> agent) {
+		assert(agent!=null);
+		this.__agent = new WeakReference<SituatedAgent<?,?,?,?>>(agent);
+		this.__perception_body = null;
+	}
+	
+	/** Set if this body was freezed.
+	 * A freezed body can not be moved.
+	 */
+	public void freeze() {
+		this.__freezed = true;
+	}
+
+	/** Set if this body was unfreezed.
+	 * A freezed body can not be moved.
+	 */
+	public void unfreeze() {
+		this.__freezed = false;
+	}
+
+	/** Replies if this body was crashed.
+	 * A freezed body can not be moved.
+	 */
+	public boolean isFreezed() {
+		return this.__freezed;
+	}
+	
+
+	/** Replies the situated environment.
+	 */
+	@SuppressWarnings("unchecked")
+	protected final SituatedEnvironment<?,?,?,?,IT> getEnvironment() {
+		Environment env = Kernel.getSingleton().getEnvironment();
+		if (env instanceof SituatedEnvironment) {
+			return (SituatedEnvironment<?,?,?,?,IT>)env;
+		}
+		return null;
+	}
+
+	/** Replies the identifier of the agent that owns this body.
+	 */
+	public final AgentIdentifier getAgent() {
+		return (this.__agent==null) ? null : this.__agent.get().getId();
+	}
+	
+	/** Replies the probe of the agent that owns this body.
+	 */
+	public final Probe getAgentProbe() {
+		SituatedAgent<?,?,?,?> ag = (this.__agent==null) ? null : this.__agent.get();
+		if (ag!=null) {
+			return ag.getProbe();
+		}
+		return null;
+	}
+
+	/** Replies the perception characteristics of thi body.
+	 */
+	public final PB getPerceptionBody() {
+		return this.__perception_body;
+	}
+
+	/** Set the perception characteristics of thi body.
+	 */
+	public final void setPerceptionBody(PB perceptBody) {
+		this.__perception_body = perceptBody;
+	}
+
+	/** Add influences.
+	 */
+	public final boolean influence(IT... influences) {
+		assert((influences!=null)&&(influences.length>0));
+		SituatedEnvironment<?,?,?,?,IT> env = getEnvironment();
+		assert(env!=null);
+		return env.influence(influences);
+	}
+
+	/** Replies the current date of simulation.
+	 * <p>
+	 * The unit depends on the environment's implementation.
+	 * 
+	 * @param desired_unit indicates the unit to use
+	 * @return the simulation's time espressed in the specified unit.
+	 */
+	public double getSimulationTime(TimeUnit desired_unit) {
+		assert(desired_unit!=null);
+		return Kernel.getSingleton().getSimulationClock().getSimulationTime(desired_unit);
+	}
+
+	/** Replies the current date of simulation.
+	 * <p>
+	 * The unit depends on the environment's implementation.
+	 * 
+	 * @return the simulation's time espressed in seconds.
+	 */
+	public double getSimulationTime() {
+		return Kernel.getSingleton().getSimulationClock().getSimulationTime();
+	}
+
+	/** Replies the duration of a simulation loop for this environment.
+	 * 
+	 * @param desired_unit indicates the unit to use
+	 * @return the simulation's step time.
+	 */
+	public double getSimulationStepDuration(TimeUnit desired_unit) {
+		assert(desired_unit!=null);
+		return Kernel.getSingleton().getSimulationClock().getSimulationStepDuration(desired_unit);
+	}
+
+	/** Replies the duration of a simulation loop for this environment.
+	 * 
+	 * @return the simulation's step time in seconds.
+	 */
+	public double getSimulationStepDuration() {
+		return Kernel.getSingleton().getSimulationClock().getSimulationStepDuration();
+	}
+
+	/** Convert the specified quantity specified in
+	 * something per second to the same quantity
+	 * expressed in something per simulation turn.
+	 * 
+	 * @see #getSimulationStepDuration()
+	 * @see #getSimulationStepDuration(TimeUnit)
+	 */
+	public double perSecond(double quantity) {
+		return getSimulationStepDuration(TimeUnit.SECONDS) * quantity;
+	}
+	
+}
\ No newline at end of file

Added: trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/body/AgentBody.java
===================================================================
--- trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/body/AgentBody.java	                        (rev 0)
+++ trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/body/AgentBody.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,58 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.situatedEnvironment.body;
+
+
+import org.arakhne.tinyMAS.core.AgentIdentifier;
+import org.arakhne.tinyMAS.core.Probe;
+import org.arakhne.tinyMAS.situatedEnvironment.environment.SituatedObject;
+import org.arakhne.tinyMAS.situatedEnvironment.influence.Influence;
+import org.arakhne.tinyMAS.situatedEnvironment.perception.PerceptionBody;
+
+/** Agent body.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public interface AgentBody<PB extends PerceptionBody, IT extends Influence> extends SituatedObject {
+
+	/** Replies the identifier of the agent that owns this body.
+	 */
+	public AgentIdentifier getAgent();
+	
+	/** Replies the probe of the agent that owns this body.
+	 */
+	public Probe getAgentProbe();
+
+	/** Replies the perception characteristics of thi body.
+	 */
+	public PB getPerceptionBody();
+	
+	/** Replies if this body was crashed.
+	 * A freezed body can not be moved.
+	 */
+	public boolean isFreezed();
+
+	/** Send an influence to the environment.
+	 */
+	public boolean influence(IT... influences);
+
+}
\ No newline at end of file

Added: trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/environment/AbstractSituatedEnvironment.java
===================================================================
--- trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/environment/AbstractSituatedEnvironment.java	                        (rev 0)
+++ trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/environment/AbstractSituatedEnvironment.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,172 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.situatedEnvironment.environment;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.WeakHashMap;
+
+import org.arakhne.tinyMAS.core.AbstractEnvironment;
+import org.arakhne.tinyMAS.core.AgentIdentifier;
+import org.arakhne.tinyMAS.core.Identifier;
+import org.arakhne.tinyMAS.core.Kernel;
+import org.arakhne.tinyMAS.core.TimeManager;
+import org.arakhne.tinyMAS.situatedEnvironment.agent.SituatedAgent;
+import org.arakhne.tinyMAS.situatedEnvironment.body.AgentBody;
+import org.arakhne.tinyMAS.situatedEnvironment.influence.Influence;
+import org.arakhne.tinyMAS.situatedEnvironment.perception.Perception;
+
+/** Situated environment model.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public abstract class AbstractSituatedEnvironment<AT extends SituatedAgent<AB,OB,PT,IT>, AB extends AgentBody<?,IT>, OB extends SituatedObject, PT extends Perception<?>, IT extends Influence> extends AbstractEnvironment<AT> implements SituatedEnvironment<AT,AB,OB,PT,IT> {
+
+	/** List of the agent's bodies.
+	 */
+	private final Map<AgentIdentifier,AB> __agent_bodies = new WeakHashMap<AgentIdentifier,AB>();
+	
+	/** List of the object's bodies.
+	 */
+	private final Map<Identifier,OB> __objects = new TreeMap<Identifier,OB>();
+
+	/** List of influences.
+	 */
+	private final List<IT> __influences = new ArrayList<IT>();
+	
+	public AbstractSituatedEnvironment(TimeManager time_manager) {
+		super(time_manager);
+	}
+	
+	/** Shutdown this environment.
+	 */
+	@Override
+	public void shutdown() {
+		super.shutdown();
+		this.__agent_bodies.clear();
+		this.__objects.clear();
+	}
+	
+	/** This function os called by the called after
+	 * the on scheduling step of the agents.
+	 */
+	@Override
+	public void postAgentScheduling(Kernel<AT,?,?,?> runningKernel) {
+		// Applies the influences and computes the reactions
+		applyInfluences(this.__influences);
+		this.__influences.clear();
+
+		//
+		// Finish the loop
+		//
+		super.postAgentScheduling(runningKernel);
+	}
+
+	/** Put the given agent inside the environment.
+	 */
+	@Override
+	public void putAgent(AT agent) {
+		assert(agent!=null);
+		final AgentIdentifier id = agent.getId();
+		final AB body = agent.createDefaultBody(this);
+		if (body!=null) {
+			this.__agent_bodies.put(id,body);
+			onAgentBodyAdded(body);
+		}
+	}
+	
+	/** Put the given body onto its location.
+	 */
+	protected abstract void onAgentBodyAdded(AB body);
+	
+	/** Remove the given body from the environment.
+	 */
+	protected abstract void onAgentBodyRemoved(AB body);
+
+	/** Put the given agent on the given segment
+
+	/** Remove the given agent from the environment.
+	 */
+	@Override
+	public void removeAgent(AgentIdentifier agent) {
+		assert(agent!=null);
+		AB body = this.__agent_bodies.get(agent);
+		if (body!=null) {
+			this.__agent_bodies.remove(agent);
+			onAgentBodyRemoved(body);
+		}
+	}
+
+	/** Replies all the bodies of the agents inside the environment.
+	 */
+	public Collection<AB> getAllAgentBodies() {
+		ArrayList<AB> list = new ArrayList<AB>();
+		list.addAll(this.__agent_bodies.values());
+		return list;
+	}
+
+	/** Replies the body of the agent inside the environment.
+	 * 
+	 * @return the location according to the environment dimension, ie.
+	 * an array of size 1 if the environment is 1D, of size 2 for
+	 * an 2D environment...
+	 */
+	@SuppressWarnings("unchecked")
+	public <T extends AB> T getAgentBody(AgentIdentifier agent) {
+		assert(agent!=null);
+		return (T)this.__agent_bodies.get(agent);
+	}
+
+	/** Replies the location of the object (excluding
+	 * agents) inside the environment.
+	 * 
+	 * @return the spatial description of the object. 
+	 */
+	public OB getObjectBody(Identifier object) {
+		assert(object!=null);
+		return this.__objects.get(object);
+	}
+
+	/** This function is called when the environment must compute
+	 * its reaction to the agent influences.
+	 * <p>
+	 * This method must fill the list of reactions according
+	 * to its computation on the agent's influences. 
+	 * 
+	 * @return <code>true</code> if the reaction was successfully computed,
+	 * otherwise <code>false</code>
+	 */
+	protected abstract boolean applyInfluences(Collection<IT> influences);
+
+	/** Send influences to the environment.
+	 */
+	public final boolean influence(IT... influences) {
+		assert((influences!=null)&&(influences.length>0));
+		// Register the influences
+		return this.__influences.addAll(Arrays.asList(influences));
+	}
+
+}
\ No newline at end of file

Added: trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/environment/SituatedEnvironment.java
===================================================================
--- trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/environment/SituatedEnvironment.java	                        (rev 0)
+++ trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/environment/SituatedEnvironment.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,72 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.situatedEnvironment.environment;
+
+
+import java.util.Collection;
+
+import org.arakhne.tinyMAS.core.AgentIdentifier;
+import org.arakhne.tinyMAS.core.Environment;
+import org.arakhne.tinyMAS.core.Identifier;
+import org.arakhne.tinyMAS.situatedEnvironment.agent.SituatedAgent;
+import org.arakhne.tinyMAS.situatedEnvironment.body.AgentBody;
+import org.arakhne.tinyMAS.situatedEnvironment.influence.Influence;
+import org.arakhne.tinyMAS.situatedEnvironment.perception.Perception;
+
+/** Interface representant un environment.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public interface SituatedEnvironment<AT extends SituatedAgent<AB,OB,PT,IT>, AB extends AgentBody<?,IT>, OB extends SituatedObject, PT extends Perception<?>, IT extends Influence> extends Environment<AT> {
+
+	/** Replies all the bodies of the agents inside the environment.
+	 */
+	public Collection<AB> getAllAgentBodies();
+
+	/** Replies the body of the agent inside the environment.
+	 * 
+	 * @return the location according to the environment dimension, ie.
+	 * an array of size 1 if the environment is 1D, of size 2 for
+	 * an 2D environment...
+	 */
+	public <T extends AB> T getAgentBody(AgentIdentifier agent);
+
+	/** Replies the location of the object (excluding
+	 * agents) inside the environment.
+	 * 
+	 * @return the spatial description of the object. 
+	 */
+	public OB getObjectBody(Identifier object);
+	
+	/** Send an influence to the environment.
+	 * 
+	 * @param influences is the list of influences to send to this environment.
+	 * @return <code>true</code> if the influences was registered,
+	 * otherwise <code>false</code> 
+	 */
+	public boolean influence(IT... influences);
+	
+	/** Compute and replies the perceptions for the specified agent.
+	 */
+	public PT[] perceive(AgentIdentifier agent);	
+
+}
\ No newline at end of file

Added: trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/environment/SituatedObject.java
===================================================================
--- trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/environment/SituatedObject.java	                        (rev 0)
+++ trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/environment/SituatedObject.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,72 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.situatedEnvironment.environment;
+
+import java.util.concurrent.TimeUnit;
+
+
+/** Object body.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public interface SituatedObject {
+
+	/** Replies the current date of simulation.
+	 * <p>
+	 * The unit depends on the environment's implementation.
+	 * 
+	 * @param desired_unit indicates the unit to use
+	 * @return the simulation's time espressed in the specified unit.
+	 */
+	public double getSimulationTime(TimeUnit desired_unit);
+
+	/** Replies the current date of simulation.
+	 * <p>
+	 * The unit depends on the environment's implementation.
+	 * 
+	 * @return the simulation's time espressed in seconds.
+	 */
+	public double getSimulationTime();
+
+	/** Replies the duration of a simulation loop for this environment.
+	 * 
+	 * @param desired_unit indicates the unit to use
+	 * @return the simulation's step time.
+	 */
+	public double getSimulationStepDuration(TimeUnit desired_unit);
+
+	/** Replies the duration of a simulation loop for this environment.
+	 * 
+	 * @return the simulation's step time in seconds.
+	 */
+	public double getSimulationStepDuration();
+	
+	/** Convert the specified quantity specified in
+	 * something per second to the same quantity
+	 * expressed in something per simulation turn.
+	 * 
+	 * @see #getSimulationStepDuration()
+	 * @see #getSimulationStepDuration(TimeUnit)
+	 */
+	public double perSecond(double quantity);
+
+}
\ No newline at end of file

Added: trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/influence/Influence.java
===================================================================
--- trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/influence/Influence.java	                        (rev 0)
+++ trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/influence/Influence.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,54 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.situatedEnvironment.influence;
+
+import java.lang.ref.WeakReference;
+
+import org.arakhne.tinyMAS.core.AgentIdentifier;
+
+/** This class describes an influence inside an environment.
+ * <p>
+ * An influence is a desired of action emitted by an agent.
+ * The environment collects all the influences and tries
+ * to applies them according to the environment's rules.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ * @author Nicolas GAUD &lt;nicolas.gaud@xxxxxxx&gt;
+ */
+public abstract class Influence {
+
+	/** This is the identifier of the influenced object.
+	 */
+	private final WeakReference<AgentIdentifier> __emitter;
+	
+	protected Influence(AgentIdentifier emitter) {
+		assert(emitter!=null);
+		this.__emitter = new WeakReference<AgentIdentifier>(emitter);
+	}
+
+	/** Replies the identifier of the agent that sent this influence.
+	 */
+	public AgentIdentifier getEmitter() {
+		return (this.__emitter==null) ? null : this.__emitter.get();
+	}
+	
+}
\ No newline at end of file

Added: trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/perception/EntityPerception.java
===================================================================
--- trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/perception/EntityPerception.java	                        (rev 0)
+++ trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/perception/EntityPerception.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,44 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.situatedEnvironment.perception;
+
+import org.arakhne.tinyMAS.core.Identifier;
+
+/** This class describes a perception inside an environment.
+ * <p>
+ * The concept of percpetion permits to agents to obtain informations
+ * on the environment.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ * @author Nicolas GAUD &lt;nicolas.gaud@xxxxxxx&gt;
+ */
+public class EntityPerception extends Perception<Identifier> {
+
+	public EntityPerception(Identifier perceived_object) {
+		super(perceived_object);
+	}
+	
+	public Identifier getPerceivedObject() {
+		return getData();
+	}
+	
+}
\ No newline at end of file

Added: trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/perception/Perception.java
===================================================================
--- trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/perception/Perception.java	                        (rev 0)
+++ trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/perception/Perception.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,46 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.situatedEnvironment.perception;
+
+/** This class describes a perception inside an environment.
+ * <p>
+ * The concept of percpetion permits to agents to obtain informations
+ * on the environment.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ * @author Nicolas GAUD &lt;nicolas.gaud@xxxxxxx&gt;
+ */
+public abstract class Perception<T> {
+
+	private final T data;
+	
+	public Perception(T data) {
+		this.data = data;
+	}
+	
+	/** Replies the data associated to this perception.
+	 */
+	public T getData() {
+		return this.data;
+	}
+	
+}
\ No newline at end of file

Added: trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/perception/PerceptionBody.java
===================================================================
--- trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/perception/PerceptionBody.java	                        (rev 0)
+++ trunk/tinymas-environment/src/main/java/org/arakhne/tinyMAS/situatedEnvironment/perception/PerceptionBody.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,32 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.situatedEnvironment.perception;
+
+
+/** A body describing the characteristics of the perceptions of
+ * an agent's body.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public interface PerceptionBody {
+	//
+}
\ No newline at end of file

Added: trunk/tinymas-kernel/pom.xml
===================================================================
--- trunk/tinymas-kernel/pom.xml	                        (rev 0)
+++ trunk/tinymas-kernel/pom.xml	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd";>
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+	<artifactId>project</artifactId>
+	<groupId>org.arakhne.tinymas</groupId>
+	<version>1.0-SNAPSHOT</version>
+  </parent>
+
+  <groupId>org.arakhne.tinymas</groupId>
+  <artifactId>tinymas-kernel</artifactId>
+  <packaging>jar</packaging>
+  <version>${version_tinymas_kernel}</version>
+  <name>TinyMAS Kernel</name>
+  <url>http://www.arakhne.org/tinymas/</url>
+
+	<!-- ======================================= -->
+	<!-- ====       Project Information      === -->
+	<!-- ======================================= -->
+		
+	<scm>
+		<url>http://www.arakhne.org/websvn.php?project=tinymas&amp;subproject=kernel</url>
+	</scm>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.arakhne.afc</groupId>
+			<artifactId>arakhneRefs</artifactId>
+		</dependency>
+	</dependencies>
+
+</project>

Added: trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/AbstractEnvironment.java
===================================================================
--- trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/AbstractEnvironment.java	                        (rev 0)
+++ trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/AbstractEnvironment.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,220 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.core;
+
+import java.lang.ref.WeakReference;
+import java.util.concurrent.TimeUnit;
+
+/** Abstract environment model.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ * @author Nicolas GAUD &lt;nicolas.gaud@xxxxxxx&gt;
+ */
+public abstract class AbstractEnvironment<AT extends Agent> implements Environment<AT> {
+
+	/** Unit used to compute the simulation time.
+	 */
+	protected final TimeManager _time_manager;
+	
+	/** Simulation clock.
+	 */
+	protected final EnvironmentClock _clock;
+
+	/** Indicates if this environment must be killed.
+	 */
+	private boolean killme = false;
+	
+	public AbstractEnvironment(TimeManager time_manager) {
+		this._time_manager = time_manager;
+		this._clock = new EnvironmentClock(time_manager);
+	}
+	
+	/** Replies if this environment is alive.
+	 * <p>
+	 * If the environment is not alive, the multiagent kernel
+	 * will quit.
+	 */
+	public boolean isAlive() {
+		return !this.killme;
+	}
+
+	/** Notify the kernel that this environment is requesting to be killed.
+	 * <p>
+	 * When a situated environment desappear, all the agents inside will be
+	 * killed also.
+	 */
+	protected void killMe() {
+		this.killme = true;
+	}
+
+	/** Initialize this environment.
+	 */
+	public void init() {
+		//
+	}
+
+	/** Shutdown this environment.
+	 */
+	public void shutdown() {
+		//
+	}
+
+	/** Put the given agent inside the environment.
+	 */
+	public abstract void putAgent(AT agent);
+	
+	/** Remove the given agent from the environment.
+	 */
+	public abstract void removeAgent(AgentIdentifier agent);
+
+	/** This function os called by the called before
+	 * the on scheduling step of the agents.
+	 * 
+	 * @param runningKernel is the instance of the kernel that is running this environment.
+	 */
+	public void preAgentScheduling(final Kernel<AT,?,?,?> runningKernel) {
+		this._time_manager.beforeAgentScheduling(
+				runningKernel.getKernelStep(),
+				runningKernel.getKernelStepDuration());
+	}
+
+	/** This function os called by the called after
+	 * the on scheduling step of the agents.
+	 * 
+	 * @param runningKernel is the instance of the kernel that is running this environment.
+	 */
+	public void postAgentScheduling(final Kernel<AT,?,?,?> runningKernel) {
+		this._time_manager.afterAgentScheduling(
+				runningKernel.getKernelStep(),
+				runningKernel.getKernelStepDuration());
+	}
+
+	/** Replies the current date of simulation.
+	 * <p>
+	 * The unit depends on the environment's implementation.
+	 * 
+	 * @param desired_unit indicates the unit to use
+	 * @return the simulation's time espressed in the specified unit.
+	 */
+	public final double getSimulationTime(TimeUnit desired_unit) {
+		assert(desired_unit!=null);
+		return this._time_manager.getSimulationTime(desired_unit);
+	}
+
+	/** Replies the current date of simulation.
+	 * <p>
+	 * The unit depends on the environment's implementation.
+	 * 
+	 * @return the simulation's time espressed in seconds.
+	 */
+	public final double getSimulationTime() {
+		return this._time_manager.getSimulationTime();
+	}
+
+	/** Replies the duration of a simulation loop for this environment.
+	 * 
+	 * @param desired_unit indicates the unit to use
+	 * @return the simulation's step time.
+	 */
+	public final double getSimulationStepDuration(TimeUnit desired_unit) {
+		assert(desired_unit!=null);
+		return this._time_manager.getSimulationStepDuration(desired_unit);
+	}
+
+	/** Replies the duration of a simulation loop for this environment.
+	 * 
+	 * @return the simulation's step time.
+	 */
+	public final double getSimulationStepDuration() {
+		return this._time_manager.getSimulationStepDuration();
+	}
+	
+	/** Replies the clock used by the environment.
+	 * 
+	 * @return never <code>null</code>
+	 */
+	public final SimulationClock getSimulationClock() {
+		return this._clock;
+	}
+
+	/** Abstract environment model.
+	 * 
+	 * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+	 * @author Nicolas GAUD &lt;nicolas.gaud@xxxxxxx&gt;
+	 */
+	private static class EnvironmentClock implements SimulationClock {
+
+		private final WeakReference<TimeManager> manager;
+		
+		public EnvironmentClock(TimeManager manager) {
+			this.manager = new WeakReference<TimeManager>(manager);
+		}
+		
+		/** {@inheritDoc}
+		 */
+		public double getSimulationTime(TimeUnit desired_unit) {
+			TimeManager tm = this.manager.get();
+			if (tm==null) throw new NullPointerException("no associated time manager"); //$NON-NLS-1$
+			return tm.getSimulationTime(desired_unit);
+		}
+
+		/** {@inheritDoc}
+		 */
+		public double getSimulationTime() {
+			TimeManager tm = this.manager.get();
+			if (tm==null) throw new NullPointerException("no associated time manager"); //$NON-NLS-1$
+			return tm.getSimulationTime();
+		}
+
+		/** {@inheritDoc}
+		 */
+		public double getSimulationStepDuration(TimeUnit desired_unit) {
+			TimeManager tm = this.manager.get();
+			if (tm==null) throw new NullPointerException("no associated time manager"); //$NON-NLS-1$
+			return tm.getSimulationStepDuration(desired_unit);
+		}
+
+		/** {@inheritDoc}
+		 */
+		public double getSimulationStepDuration() {
+			TimeManager tm = this.manager.get();
+			if (tm==null) throw new NullPointerException("no associated time manager"); //$NON-NLS-1$
+			return tm.getSimulationStepDuration();
+		}
+
+		/** Compute a value expressed in something per time unit into
+		 * something per simulation loop.
+		 */
+		public double perTimeUnit(double value) {
+			return perTimeUnit(value, TimeUnit.SECONDS);
+		}
+
+		/** Compute a value expressed in something per time unit into
+		 * something per simulation loop.
+		 */
+		public double perTimeUnit(double value, TimeUnit desiredUnit) {
+			return value * getSimulationStepDuration(desiredUnit);
+		}
+
+	}
+	
+}
\ No newline at end of file

Added: trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/AbstractScheduler.java
===================================================================
--- trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/AbstractScheduler.java	                        (rev 0)
+++ trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/AbstractScheduler.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,55 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.core;
+
+import java.util.List;
+
+/** Default scheduler for agents.
+ * <p>
+ * This scheduler shuffles the list of agents and run them in a sequential way.
+ *
+ * @param <AT> is the type of the agents to schedule.
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ * @author Nicolas GAUD &lt;nicolas.gaud@xxxxxxx&gt;
+ */
+public abstract class AbstractScheduler<AT extends Agent> implements Scheduler<AT> {
+
+	/** {@inheritDoc}
+	 */
+	public void schedule(Kernel<AT,?,?,?> runningKernel, Environment<AT> environment, List<AT> agents) {
+		//
+		// Stage of pre-scheduling
+		//
+		environment.preAgentScheduling(runningKernel);
+		
+		//
+		// Stage of agent execution
+		//
+		schedule(agents) ;
+		
+		//
+		// Stage of post-scheduling
+		//
+		environment.postAgentScheduling(runningKernel);
+	}
+
+}
\ No newline at end of file

Added: trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/AbstractTimeManager.java
===================================================================
--- trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/AbstractTimeManager.java	                        (rev 0)
+++ trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/AbstractTimeManager.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,124 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.core;
+
+import java.util.concurrent.TimeUnit;
+
+/** Time Manager.
+ * <p>
+ * <code>simulation_time(t+1) = simulation_time(t) + step_duration</code>
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ * @author Nicolas GAUD &lt;nicolas.gaud@xxxxxxx&gt;
+ */
+public abstract class AbstractTimeManager extends TimeManager {
+	
+	/** Current simulation time (in seconds).
+	 */
+	private volatile double __simulation_time = 0; 
+	
+	/** Current simulation step duration (in milliseconds).
+	 */
+	private volatile double __simulation_step_duration = 0; 
+
+	/** Set the current simulation time. It is the count of
+	 * seconds since the starting of the simulation.
+	 * <p>
+	 * <code>simulation_time(t+1) = simulation_time(t) + step_duration</code>
+	 * 
+	 * @param time is the new simulation time expresed in seconds.
+	 */
+	@Override
+	protected void setSimulationTime(double time) {
+		this.__simulation_time = time;
+	}
+	
+	/** Set the current simulation step duration. It is the duration
+	 * of one simulation step expressed in the simulation time
+	 * coordinate system.
+	 * <p>
+	 * <code>simulation_time(t+1) = simulation_time(t) + step_duration</code>
+	 * 
+	 * @param step_duration is the new simulation time expressed in milliseconds.
+	 */
+	@Override
+	protected void setSimulationStepDuration(double step_duration) {
+		this.__simulation_step_duration = step_duration;
+	}
+
+	/** Replies the current date of simulation.
+	 * 
+	 * @param desired_unit indicates the unit to use
+	 * @return the simulation's time espressed in the specified unit.
+	 */
+	@Override
+	public final double getSimulationTime(TimeUnit desired_unit) {
+		assert(desired_unit!=null);
+		double time = 0;
+		switch(desired_unit) {
+		case MICROSECONDS:
+			time = MeasureUtil.unit2micro(this.__simulation_time);
+			break;
+		case MILLISECONDS:
+			time = MeasureUtil.unit2milli(this.__simulation_time);
+			break;
+		case NANOSECONDS:
+			time = MeasureUtil.unit2nano(this.__simulation_time);
+			break;
+		case SECONDS:
+			time = this.__simulation_time;
+			break;
+		default:
+		}
+		return time;
+	}
+
+	/** Replies the duration of a simulation loop for this environment.
+	 * <p>
+	 * <code>simulation_time(t+1) = simulation_time(t) + step_duration</code>
+	 * 
+	 * @param desired_unit indicates the unit to use
+	 * @return the simulation's step time.
+	 */
+	@Override
+	public final double getSimulationStepDuration(TimeUnit desired_unit) {
+		assert(desired_unit!=null);
+		double time = 0;
+		switch(desired_unit) {
+		case MICROSECONDS:
+			time = MeasureUtil.milli2micro(this.__simulation_step_duration);
+			break;
+		case MILLISECONDS:
+			time = this.__simulation_step_duration;
+			break;
+		case NANOSECONDS:
+			time = MeasureUtil.milli2nano(this.__simulation_step_duration);
+			break;
+		case SECONDS:
+			time = MeasureUtil.milli2unit(this.__simulation_step_duration);
+			break;
+		default:
+		}
+		return time;
+	}
+
+}
\ No newline at end of file

Added: trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/Agent.java
===================================================================
--- trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/Agent.java	                        (rev 0)
+++ trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/Agent.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,319 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.core;
+
+import java.io.Serializable;
+import java.util.concurrent.TimeUnit;
+
+/** Abstract class that represents an agent.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ * @author Nicolas GAUD &lt;nicolas.gaud@xxxxxxx&gt;
+ */
+public abstract class Agent implements Comparable<Agent> {
+	
+	/** Identifier of an agent.
+	 */
+	private volatile AgentIdentifier __id ;
+	
+	private boolean __started = false;
+	
+	/** Probe.
+	 */
+	private DefaultProbe __probe = null;
+	
+	/** Create an uninitialized agent.
+	 */
+	public Agent() {
+		this.__id = null ;
+	}
+	
+	/** Force the identifier of this agent to adopt the string representation
+	 * of this agent.
+	 * 
+	 * @see #toString()
+	 */
+	protected void forceIdentifierStringRepresentation() {
+		forceIdentifierStringRepresentation(toString());
+	}
+	
+	/** Force the identifier of this agent to adopt the string representation
+	 * of this agent.
+	 */
+	protected void forceIdentifierStringRepresentation(String str) {
+		if (this.__id!=null)
+			this.__id.setStringRepresentation(str);
+	}
+
+	/** Replies a probe on this agent.
+	 * 
+	 * @return a probe or <code>null</code> if this agent
+	 * could not provide a probe.
+	 */
+	public Probe getProbe() {
+		synchronized(this) {
+			return this.__probe;
+		}
+	}
+
+	/** Set value that could be probed by another entity.
+	 * 
+	 * @param probeName is the name of the value.
+	 * @param value is the value that could be obtained by a probe user.
+	 */
+	protected void setProbe(String probeName, Object value) {
+		synchronized(this) {
+			assert((probeName!=null)&&(!"".equals(probeName))); //$NON-NLS-1$
+			if (value==null) {
+				if (this.__probe!=null) {
+					this.__probe.removeProbeValue(probeName);
+					if (!this.__probe.hasProbeValues()) {
+						this.__probe = null;
+					}
+				}
+			}
+			else {
+				if (this.__probe==null) {
+					this.__probe = new DefaultProbe(this);
+				}
+				this.__probe.putProbeValue(probeName,value);
+			}
+		}
+	}
+
+	/** Clear the probes.
+	 */
+	protected void clearProbes() {
+		synchronized(this) {
+			this.__probe.clearProbeValues();
+			this.__probe = null;
+		}
+	}
+
+	/** Remove a probe.
+	 */
+	protected void removeProbe(String probeName) {
+		synchronized(this) {
+			assert((probeName!=null)&&(!"".equals(probeName))); //$NON-NLS-1$
+			if (this.__probe!=null) {
+				this.__probe.removeProbeValue(probeName);
+				if (!this.__probe.hasProbeValues()) {
+					this.__probe = null;
+				}
+			}
+		}
+	}
+
+	/** Remove all the probes.
+	 */
+	protected void removeAllProbes() {
+		synchronized(this) {
+			if (this.__probe!=null) {
+				this.__probe.clearProbeValues();
+				this.__probe = null;
+			}
+		}
+	}
+
+	public int compareTo(Agent a) {
+		if ((a==null)||(a.getId()==null)) return 1;
+		if (this.__id==null) return -1;
+		return this.__id.compareTo(a.getId());
+	}
+
+	@Override
+	public boolean equals(Object o) {
+		if ((o!=null)&&(o==this)) return true;
+		if ((o!=null)&&(o instanceof Agent)) {
+			return compareTo((Agent)o)==0;
+		}
+		if ((o!=null)&&(o instanceof AgentIdentifier)) {
+			return ((AgentIdentifier)o).compareTo(this.__id)==0;
+		}
+		return false;
+	}
+
+	/** Replies the identifier of the agent.
+	 */	
+	public final AgentIdentifier getId() {
+		return this.__id ;
+	}
+	
+	/** Set the agent's identifier of this agent.
+	 * 
+	 * @param id is the identifier computed by the kernel.
+	 */
+	void setId(AgentIdentifier id) {
+		this.__id = id ;
+	}
+	
+	/** Replies if this agent living.
+	 */
+	boolean isAlive() {
+		return this.__started && this.__id!=null;
+	}
+
+	/** Start the life of an agent.
+	 *  <p>
+	 *  This method must initialize the simulation's attributes of the agent.
+	 * 
+	 * @param id is the identifier of the agent.
+	 */
+	final void start(AgentIdentifier id) {
+		assert(id!=null);
+		this.__started = true;
+		this.__id = id ;
+		start();
+	}
+	
+	/** Start the life of an agent.
+	 *  <p>
+	 *  This method must initialize the simulation's attributes of the agent.
+	 */
+	public void start() {
+		//
+	}
+
+	/** Notify the agent that it must run one step of its life.
+	 */
+	public abstract void live() ;
+
+	/** Invoked when the agent is dead and must deasappear.
+	 * <p>
+	 * This method is supposed to released any computer resource
+	 * allocated by the agent.
+	 */	
+	public void stop() {
+		this.__started = false;
+		this.__id = null ;
+	}
+
+	/** Send a message to another agent.
+	 * 
+	 * @param to is the identifier of the message receiver.
+	 * @param content is the content of the message. 
+	 * @return <code>true</code> if the message was send, otherwise <code>false</code>
+	 */	
+	protected final boolean sendMessage(AgentIdentifier to, Serializable content) {
+		assert(to!=null);
+		if (this.__id!=null) {
+			Message m = new Message(this.__id,to,content) ;
+			return Kernel.getSingleton().getMTS().send(m) ;
+		}
+		return false ;
+	}
+	
+	/** Replies the next message available for this agent.
+	 * 
+	 * @return the message or <code>null</code> if none was available
+	 */
+	protected final Message getNextMessage() {
+		if (this.__id!=null) {
+			return Kernel.getSingleton().getMTS().getNextMessage(this.__id) ;
+		}
+		return null ;
+	}
+
+	/** Replies if a message is available.
+	 */
+	protected final boolean hasMessage() {
+		if (this.__id!=null) {
+			return Kernel.getSingleton().getMTS().hasMessage(this.__id) ;
+		}
+		return false ;
+	}
+
+	/** The agent should invoke this method to kill itself.
+	 */
+	protected final void killMe() {
+		Kernel.getSingleton().killAgent(this.__id);		
+	}
+	
+	/** Replies the simulation times in milliseconds.
+	 */
+	protected final double getSimulationTime() {
+		return Kernel.getSingleton().getSimulationClock().getSimulationTime(TimeUnit.MILLISECONDS);
+	}
+
+	/** Replies the simulation times.
+	 */
+	protected final double getSimulationTime(TimeUnit timeUnit) {
+		assert(timeUnit!=null);
+		return Kernel.getSingleton().getSimulationClock().getSimulationTime(timeUnit);
+	}
+
+	/** Replies the duration in milliseconds of one turn of the simulation.
+	 */
+	protected final double getSimulationStepDuration() {
+		return getSimulationStepDuration(TimeUnit.MILLISECONDS);
+	}
+
+	/** Replies the duration of a simulation loop for this environment.
+	 * 
+	 * @param desired_unit indicates the unit to use
+	 * @return the simulation's step time.
+	 */
+	protected double getSimulationStepDuration(TimeUnit desired_unit) {
+		assert(desired_unit!=null);
+		return Kernel.getSingleton().getSimulationClock().getSimulationStepDuration(desired_unit);
+	}
+
+	/** Convert the specified quantity specified in
+	 * something per second to the same quantity
+	 * expressed in something per simulation turn.
+	 * 
+	 * @see #getSimulationStepDuration()
+	 * @see #getSimulationStepDuration(TimeUnit)
+	 */
+	protected double perSecond(double quantity) {
+		return getSimulationStepDuration(TimeUnit.SECONDS) * quantity;
+	}
+	
+	/** Register this agent as a provider of the specified services.
+	 */
+	protected final void registerService(String... services) {
+		Kernel<?,?,?,?> k = Kernel.getSingleton();
+		assert(k!=null);
+		assert(this.__id!=null);
+		YellowPages yp = k.getYellowPageSystem();
+		if (yp!=null) {
+			for (String service : services) {
+				yp.registerService(service, this.__id);
+			}
+		}
+	}
+
+	/** Unregister this agent as a provider of the specified services.
+	 */
+	protected final void unregisterService(String... services) {
+		Kernel<?,?,?,?> k = Kernel.getSingleton();
+		assert(k!=null);
+		assert(this.__id!=null);
+		YellowPages yp = k.getYellowPageSystem();
+		if (yp!=null) {
+			for (String service : services) {
+				yp.unregisterService(service, this.__id);
+			}
+		}
+	}
+
+}
\ No newline at end of file

Added: trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/AgentIdentifier.java
===================================================================
--- trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/AgentIdentifier.java	                        (rev 0)
+++ trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/AgentIdentifier.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,132 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.core;
+
+import java.rmi.server.UID;
+import java.util.UUID;
+
+
+/** Unique identifier of an agent.
+ * <p>
+ * The agent identifier must be unique along all the kernel which are accessible by this agent.
+ * <p>
+ * This identifier is composed of two parts:
+ * <ul>
+ * <li>the kernel's identifier</li> where the agent was spawn for the first time; if the agent has migrated, this part does not reflect the
+ * kernel where the agent is currently run.</li>
+ * <li>a unique identifier (see {@link UUID})</li>
+ * </ul>
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ * @author Nicolas GAUD &lt;nicolas.gaud@xxxxxxx&gt;
+ */
+public class AgentIdentifier implements Identifier {
+
+	private static final long serialVersionUID = 2423898722296398245L;
+	
+	private final KernelIdentifier __kernel_id;
+	private final String __agent_id;
+	
+	private String representation;
+	
+	/** Create a new identifier.
+	 */
+	public AgentIdentifier() {
+		this(Kernel.getSingleton().getKernelId(),
+				new UID().toString());
+	}
+
+	/** Spawn an existing identifier.
+	 * 
+	 * @param kernelId is the kernel identifier where the agent was spawn for the first time.
+	 * @param agentId is the agent identifier computed by the kernel.
+	 */
+	public AgentIdentifier(KernelIdentifier kernelId, String agentId) {
+		assert(kernelId!=null);
+		assert(agentId!=null);
+		this.__kernel_id = kernelId;
+		this.__agent_id = agentId;
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public String toString() {
+		StringBuffer buf = new StringBuffer();
+		buf.append(this.__agent_id);
+		buf.append(':');
+		buf.append(Long.toHexString(serialVersionUID));
+		buf.append('@');
+		buf.append(this.__kernel_id.toString());
+		return buf.toString();
+	}
+
+	/** Replies the string representation associated to this identifier or
+	 * if it was never set, the result of {@link #toString()}
+	 * 
+	 * @return the string representation of this identifier.
+	 */
+	public String getString() {
+		if (this.representation!=null) return this.representation;
+		return toString();
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public boolean equals(Object o) {
+		if (o instanceof Identifier) {
+			return compareTo((Identifier)o)==0;
+		}
+		return false;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public int compareTo(Identifier id) {
+		if (id==null) return 1;
+		return toString().compareTo(id.toString());
+	}
+
+	/** Replies the kernel's identifier part of this agent's identifier.
+	 * <p>
+	 * The kernel identifier basically corresponds to the kernel that
+	 * on which the agent was spawn for the first time.
+	 * 
+	 * @return the identifier of the kernel on which the agent is located.
+	 */
+	public KernelIdentifier getKernelId() {
+		return this.__kernel_id;
+	}
+	
+	/** Set the string representation of this identifier.
+	 * 
+	 * @param str is the string representation associated to this identifier.
+	 */
+	void setStringRepresentation(String str) {
+		this.representation = str;
+	}
+	
+}
\ No newline at end of file

Added: trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/ConstantStepTimeManager.java
===================================================================
--- trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/ConstantStepTimeManager.java	                        (rev 0)
+++ trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/ConstantStepTimeManager.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,78 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.core;
+
+import java.util.concurrent.TimeUnit;
+
+/** Time Manager based on constant time steps.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ * @author Nicolas GAUD &lt;nicolas.gaud@xxxxxxx&gt;
+ */
+public class ConstantStepTimeManager extends AbstractTimeManager {
+
+	/**
+	 * @param time_step is the constant time step used by this manager.
+	 * @param time_unit is the unit to express the constant time step.
+	 */
+	public ConstantStepTimeManager(long time_step, TimeUnit time_unit) {
+		assert(time_unit!=null);
+		switch(time_unit) {
+		case SECONDS:
+			setSimulationStepDuration(MeasureUtil.unit2milli(time_step));
+			break;
+		case MILLISECONDS:
+			setSimulationStepDuration(time_step);
+			break;
+		case MICROSECONDS:
+			setSimulationStepDuration(MeasureUtil.micro2milli(time_step));
+			break;
+		case NANOSECONDS:
+			setSimulationStepDuration(MeasureUtil.nano2milli(time_step));
+			break;
+		default:
+		}
+	}
+	
+	/** Called by the environment before the scheduling of the agents.
+	 * 
+	 * @param kernel_time is the current kernel date.
+	 * @param last_kernel_step_duration is the duration of the last
+	 * kernel step in milliseconds.
+	 */
+	@Override
+	protected void preAgentScheduling(long kernel_time, long last_kernel_step_duration) {
+		setSimulationTime(kernel_time * getSimulationStepDuration(TimeUnit.SECONDS));
+	}
+
+	/** Called by the environment before the scheduling of the agents.
+	 * 
+	 * @param kernel_time is the current kernel date.
+	 * @param last_kernel_step_duration is the duration of the last
+	 * kernel step in milliseconds.
+	 */
+	@Override
+	protected void postAgentScheduling(long kernel_time, long last_kernel_step_duration) {
+		//
+	}
+
+}
\ No newline at end of file

Added: trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/DefaultProbe.java
===================================================================
--- trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/DefaultProbe.java	                        (rev 0)
+++ trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/DefaultProbe.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,282 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.core;
+
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Array;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+/** A probe permits to obtain information on agents.
+ * <p>
+ * A probe must not be invasive and the agent is
+ * able to ignore them (ie. to not provide information).
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ * @author Nicolas GAUD &lt;nicolas.gaud@xxxxxxx&gt;
+ */
+class DefaultProbe implements Probe {
+
+	private final Map<String,Object> __values = new TreeMap<String,Object>();
+	
+	private final WeakReference<Agent> __agent;
+	
+	DefaultProbe(Agent agent) {
+		assert(agent!=null);
+		this.__agent = new WeakReference<Agent>(agent);
+	}
+	
+	/** Replies the names of the probed values inside the agent.
+	 */
+	public final String[] getProbeNames() {
+		Set<String> theSet = this.__values.keySet();
+		String[] tab = new String[theSet.size()];
+		theSet.toArray(tab);
+		return tab;
+	}
+
+	/** Replies a probed value.
+	 * 
+	 * @param probeName is the name of the probed value
+	 * @return the value
+	 */
+	protected Object getProbeValue(String probeName) {
+		assert((probeName!=null)&&(!"".equals(probeName))); //$NON-NLS-1$
+		Object o = null;
+		synchronized(this.__values) {
+			o = this.__values.get(probeName);
+		}
+		return o;
+	}
+
+	/** Replies a probed value.
+	 * <p>
+	 * This method permits to force the type of the value.
+	 * 
+	 * @param probeName is the name of the probed value.
+	 * @param clazz is the type of the expected value.
+	 * @return the value or <code>null</code>
+	 */
+	@SuppressWarnings("unchecked")
+	public <T> T[] getProbeArray(String probeName, Class<T> clazz) {
+		assert((probeName!=null)&&(!"".equals(probeName))); //$NON-NLS-1$
+		assert(clazz!=null);
+		Object o = null;
+		synchronized(this.__values) {
+			o = this.__values.get(probeName);
+		}
+		if (o!=null) {
+			try {
+				int count = Array.getLength(o);
+				T[] t = (T[])Array.newInstance(clazz,count);
+				for(int i=0; i<count; i++) {
+					Object lo = Array.get(o,i);
+					if ((lo!=null)&&(clazz.isInstance(lo))) {
+						t[i] = clazz.cast(lo);
+					}
+				}
+				return t;
+			}
+			catch(Exception _) {
+				//
+			}
+		}
+		return null;
+	}
+
+	/** Store the value associated to a probe name.
+	 * <p>
+	 * This method is generally invoked from the agent.
+	 * 
+	 * @param probeName is the name of the probed value.
+	 * @param value is the value of the probe.
+	 */
+	public void putProbeValue(String probeName, Object value) {
+		synchronized(this.__values) {
+			assert((probeName!=null)&&(!"".equals(probeName))); //$NON-NLS-1$
+			this.__values.put(probeName,value);
+		}
+	}
+
+	/** Remove a value from this probe.
+	 * 
+	 * @param probeName is the name of the probed value.
+	 */
+	public void removeProbeValue(String probeName) {
+		synchronized(this.__values) {
+			assert((probeName!=null)&&(!"".equals(probeName))); //$NON-NLS-1$
+			this.__values.remove(probeName);
+		}
+	}
+
+	/** Remove all the values.
+	 */
+	public void clearProbeValues() {
+		synchronized(this.__values) {
+			this.__values.clear();
+		}
+	}
+
+	/** Replies if this probe contains a value.
+	 */
+	public boolean hasProbeValues() {
+		synchronized(this.__values) {
+			return !this.__values.isEmpty();
+		}
+	}
+
+	/** Replies a probed value.
+	 * <p>
+	 * This method permits to force the type of the value.
+	 * 
+	 * @param probeName is the name of the probed value.
+	 * @param clazz is the type of the expected value.
+	 * @return the value or <code>null</code>
+	 */
+	public final <T> T getProbeValue(String probeName, Class<T> clazz) {
+		assert((probeName!=null)&&(!"".equals(probeName))); //$NON-NLS-1$
+		assert(clazz!=null);
+		Object o = getProbeValue(probeName);
+		if (o==null) return null;
+		return clazz.cast(o);
+	}
+
+	/** Replies a probed value as integer (if possible).
+	 * 
+	 * @param probeName is the name of the probed value.
+	 * @return the value or <code>null</code>
+	 */
+	public final int getProbeInt(String probeName) throws ProbeValueNotDefinedException {
+		assert((probeName!=null)&&(!"".equals(probeName))); //$NON-NLS-1$
+		if (!hasProbeValue(probeName)) throw new ProbeValueNotDefinedException(probeName);
+		Object n = getProbeValue(probeName);
+		if ((n==null)||(!(n instanceof Number))) throw new ProbeValueNotDefinedException(probeName);
+		return ((Number)n).intValue();
+	}
+
+	/** Replies a probed value as integer (if possible).
+	 * 
+	 * @param probeName is the name of the probed value.
+	 * @return the value or <code>null</code>
+	 */
+	public final long getProbeLong(String probeName) throws ProbeValueNotDefinedException {
+		assert((probeName!=null)&&(!"".equals(probeName))); //$NON-NLS-1$
+		if (!hasProbeValue(probeName)) throw new ProbeValueNotDefinedException(probeName);
+		Object n = getProbeValue(probeName);
+		if ((n==null)||(!(n instanceof Number))) throw new ProbeValueNotDefinedException(probeName);
+		return ((Number)n).longValue();
+	}
+
+	/** Replies a probed value as float (if possible).
+	 * 
+	 * @param probeName is the name of the probed value.
+	 * @return the value or <code>null</code>
+	 */
+	public final float getProbeFloat(String probeName) throws ProbeValueNotDefinedException {
+		assert((probeName!=null)&&(!"".equals(probeName))); //$NON-NLS-1$
+		if (!hasProbeValue(probeName)) throw new ProbeValueNotDefinedException(probeName);
+		Object n = getProbeValue(probeName);
+		if ((n==null)||(!(n instanceof Number))) throw new ProbeValueNotDefinedException(probeName);
+		return ((Number)n).floatValue();
+	}
+
+	/** Replies a probed value as double (if possible).
+	 * 
+	 * @param probeName is the name of the probed value.
+	 * @return the value or <code>null</code>
+	 */
+	public final double getProbeDouble(String probeName) throws ProbeValueNotDefinedException {
+		assert((probeName!=null)&&(!"".equals(probeName))); //$NON-NLS-1$
+		if (!hasProbeValue(probeName)) throw new ProbeValueNotDefinedException(probeName);
+		Object n = getProbeValue(probeName);
+		if ((n==null)||(!(n instanceof Number))) throw new ProbeValueNotDefinedException(probeName);
+		return ((Number)n).doubleValue();
+	}
+
+	/** Replies a probed value as boolean (if possible).
+	 * 
+	 * @param probeName is the name of the probed value.
+	 * @return the value or <code>null</code>
+	 */
+	public final boolean getProbeBool(String probeName) throws ProbeValueNotDefinedException {
+		assert((probeName!=null)&&(!"".equals(probeName))); //$NON-NLS-1$
+		if (!hasProbeValue(probeName)) throw new ProbeValueNotDefinedException(probeName);
+		Object n = getProbeValue(probeName);
+		if ((n==null)||(!(n instanceof Boolean))) throw new ProbeValueNotDefinedException(probeName);
+		return ((Boolean)n).booleanValue();
+	}
+
+	/** Replies a probed value as character (if possible).
+	 * 
+	 * @param probeName is the name of the probed value.
+	 * @return the value or <code>null</code>
+	 */
+	public final char getProbeChar(String probeName) throws ProbeValueNotDefinedException {
+		assert((probeName!=null)&&(!"".equals(probeName))); //$NON-NLS-1$
+		if (!hasProbeValue(probeName)) throw new ProbeValueNotDefinedException(probeName);
+		Object n = getProbeValue(probeName);
+		if ((n==null)||(!(n instanceof Character))) throw new ProbeValueNotDefinedException(probeName);
+		return ((Character)n).charValue();
+	}
+
+	/** Replies a probed value as string (if possible).
+	 * 
+	 * @param probeName is the name of the probed value.
+	 * @return the value or <code>null</code>
+	 */
+	public final String getProbeString(String probeName) throws ProbeValueNotDefinedException {
+		assert((probeName!=null)&&(!"".equals(probeName))); //$NON-NLS-1$
+		if (!hasProbeValue(probeName)) throw new ProbeValueNotDefinedException(probeName);
+		Object n = getProbeValue(probeName);
+		if (n==null) return null;
+		return n.toString();
+	}
+	
+	/** Replies if the agent is alive.
+	 */
+	public boolean isProbedAgentAlive() {
+		Agent ag = this.__agent.get();
+		if (ag!=null)
+			return ag.isAlive();
+		return false;
+	}
+	
+	/** Replies the identifier of the probed agent.
+	 */
+	public AgentIdentifier getProbedAgentId() {
+		Agent ag = this.__agent.get();
+		if (ag!=null)
+			return ag.getId();
+		return null;
+	}
+
+	/** Replies if the specified probe value exists.
+	 */
+	public boolean hasProbeValue(String probeName) {
+		synchronized(this.__values) {
+			assert((probeName!=null)&&(!"".equals(probeName))); //$NON-NLS-1$
+			return this.__values.containsKey(probeName);
+		}
+	}
+	
+}
\ No newline at end of file

Added: trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/DefaultScheduler.java
===================================================================
--- trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/DefaultScheduler.java	                        (rev 0)
+++ trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/DefaultScheduler.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,46 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.core;
+
+import java.util.Collections;
+import java.util.List;
+
+/** Default scheduler for agents.
+ * <p>
+ * This scheduler shuffles the list of agents and run them in a sequential way.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ * @author Nicolas GAUD &lt;nicolas.gaud@xxxxxxx&gt;
+ */
+public class DefaultScheduler<AT extends Agent> extends AbstractScheduler<AT> {
+
+	/** Make the specified agents alive.
+	 */
+	public void schedule(List<AT> agents) {
+		assert(agents!=null);
+		Collections.shuffle(agents);
+		for (AT at : agents) {
+			at.live();
+		}
+	}
+
+}
\ No newline at end of file

Added: trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/Environment.java
===================================================================
--- trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/Environment.java	                        (rev 0)
+++ trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/Environment.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,84 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.core;
+
+/** This interface representes the environment inside a multiagent system.
+ * <p>
+ * The environment is also assumed to be a time reference for the agent society.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ * @author Nicolas GAUD &lt;nicolas.gaud@xxxxxxx&gt;
+ */
+public interface Environment<AT extends Agent> {
+
+	/** Initialize this environment.
+	 */
+	public void init();
+
+	/** Shutdown this environment.
+	 */
+	public void shutdown();
+
+	/** Put the given agent inside the environment.
+	 * <p>
+	 * The implementation of this method is problem-dependent
+	 * because several type of environments should not contains
+	 * the agents. 
+	 */
+	public void putAgent(AT agent);
+
+	/** Remove the given agent from the environment.
+	 * <p>
+	 * The implementation of this method is problem-dependent
+	 * because several type of environments should not contains
+	 * the agents. 
+	 */
+	public void removeAgent(AgentIdentifier agent);
+	
+	/** This function is invoked by the kernel before
+	 * the scheduling of the agents.
+	 * 
+	 * @param runningKernel is the instance of the kernel that is running this environment.
+	 */
+	public void preAgentScheduling(final Kernel<AT,?,?,?> runningKernel);
+
+	/** This function is invoked by the kernel after
+	 * the scheduling of the agents.
+	 * 
+	 * @param runningKernel is the instance of the kernel that is running this environment.
+	 */
+	public void postAgentScheduling(final Kernel<AT,?,?,?> runningKernel);
+
+	/** Replies if this environment is alive.
+	 * <p>
+	 * If the environment is not alive, the multiagent kernel
+	 * will quit.
+	 */
+	public boolean isAlive();
+	
+	/** Replies the clock used by the environment.
+	 * 
+	 * @return never <code>null</code>
+	 */
+	public SimulationClock getSimulationClock();
+
+}
\ No newline at end of file

Added: trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/FilteringTimeManager.java
===================================================================
--- trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/FilteringTimeManager.java	                        (rev 0)
+++ trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/FilteringTimeManager.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,111 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.core;
+
+import java.util.concurrent.TimeUnit;
+
+/** Time Manager for that was a filter to another time manager.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ * @author Nicolas GAUD &lt;nicolas.gaud@xxxxxxx&gt;
+ */
+public abstract class FilteringTimeManager extends TimeManager {
+
+	private final TimeManager __manager;
+	
+	public FilteringTimeManager(TimeManager manager) {
+		assert(manager!=null);
+		this.__manager = manager;
+	}
+	
+	/** Replies the current date of simulation.
+	 * 
+	 * @param desired_unit indicates the unit to use
+	 * @return the simulation's time espressed in the specified unit.
+	 */
+	@Override
+	public final double getSimulationTime(TimeUnit desired_unit) {
+		assert(desired_unit!=null);
+		return this.__manager.getSimulationTime(desired_unit);
+	}
+
+	/** Replies the duration of a simulation loop for this environment.
+	 * <p>
+	 * <code>simulation_time(t+1) = simulation_time(t) + step_duration</code>
+	 * 
+	 * @param desired_unit indicates the unit to use
+	 * @return the simulation's step time.
+	 */
+	@Override
+	public final double getSimulationStepDuration(TimeUnit desired_unit) {
+		assert(desired_unit!=null);
+		return this.__manager.getSimulationStepDuration(desired_unit);
+	}
+
+	/** Called by the environment before the scheduling of the agents.
+	 * 
+	 * @param kernel_time is the current kernel date.
+	 * @param last_kernel_step_duration is the duration of the last
+	 * kernel step in milliseconds.
+	 */
+	@Override
+	protected void preAgentScheduling(long kernel_time, long last_kernel_step_duration) {
+		this.__manager.preAgentScheduling(kernel_time,last_kernel_step_duration);
+	}
+
+	/** Called by the environment before the scheduling of the agents.
+	 * 
+	 * @param kernel_time is the current kernel date.
+	 * @param last_kernel_step_duration is the duration of the last
+	 * kernel step in milliseconds.
+	 */
+	@Override
+	protected void postAgentScheduling(long kernel_time, long last_kernel_step_duration) {
+		this.__manager.preAgentScheduling(kernel_time,last_kernel_step_duration);
+	}
+
+	/** Set the current simulation time. It is the count of
+	 * seconds since the starting of the simulation.
+	 * <p>
+	 * <code>simulation_time(t+1) = simulation_time(t) + step_duration</code>
+	 * 
+	 * @param time is the new simulation time expresed in seconds.
+	 */
+	@Override
+	protected final void setSimulationTime(double time) {
+		this.__manager.setSimulationTime(time);
+	}
+	
+	/** Set the current simulation step duration. It is the duration
+	 * of one simulation step expressed in the simulation time
+	 * coordinate system.
+	 * <p>
+	 * <code>simulation_time(t+1) = simulation_time(t) + step_duration</code>
+	 * 
+	 * @param step_duration is the new simulation time expresed in milliseconds.
+	 */
+	@Override
+	protected final void setSimulationStepDuration(double step_duration) {
+		this.__manager.setSimulationTime(step_duration);
+	}
+
+}
\ No newline at end of file

Added: trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/Identifier.java
===================================================================
--- trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/Identifier.java	                        (rev 0)
+++ trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/Identifier.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,37 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.core;
+
+import java.io.Serializable;
+
+/** This interface represents a unique identifier.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ * @author Nicolas GAUD &lt;nicolas.gaud@xxxxxxx&gt;
+ */
+public interface Identifier extends Serializable, Comparable<Identifier> {
+
+	public String toString();
+
+	public boolean equals(Object o);
+
+}
\ No newline at end of file

Added: trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/Kernel.java
===================================================================
--- trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/Kernel.java	                        (rev 0)
+++ trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/Kernel.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,934 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.core;
+
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import org.arakhne.util.ref.WeakArrayList;
+
+/** Kernel of the TinyMAS application.
+ * <p>
+ * The kernel is the central point of the multiagent platform.
+ * 
+ * @param <AT> is the type of agent supported by this kernel
+ * @param <ET> is the type of environment supported by this kernel
+ * @param <YP> is the type of yellow page supported by this kernel
+ * @param <MTS> is the type of message transport service supported by this kernel.
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ * @author Nicolas GAUD &lt;nicolas.gaud@xxxxxxx&gt;
+ */
+public class Kernel<AT extends Agent, ET extends Environment<AT>, YP extends YellowPages, MTS extends MessageTransportService> implements Runnable {
+
+	/** This is the minimal duration which can be measured
+	 * by an operating system (in milliseconds).
+	 */ 
+	public static final int TIME_PRECISION = 10;
+	
+	/** Timeout in milliseconds to wait about kernel stop.
+	 */
+	public static final int KERNEL_STOP_TIMEOUT = 20000;
+	
+	private static volatile Kernel<?,?,?,?> SINGLETON;
+	
+	/** Manager of the message transport.
+	 */
+	private final MTS __mts;
+	
+	/** Manager of the agent identification and
+	 * of the "white pages" of the application.
+	 */	
+	private final WhitePages<AT> __whitepages;
+
+	/** Service manager.
+	 */	
+	private final YP __yellowpages;
+
+	/** Identifier of this kernel.
+	 */
+	private final KernelIdentifier __kernel_id;
+	
+	/** Agent scheduler used by this kernel. 
+	 */
+	private final Scheduler<AT> __scheduler;
+
+	/** Environment.
+	 */
+	private ET __environment;
+
+	/** flag that indicates if the kernel should stop or not.
+	 */
+	private volatile boolean __stopsimu = true;
+
+	/** Indicates if the kernel is paused after its started.
+	 */
+	private volatile boolean __isUnderPause = false;
+
+	/** Indicates if the kernel is currently in
+	 * its shutdown process.
+	 */
+	private volatile boolean __in_shutdowning = false;
+	
+	/** Indicates if the kernel was shutdowned.
+	 */
+	private volatile boolean __is_shutdown = false;
+
+	/** Simulation time.
+	 */
+	private long __simulation_time = 0;
+	
+	/** Last simulation step duration.
+	 */
+	private long __simulation_step_duration = 0;
+	
+	/** Listeners.
+	 */
+	private final List<KernelListener> __kernelListeners = new ArrayList<KernelListener>();
+	
+	/** List of agents to kill.
+	 * <p>
+	 * An agent should appear in this list only if it invoked {@link Agent#killMe()}.
+	 */
+	private final List<AgentIdentifier> __agentsToKill = new WeakArrayList<AgentIdentifier>();
+	
+	/** Indicates the waiting time in milliseconds between two simulation
+	 * steps.
+	 */
+	private int __waitingTime = 0;
+
+	/** Indicates the waiting time in milliseconds between two simulation
+	 * steps.
+	 */
+	private long __waitingTimeCountDown = 0;
+
+	/** Create a kernel with the default components.
+	 */
+	@SuppressWarnings("unchecked")
+	public Kernel() {
+		this(
+				(MTS)new MessageTransportService(),
+				new WhitePages<AT>(),
+				(YP)new YellowPages(),
+				new DefaultScheduler<AT>(),
+				null);
+	}
+	
+	/** Create a kernel with the specified scheduler.
+	 * 
+	 * @param scheduler
+	 */
+	@SuppressWarnings("unchecked")
+	public Kernel(Scheduler<AT> scheduler) {
+		this(
+				(MTS)new MessageTransportService(),
+				new WhitePages<AT>(),
+				(YP)new YellowPages(),
+				scheduler,
+				null);
+	}
+
+	/** Create a kernel with the specified scheduler and message transport service.
+	 * 
+	 * @param mts
+	 * @param scheduler
+	 */
+	@SuppressWarnings("unchecked")
+	public Kernel(MTS mts, Scheduler<AT> scheduler) {
+		this(
+				mts,
+				new WhitePages<AT>(),
+				(YP)new YellowPages(),
+				new DefaultScheduler<AT>(),
+				null);
+	}
+
+	/** Create a kernel with the specified components.
+	 * 
+	 * @param mts
+	 * @param whitepages
+	 * @param yellowpages
+	 */
+	public Kernel(MTS mts, WhitePages<AT> whitepages, YP yellowpages) {
+		this(
+				mts,
+				whitepages,
+				yellowpages,
+				new DefaultScheduler<AT>(),
+				null);
+	}
+
+	/** Create a kernel with the specified components.
+	 * 
+	 * @param mts
+	 * @param yellowpages
+	 */
+	public Kernel(MTS mts, YP yellowpages) {
+		this(
+				mts,
+				new WhitePages<AT>(),
+				yellowpages,
+				new DefaultScheduler<AT>(),
+				null);
+	}
+
+	/** Create a kernel with the specified components.
+	 * 
+	 * @param mts
+	 * @param whitepages
+	 * @param yellowpages
+	 * @param scheduler
+	 */
+	public Kernel(MTS mts, WhitePages<AT> whitepages, YP yellowpages, Scheduler<AT> scheduler) {
+		this(mts, whitepages, yellowpages, scheduler, null);
+	}
+
+	/** Create a kernel with the specified components.
+	 * 
+	 * @param mts
+	 * @param yellowpages
+	 * @param scheduler
+	 */
+	public Kernel(MTS mts, YP yellowpages, Scheduler<AT> scheduler) {
+		this(mts, new WhitePages<AT>(), yellowpages, scheduler, null);
+	}
+
+	/** Create a kernel with the specified components.
+	 * 
+	 * @param env
+	 */
+	@SuppressWarnings("unchecked")
+	public Kernel(ET env) {
+		this(
+				(MTS)new MessageTransportService(),
+				new WhitePages<AT>(),
+				(YP)new YellowPages(),
+				new DefaultScheduler<AT>(),
+				env);
+	}
+
+	/** Create a kernel with the specified components.
+	 * 
+	 * @param mts
+	 * @param whitepages
+	 * @param yellowpages
+	 * @param scheduler
+	 * @param env
+	 */
+	public Kernel(MTS mts, WhitePages<AT> whitepages, YP yellowpages, Scheduler<AT> scheduler, ET env) {
+		assert(whitepages!=null);
+		assert(yellowpages!=null);
+		assert(mts!=null);
+		this.__kernel_id = mts.getKernelId();
+		this.__mts = mts;
+		this.__whitepages = whitepages;
+		this.__yellowpages = yellowpages;
+		this.__scheduler = scheduler;
+		this.__environment = env;
+		registerAsSingleton();
+	}
+
+	/** Replies the unique instance of Kernel.
+	 *
+	 * @return the singleton
+	 * @see #registerAsSingleton()
+	 */
+	public static Kernel<?,?,?,?> getSingleton() {
+		return SINGLETON;
+	}
+
+	/** Register this kernel as the singleton.
+	 * 
+	 * @return <code>true</code> if this kernel is now the singleton, otherwise <code>false</code>
+	 * @see #getSingleton()
+	 */
+	public boolean registerAsSingleton() {
+		if ((SINGLETON==null)||(SINGLETON.__is_shutdown)) {
+			SINGLETON = this;
+			return true;
+		}
+		return false;
+	}
+	
+	/** Replies the message transport service used by this kernel.
+	 * 
+	 * @return the MTS
+	 */
+	MTS getMTS() {
+		return this.__mts;
+	}	
+
+	/** Replies the environment used by this kernel (if it exist).
+	 * 
+	 * @return the environment
+	 */
+	public ET getEnvironment() {
+		return this.__environment;
+	}	
+
+	/** Set the environment that should be used by this kernel.
+	 * 
+	 * @param env
+	 */
+	public void setEnvironment(ET env) {
+		this.__environment = env;
+	}	
+
+	/** Add an agent inside this kernel.
+	 * <p>
+	 * The kernel assumes that the specified agent
+	 * was never spawn before. An unique identifier
+	 * will be provided to the specified agent.
+	 * 
+	 * @param agent
+	 */	
+	@SuppressWarnings("unchecked")
+	public void addAgent(Agent agent) {
+		assert(agent!=null);
+		AT a = (AT)agent;
+		if (!this.__in_shutdowning) {
+			this.__whitepages.register(a) ;
+			AgentIdentifier id  = this.__whitepages.getId(a) ;
+			this.__mts.registerAgent(id) ;
+			if (this.__environment!=null) {
+				this.__environment.putAgent(a);
+			}
+			if (!this.__stopsimu) {
+				a.start(id);
+				fireAgentAdded(id);
+			}			
+		}
+	}
+
+	/** Add an agent inside this kernel.
+	 * <p>
+	 * The kernel assumes that the specified agent
+	 * was already spawn before. The specified
+	 * identifier will be given to the agent (if
+	 * it is unique).
+	 *
+	 * @param id
+	 * @param a
+	 */	
+	public void addAgent(AgentIdentifier id, AT a) {
+		assert(id!=null);
+		assert(a!=null);
+		if (!this.__in_shutdowning) {
+			this.__whitepages.register(id, a) ;
+			this.__mts.registerAgent(id) ;
+			if (this.__environment!=null) {
+				this.__environment.putAgent(a);
+			}
+			if (!this.__stopsimu) {
+				a.start(id);
+				fireAgentAdded(id);
+			}			
+		}
+	}
+
+	/** Kill an agent.
+	 * <p>
+	 * This method should only be invoked by {@link Agent#killMe()}.
+	 * <p>
+	 * The agent will be removed at the end of the current scheduling step.
+	 * 
+	 * @param id
+	 * @see #removeAgent(AgentIdentifier)
+	 */
+	void killAgent(AgentIdentifier id) {
+		assert(id!=null);
+		this.__agentsToKill.add(id);
+	}
+	
+	/** Kill an agent.
+	 * <p>
+	 * The agent will be removed immediately.
+	 * 
+	 * @param id
+	 * @see #killAgent(AgentIdentifier)
+	 */
+	void removeAgent(AgentIdentifier id) {
+		assert(id!=null);
+		removeAgent(id,true);
+	}
+
+	/** Kill an agent.
+	 * <p>
+	 * The agent will be removed immediately.
+	 * 
+	 * @param id
+	 * @param notify must be <code>true</code> to notify the listeners.
+	 * @see #killAgent(AgentIdentifier)
+	 */
+	private void removeAgent(AgentIdentifier id, boolean notify) {
+		assert(id!=null);
+		if (this.__environment!=null) {
+			this.__environment.removeAgent(id);
+		}
+		Agent ag = this.__whitepages.unregister(id) ;
+		this.__mts.unregisterAgent(id) ;
+		if (this.__yellowpages!=null)
+			this.__yellowpages.unregisterServices(id) ;
+		if (ag != null) {
+			if (!this.__in_shutdowning) ag.stop() ;
+		}
+		if ((!this.__stopsimu)&&(notify)) {
+			fireAgentRemoved(id);
+		}
+	}
+	
+	/** Kill immediately all the agents.
+	 */
+	void removeAllAgents() {
+		AgentIdentifier[] ags = this.__whitepages.getAllAgentIdentifiers() ;
+		for (AgentIdentifier identifier : ags) {
+			removeAgent(identifier,false);
+		}
+		if (!this.__stopsimu) {
+			fireAgentRemoved(ags);
+		}
+	}
+
+	/** Replies the identifier of the specified agent.
+	 *
+	 * @param a
+	 * @return the identifier.
+	 */
+	AgentIdentifier getAgentId(AT a) {
+		assert(a!=null);
+		return this.__whitepages.getId(a) ;
+	}
+	
+	/** Run the kernel.
+	 * <p>
+	 * This method invokes:
+	 * <ul>
+	 * <li>{@link #runInitializationStage()}</li>
+	 * <li>{@link #runAgentLifeStage()}</li>
+	 * <li>{@link #runShutdownStage()}</li>
+	 * </ul>
+	 *
+	 * @see #runInitializationStage()
+	 * @see #runAgentLifeStage()
+	 * @see #runShutdownStage()
+	 */
+	public void run() {
+		runInitializationStage();
+		runAgentLifeStage();
+		runShutdownStage();
+	}
+	
+	/** Replies the agents which are alive.
+	 */
+	private List<AT> getAliveAgents() {
+		Collection<AT> c = this.__whitepages.getAllAgents();
+		List<AT> l = new ArrayList<AT>();
+		for (AT at : c) {
+			if ((at!=null)&&(at.isAlive())) {
+				l.add(at);
+			}
+		}
+		return l;
+	}
+
+	/** Replies the agents which are registered.
+	 */
+	private List<AT> getRegisteredAgents() {
+		Collection<AT> c = this.__whitepages.getAllAgents();
+		List<AT> l = new ArrayList<AT>();
+		l.addAll(c);
+		return l;
+	}
+
+	/** Run the initialization stage of the kernel.
+	 *
+	 * @see #run()
+	 * @see #runAgentLifeStage()
+	 * @see #runShutdownStage()
+	 */
+	protected void runInitializationStage() {
+		this.__in_shutdowning = false;
+		this.__is_shutdown = false;
+		this.__stopsimu = true;
+		this.__isUnderPause = false;
+		
+		this.__simulation_time = 0;
+		this.__simulation_step_duration = System.currentTimeMillis();
+		displayKernelMessage("Initializing micro-kernel..."); //$NON-NLS-1$
+		registerAsSingleton();
+		displayKernelMessage("\tstarting MTS..."); //$NON-NLS-1$
+		this.__mts.startMTS();
+		if (this.__environment!=null) {
+			displayKernelMessage("\tinitializing environment..."); //$NON-NLS-1$
+			this.__environment.init() ;
+		}
+		displayKernelMessage("\tstarting agents..."); //$NON-NLS-1$
+		startAgents(getRegisteredAgents()) ;
+		this.__simulation_step_duration = System.currentTimeMillis() - this.__simulation_step_duration;
+	}
+
+	/** Run the agent live stages.
+	 * 
+	 * @see #run()
+	 * @see #runInitializationStage()
+	 * @see #runShutdownStage()
+	 */
+	protected void runAgentLifeStage() {
+		displayKernelMessage("Running micro-kernel..."); //$NON-NLS-1$
+		this.__stopsimu = false ;
+		this.__simulation_time = 0;
+		fireKernelStarted();
+		boolean previousPauseState = this.__isUnderPause;
+		while (!isStopped()) {
+			if (previousPauseState!=this.__isUnderPause) {
+				if (this.__isUnderPause) {
+					fireKernelPaused();
+				}
+				else {
+					fireKernelRestarted();
+				}
+				previousPauseState = this.__isUnderPause;
+			}
+			if (!this.__isUnderPause) {
+
+				long starting_date = System.currentTimeMillis();
+
+				if ((this.__waitingTime<=0)||
+					(this.__waitingTimeCountDown<=starting_date)) {
+				
+					// Run the system
+					if (this.__scheduler!=null) {
+						List<AT> agents = getAliveAgents();
+						if (this.__environment!=null)
+							this.__scheduler.schedule(this,this.__environment, agents);
+						else
+							this.__scheduler.schedule(agents);
+					}
+					
+					//
+					// Stop the system if the environment is dead
+					//
+					if ((this.__environment!=null)&&(!this.__environment.isAlive())) {
+						stopKernel();
+					}
+
+					//
+					// Kill the agents which request it
+					//
+					if (!this.__agentsToKill.isEmpty()) {
+						for (AgentIdentifier id : this.__agentsToKill) {
+							removeAgent(id);
+						}
+						displayKernelMessage("Killed "+this.__agentsToKill.size()+" agent(s)"); //$NON-NLS-1$ //$NON-NLS-2$
+						this.__agentsToKill.clear();
+					}
+					
+					//
+					// Compute time indicators
+					//
+					long ending_date = System.currentTimeMillis();
+					this.__simulation_step_duration = ending_date - starting_date;
+					this.__simulation_time++;
+					
+					if (this.__waitingTime>0)
+						this.__waitingTimeCountDown = ending_date + this.__waitingTime;
+					
+					// Allow external refresh
+					fireKernelExternalRefreshAllowed();					
+
+				}
+				
+			}
+		}
+	}
+
+	/** run the shutdown stage of the kernel.
+	 * 
+	 * @see #run()
+	 * @see #runInitializationStage()
+	 * @see #runAgentLifeStage()
+	 */
+	protected void runShutdownStage() {
+		displayKernelMessage("Shutdowning micro-kernel..."); //$NON-NLS-1$
+		displayKernelMessage("\tstoping agents..."); //$NON-NLS-1$
+		this.__in_shutdowning = true;
+		stopAgents(getRegisteredAgents()) ;
+		removeAllAgents();
+		if (this.__environment!=null) {
+			displayKernelMessage("\tshutdown environment..."); //$NON-NLS-1$
+			this.__environment.shutdown() ;
+		}
+		displayKernelMessage("\tstoping MTS..."); //$NON-NLS-1$
+		this.__mts.stopMTS();
+		this.__stopsimu = true;
+		this.__simulation_time = 0;
+		this.__simulation_step_duration = 0;
+		displayKernelMessage("\tshutdown complete."); //$NON-NLS-1$
+		this.__in_shutdowning = false;
+		this.__is_shutdown = true;
+		fireKernelStopped();
+	}
+
+	/** Agent lif-cycle: starts all the specified agents.
+	 * 
+	 * @param agents
+	 */	
+	protected void startAgents(Collection<AT> agents) {
+		assert(agents!=null);
+		for(AT agent : agents) {
+			AgentIdentifier id = this.__whitepages.getId(agent) ;
+			if (id!=null) {
+				agent.start(id) ;
+			}
+		}
+	}
+	
+	/** Set the milliseconds to wait between two simulation steps.
+	 * 
+	 * @param duration
+	 */
+	public void setWaitingDuration(int duration) {
+		if (duration>=0) this.__waitingTime = duration;
+	}
+
+	/** Notify of the specified agents that they are dead.
+	 * 
+	 * @param agents
+	 */
+	protected void stopAgents(Collection<AT> agents) {
+		assert(agents!=null);
+		for(Agent agent : agents) {
+			agent.stop() ;
+		}
+	}
+
+	/** Replies if the kernel is not running.
+	 * If the kernel is under pause, this function
+	 * replies <code>true</code>
+	 * 
+	 * @return <code>true</code> if the kernel was stopped, otherwise <code>false</code>
+	 */
+	public boolean isStopped() {
+		return ((this.__stopsimu)||
+				(this.__whitepages.size()==0)||
+				(this.__is_shutdown)||
+				(this.__in_shutdowning)) ;
+	}
+
+	/** Replies if this kernel is under pause.
+	 * 
+	 * @return <code>true</code> if the kernel was paused, otherwise <code>false</code>
+	 */
+	public boolean isUnderPause() {
+		return (this.__isUnderPause);
+	}
+
+	/** Replies if this kernel was launch, but is now shutdown.
+	 * 
+	 * @return <code>true</code> if the kernel was shutdown, otherwise <code>false</code>
+	 */
+	public boolean isShutdown() {
+		return (this.__is_shutdown || this.__in_shutdowning);
+	}
+
+	/** Stop the kernel.
+	 */	
+	public void stop() {
+		displayKernelMessage("Requesting kernel shutdown") ; //$NON-NLS-1$
+		this.__stopsimu = true;
+	}
+
+	/** Stop the kernel singleton.
+	 */	
+	public static void stopKernel() {
+		if (SINGLETON!=null) {
+			SINGLETON.stop() ;
+		}		
+	}
+	
+	/** Push the current kernel under pause.
+	 */	
+	public void pause() {
+		if (!this.__stopsimu) {
+			if (!this.__isUnderPause) { 
+				displayKernelMessage("Requesting kernel pause") ; //$NON-NLS-1$
+			}
+			this.__isUnderPause = ! this.__isUnderPause;
+		}
+	}
+
+	/** Push the singleton kernel under pause.
+	 */	
+	public static void pauseKernel() {
+		if (SINGLETON!=null) {
+			SINGLETON.pause() ;
+		}		
+	}
+	
+	/** Replies a probe on the specified agent.
+	 *
+	 * @param agentId
+	 * @return a probe or <code>null</code> if the agent
+	 * could not provide a probe.
+	 */
+	public static Probe probe(AgentIdentifier agentId) {
+		assert(agentId!=null);
+		if (SINGLETON!=null) {
+			SINGLETON.getProbe(agentId);
+		}
+		return null;
+	}
+
+	/** Replies the list of agents that provide the specified service
+	 *
+	 * @param serviceName
+	 * @return the list of providers.
+	 */
+	public static AgentIdentifier[] service(String serviceName) {
+		assert((serviceName!=null)&&(!"".equals(serviceName))); //$NON-NLS-1$
+		if (SINGLETON!=null) {
+			return SINGLETON.getServiceProviders(serviceName);
+		}
+		return new AgentIdentifier[0];
+	}
+
+	/** Replies the identifier of this kernel.
+	 * 
+	 * @return the kernel identifier
+	 */
+	public KernelIdentifier getKernelId() {
+		return this.__kernel_id;
+	}
+	
+	/** Replies the yellow pages used by this kernel.
+	 *
+	 * @return the yellow pages
+	 */
+	public YP getYellowPageSystem() {
+		return this.__yellowpages;
+	}
+	
+	/** Replies the list of agents that provide the specified service
+	 *
+	 * @param serviceName
+	 * @return the providers
+	 */
+	public AgentIdentifier[] getServiceProviders(String serviceName) {
+		assert((serviceName!=null)&&(!"".equals(serviceName))); //$NON-NLS-1$
+		return this.__yellowpages.getAgents(serviceName);
+	}
+
+	/** Replies the count of agents registered inside this kernel.
+	 * 
+	 * @return the count of agents.
+	 */
+	public long getAgentCount() {
+		return this.__whitepages.size();
+	}
+
+	/** Replies if this agent identifier corresponds to an
+	 * agent inside this kernel.
+	 * 
+	 * @param agent
+	 * @return <code>true</code> if the given agent is on this kernel,
+	 * otherwise <code>false</code>
+	 */
+	public boolean isOnThisKernel(AgentIdentifier agent) {
+		assert(agent!=null);
+		return getKernelId().equals(agent.getKernelId());
+	}
+	
+	/** Kernel log.
+	 * 
+	 * @param msg
+	 */
+	protected static void displayKernelMessage(String msg) {
+		System.err.println("*** KERNEL *** > "+msg); //$NON-NLS-1$
+	}
+
+	/** Replies the count of simulation turns
+	 * since the start of the kernel.
+	 * 
+	 * @return the count of turns
+	 */
+	public long getKernelStep() {
+		return this.__simulation_time;
+	}
+	
+	/** Replies the duration in milliseconds of one turn of the kernel.
+	 * 
+	 * @return the duration of a turn.
+	 */
+	public long getKernelStepDuration() {
+		return (this.__simulation_step_duration<TIME_PRECISION) ?
+			TIME_PRECISION : this.__simulation_step_duration;
+	}
+	
+	/** Replies the simulation clock associated to this kernel.
+	 * <p>
+	 * This function replies the clock of the environment if it
+	 * exists or an internal clock based on the kernel steps.
+	 * 
+	 * @return never <code>null</code>
+	 * @see #getKernelStep()
+	 * @see #getKernelStepDuration()
+	 */
+	public SimulationClock getSimulationClock() {
+		SimulationClock sc = null;
+		ET env = getEnvironment();
+		if (env!=null) {
+			sc = env.getSimulationClock();
+		}
+		if (sc==null) {
+			// Replies the internal representation
+			return new SimulationClock() {
+				public double getSimulationStepDuration(TimeUnit desired_unit) {
+					return desired_unit.convert(getKernelStepDuration(),TimeUnit.MILLISECONDS);
+				}
+				public double getSimulationStepDuration() {
+					return getKernelStepDuration();
+				}
+				public double getSimulationTime(TimeUnit desired_unit) {
+					return getKernelStep();
+				}
+				public double getSimulationTime() {
+					return getKernelStep();
+				}
+				public double perTimeUnit(double value) {
+					return perTimeUnit(value,TimeUnit.SECONDS);
+				}
+				public double perTimeUnit(double value, TimeUnit desiredUnit) {
+					return value * getSimulationStepDuration(desiredUnit);
+				}
+			};
+		}
+		return sc;
+	}
+	
+	/** Add a listener.
+	 * 
+	 * @param listener
+	 */
+	public void addKernelListener(KernelListener listener) {
+		assert(listener!=null);
+		this.__kernelListeners.add(listener);
+	}
+
+	/** remove a listener.
+	 * 
+	 * @param listener
+	 */
+	public void removeKernelListener(KernelListener listener) {
+		assert(listener!=null);
+		this.__kernelListeners.remove(listener);
+	}
+
+	/** Informs listener about the starting of the kernel.
+	 */
+	private void fireKernelStarted() {
+		for (KernelListener listener : this.__kernelListeners) {
+			if (listener!=null) {
+				listener.kernelStarted(this);
+			}
+		}
+	}
+
+	/** Informs listener about the ending of the kernel.
+	 */
+	private void fireKernelStopped() {
+		for (KernelListener listener : this.__kernelListeners) {
+			if (listener!=null) {
+				listener.kernelStopped(this);
+			}
+		}
+	}
+
+	/** Informs listener about external refresh.
+	 */
+	private void fireKernelExternalRefreshAllowed() {
+		for (KernelListener listener : this.__kernelListeners) {
+			if (listener!=null) {
+				listener.kernelRefreshAllowed(this);
+			}
+		}
+	}
+
+	/** Informs listener about the pause of the kernel.
+	 */
+	private void fireKernelPaused() {
+		for (KernelListener listener : this.__kernelListeners) {
+			if (listener!=null) {
+				listener.kernelPaused(this);
+			}
+		}
+	}
+	
+	/** Informs listener about the return from a pause of the kernel.
+	 */
+	private void fireKernelRestarted() {
+		for (KernelListener listener : this.__kernelListeners) {
+			if (listener!=null) {
+				listener.kernelRestarted(this);
+			}
+		}
+	}
+
+	/** Informs listener about the addition of an agent.
+	 */
+	private void fireAgentAdded(AgentIdentifier... ids) {
+		assert(ids!=null);
+		for (KernelListener listener : this.__kernelListeners) {
+			if (listener!=null) {
+				listener.kernelAgentAdded(this,ids);
+			}
+		}
+	}
+
+	/** Informs listener about the deletion of an agent.
+	 */
+	private void fireAgentRemoved(AgentIdentifier... ids) {
+		assert(ids!=null);
+		for (KernelListener listener : this.__kernelListeners) {
+			if (listener!=null) {
+				listener.kernelAgentRemoved(this,ids);
+			}
+		}
+	}
+
+	/** Replies a probe on the specified agent.
+	 * 
+	 * @param agentId
+	 * @return a probe or <code>null</code> if the agent
+	 * could not provide a probe.
+	 */
+	public Probe getProbe(AgentIdentifier agentId) {
+		assert(agentId!=null);
+		Agent ag = this.__whitepages.getAgent(agentId);
+		if (ag!=null) {
+			return ag.getProbe();
+		}
+		return null;
+	}
+
+}
\ No newline at end of file

Added: trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/KernelAdapter.java
===================================================================
--- trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/KernelAdapter.java	                        (rev 0)
+++ trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/KernelAdapter.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,73 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.core;
+
+/** Listener kernel events.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ * @author Nicolas GAUD &lt;nicolas.gaud@xxxxxxx&gt;
+ */
+public class KernelAdapter implements KernelListener {
+
+	/** Invoked when the specified kernal has been started.
+	 */
+	public void kernelStarted(Kernel<?,?,?,?> kernel) {
+		//
+	}
+
+	/** Invoked when the specified kernal has been stoped.
+	 */
+	public void kernelStopped(Kernel<?,?,?,?> kernel) {
+		//
+	}
+
+	/** Invoked when the specified kernal has been paused.
+	 */
+	public void kernelPaused(Kernel<?,?,?,?> kernel) {
+		//
+	}
+
+	/** Invoked when the specified kernal has been restarted after paused.
+	 */
+	public void kernelRestarted(Kernel<?,?,?,?> kernel) {
+		//
+	}
+
+	/** Invoked when an agent was removed from the kernel.
+	 */
+	public void kernelAgentRemoved(Kernel<?,?,?,?> kernel, AgentIdentifier... id) {
+		//
+	}
+
+	/** Invoked when an agent was added inside the kernel.
+	 */
+	public void kernelAgentAdded(Kernel<?,?,?,?> kernel, AgentIdentifier... id) {
+		//
+	}
+
+	/** Invoked when the kernel allows external refresh.
+	 */
+	public void kernelRefreshAllowed(Kernel<?,?,?,?> kernel) {
+		//
+	}
+
+}
\ No newline at end of file

Added: trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/KernelIdentifier.java
===================================================================
--- trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/KernelIdentifier.java	                        (rev 0)
+++ trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/KernelIdentifier.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,106 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.core;
+
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.NetworkInterface;
+import java.util.Enumeration;
+
+
+/** Unique identifier of a kernel.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ * @author Nicolas GAUD &lt;nicolas.gaud@xxxxxxx&gt;
+ */
+public class KernelIdentifier implements Identifier {
+
+	private static final long serialVersionUID = -8945321864190782646L;
+	
+	private final InetSocketAddress __kernel_address;
+	
+	public KernelIdentifier() {
+		this((int)(Math.random()*1000)+1000);
+	}
+
+	public KernelIdentifier(int port) {
+        InetAddress lastAdr = null;
+        InetAddress loopBackAddresses = null;
+        try {
+                Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
+                NetworkInterface netInterface;
+                while (interfaces.hasMoreElements() && lastAdr==null) {
+                        netInterface = interfaces.nextElement();
+                        if (!netInterface.isLoopback()) {
+                                lastAdr = extractAddress(netInterface.getInetAddresses());
+                        }
+                        else if (loopBackAddresses==null) {
+                                loopBackAddresses = extractAddress(netInterface.getInetAddresses());
+                        }
+                }
+        }
+        catch (Exception e) {
+                e.printStackTrace();
+        }
+        
+        if (lastAdr==null) {
+                lastAdr = loopBackAddresses;
+        }
+        
+        this.__kernel_address = new InetSocketAddress(lastAdr,port);
+	}
+	
+    private InetAddress extractAddress(Enumeration<InetAddress> addresses) {
+        InetAddress adr;
+        while (addresses.hasMoreElements()) {
+                adr = addresses.nextElement();
+                if (adr instanceof Inet4Address) return adr;
+        }
+        return null;
+    }
+    
+    @Override
+	public String toString() {
+		return Long.toHexString(serialVersionUID)+":"+this.__kernel_address.toString(); //$NON-NLS-1$
+	}
+	
+	@Override
+	public boolean equals(Object o) {
+		if (o instanceof Identifier) {
+			return compareTo((Identifier)o)==0;
+		}
+		return false;
+	}
+
+	public int compareTo(Identifier id) {
+		if (id==null) return -1;
+		return toString().compareTo(id.toString());
+	}
+
+	/** Retourne l'adresse reseau du Kernel correspondant à cet identificateur.
+	 */
+	public InetSocketAddress getKernelAddress() {
+		return this.__kernel_address;
+	}
+
+}
\ No newline at end of file

Added: trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/KernelListener.java
===================================================================
--- trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/KernelListener.java	                        (rev 0)
+++ trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/KernelListener.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,59 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.core;
+
+/** Listener kernel events.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ * @author Nicolas GAUD &lt;nicolas.gaud@xxxxxxx&gt;
+ */
+public interface KernelListener {
+
+	/** Invoked when the specified kernal has been started.
+	 */
+	public void kernelStarted(Kernel<?,?,?,?> kernel);
+
+	/** Invoked when the specified kernal has been stoped.
+	 */
+	public void kernelStopped(Kernel<?,?,?,?> kernel);
+
+	/** Invoked when the specified kernal has been paused.
+	 */
+	public void kernelPaused(Kernel<?,?,?,?> kernel);
+
+	/** Invoked when the specified kernal has been restarted after paused.
+	 */
+	public void kernelRestarted(Kernel<?,?,?,?> kernel);
+
+	/** Invoked when an agent was removed from the kernel.
+	 */
+	public void kernelAgentRemoved(Kernel<?,?,?,?> kernel, AgentIdentifier... id);
+
+	/** Invoked when an agent was added inside the kernel.
+	 */
+	public void kernelAgentAdded(Kernel<?,?,?,?> kernel, AgentIdentifier... id);
+
+	/** Invoked when the kernel allows external refresh.
+	 */
+	public void kernelRefreshAllowed(Kernel<?,?,?,?> kernel);
+
+}
\ No newline at end of file

Added: trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/MeasureUtil.java
===================================================================
--- trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/MeasureUtil.java	                        (rev 0)
+++ trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/MeasureUtil.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,222 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.core;
+
+/**
+ * This class permits to manipulate measure units.
+ * <p>
+ * A foot is a unit of length, in a number of different systems, 
+ * including English units, Imperial units, and United States
+ * customary units. Its size can vary from system to system,
+ * but in each is around a quarter to a third of a meter.
+ * The most commonly used foot today is the international foot.
+ * There are 3 feet in a yard and 12 inches in a foot.
+ * <p>
+ * An inch is the name of a unit of length in a number of
+ * different systems, including English units, Imperial units,
+ * and United States customary units. Its size can vary from system
+ * to system. There are 36 inches in a yard and 12 inches in a foot.
+ * <p>
+ * The fathoms is the name of a unit of length,
+ * in a number of different systems, including
+ * English units, Imperial units, and United
+ * States customary units. The name derives from
+ * the Old English word f&aelig;thm (plural) meaning 
+ * 'outstretched arms' which was the original
+ * definition of the unit's measure.
+ * 
+ * @author St&eacute;phane GALLAND &lt;stephane.galland@xxxxxxx&gt;
+ * @version $Name:  $ $Revision: 1.1 $ $Date: 2007-02-20 08:52:35 $
+ */
+public class MeasureUtil {
+
+	/** Translate m/s to km/h.
+	 */
+	public static double ms2kmh(double ms) {
+		//return ((ms/1000.0)*3600.0);
+		return ms*3.6;
+	}
+
+	/** Translate km/h to m/s.
+	 */
+	public static double kmh2ms(double kmh) {
+		//return ((kmh/3600.0)*1000.0);
+		return kmh / 3.6;
+	}
+
+	/** Translate meters to kilometers.
+	 */
+	public static double m2km(double m) {
+		return m / 1000.;
+	}
+	
+	/** Translate kilometers to meters.
+	 */
+	public static double km2m(double km) {
+		return km * 1000.;
+	}
+
+	/** Translate from "long" pixel coordinate to "system" pixel coordinate.
+	 * 
+	 * @param pixel_coord is the pixel coordinate to translate.
+	 */
+	public static int pix2pix(double pixel_coord) {
+		return (int)Math.round(pixel_coord);
+	}
+	
+	/** Translate from "long" pixel coordinate to "system" pixel coordinate.
+	 * 
+	 * @param pixel_coord is the pixel coordinate to translate.
+	 */
+	public static int pix2pix(long pixel_coord) {
+		return (int)pixel_coord;
+	}
+
+	/** Translate from "long" pixel coordinate to "system" pixel coordinate.
+	 * 
+	 * @param pixel_coord is the pixel coordinate to translate.
+	 */
+	public static int pix2pix(float pixel_coord) {
+		return Math.round(pixel_coord);
+	}
+
+	/** Translate from unit (10^0) to nano (10^-9).
+	 */
+	public static double unit2nano(double unit) {
+		return unit / 1e-9;
+	}
+	
+	/** Translate from nano (10^-9) to unit (10^0).
+	 */
+	public static double nano2unit(double nano) {
+		return nano * 1e-9;
+	}
+
+	/** Translate from unit (10^0) to micro (10^-6).
+	 */
+	public static double unit2micro(double unit) {
+		return unit / 1e-6;
+	}
+	
+	/** Translate from micro (10^-6) to unit (10^0).
+	 */
+	public static double micro2unit(double micro) {
+		return micro * 1e-6;
+	}
+
+	/** Translate from unit (10^0) to milli (10^-3).
+	 */
+	public static double unit2milli(double unit) {
+		return unit / 1e-3;
+	}
+	
+	/** Translate from milli (10^-3) to unit (10^0).
+	 */
+	public static double milli2unit(double milli) {
+		return milli * 1e-3;
+	}
+	
+	/** Translate from milli (10^-3) to micro (10^-6).
+	 */
+	public static double milli2micro(double milli) {
+		return milli / 1e-3;
+	}
+
+	/** Translate from milli (10^-3) to nano (10^-9).
+	 */
+	public static double milli2nano(double milli) {
+		return milli / 1e-6;
+	}
+
+	/** Translate from micro (10^-6) to nano (10^-9).
+	 */
+	public static double micro2nano(double milli) {
+		return milli / 1e-3;
+	}
+
+	/** Translate from micro (10^-6) to milli (10^-3).
+	 */
+	public static double micro2milli(double micro) {
+		return micro * 1e-3;
+	}
+
+	/** Translate from nano (10^-9) to micro (10^-6).
+	 */
+	public static double nano2micro(double nano) {
+		return nano * 1e-3;
+	}
+
+	/** Translate from nano (10^-9) to milli (10^-3).
+	 */
+	public static double nano2milli(double nano) {
+		return nano * 1e-6;
+	}
+	
+	/** Translate meters to fathoms.
+	 */
+	public static double m2fh(double m) {
+		return m * 0.5468;
+	}
+
+	/** Translate feets to fathoms.
+	 */
+	public static double ft2fh(double ft) {
+		return ft * 0.1667;
+	}
+
+	/** Translate inches to fathoms.
+	 */
+	public static double in2fh(double in) {
+		return in / 72;
+	}
+
+	/** Translate meters to feets.
+	 */
+	public static double m2ft(double m) {
+		return m * 0.3048;
+	}
+
+	/** Translate inches to feets.
+	 */
+	public static double in2ft(double in) {
+		return in / 12;
+	}
+
+	/** Translate fathoms to feets.
+	 */
+	public static double fh2ft(double fh) {
+		return fh / 0.1667;
+	}
+	
+	/** Translate meters to inches.
+	 */
+	public static double m2in(double m) {
+		return m * 0.025;
+	}
+	
+	/** Translate feets to inches.
+	 */
+	public static double ft2in(double ft) {
+		return ft * 12;
+	}
+
+}
\ No newline at end of file

Added: trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/Message.java
===================================================================
--- trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/Message.java	                        (rev 0)
+++ trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/Message.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,85 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.core;
+
+import java.io.Serializable;
+
+
+
+/** Message exchange by agents.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ * @author Nicolas GAUD &lt;nicolas.gaud@xxxxxxx&gt;
+ */
+public class Message implements Serializable {
+
+	private static final long serialVersionUID = 48820292710180478L;
+
+	/** Content of this message
+	 */	
+	public final Serializable CONTENT ;
+
+	/** Sender.
+	 */	
+	public final AgentIdentifier FROM ;
+
+	/** Receiver.
+	 */	
+	public final AgentIdentifier TO ;
+
+	/**
+	 * @param from is the emitter
+	 * @param to is the received
+	 * @param content is the content of the message.
+	 */
+	public Message(AgentIdentifier from, AgentIdentifier to, Serializable content) {
+		assert(from!=null);
+		assert(to!=null);
+		this.FROM = from ;
+		this.TO = to ;
+		this.CONTENT = content ;
+	}
+	
+	/** Replies if the content of this message has the specified type.
+	 * 
+	 * @param type is the type to test against the message content
+	 * @return <code>true</code> if the message content is an instance of the given type,
+	 * otherwise <code>false</code>
+	 */
+	public boolean isTypeOf(Class<? extends Serializable> type) {
+		assert(type!=null);
+		return ((this.CONTENT!=null)&&
+				(type.isInstance(this.CONTENT)));
+	}
+	
+	/** Replies the content.
+	 * 
+	 * @param <T> is the type of the message content.
+	 * @throws ClassCastException if the content could not be casted as type {@code T}.
+	 * @return the message content. 
+	 */
+	@SuppressWarnings("unchecked")
+	public <T extends Serializable> T getContent() {
+		return (T)this.CONTENT;
+	}
+
+}
\ No newline at end of file

Added: trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/MessageBoxManager.java
===================================================================
--- trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/MessageBoxManager.java	                        (rev 0)
+++ trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/MessageBoxManager.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,113 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.core;
+
+import java.util.Map;
+import java.util.Queue;
+import java.util.WeakHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+
+
+/** This class manager a set of message boxes. Each message box is associated
+ * to exactly one agent and contains a list of messages that were not consumed
+ * by the agent.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ * @author Nicolas GAUD &lt;nicolas.gaud@xxxxxxx&gt;
+ */
+class MessageBoxManager {
+
+	/** Message boxes.
+	 */	
+	private final Map<AgentIdentifier,Queue<Message>> __queues = new WeakHashMap<AgentIdentifier,Queue<Message>>() ;
+
+	/** Create a message box for the specified agent
+	 * 
+	 * @param id is the identifier of the agent for which a box must be created.
+	 */	
+	synchronized void registerAgent(AgentIdentifier id) {
+		assert(id!=null);
+		this.__queues.put(id, new ConcurrentLinkedQueue<Message>()) ;
+	}
+
+	/** Delete the message box of the specified agent
+	 * 
+	 * @param id est l'identificateur de l'agent
+	 */	
+	synchronized void unregisterAgent(AgentIdentifier id) {
+		assert(id!=null);
+		this.__queues.remove(id) ;
+	}
+	
+	/** Store a message inside a box.
+	 * <p>
+	 * The box depends on the message receiver.
+	 *
+	 * @param m is the message to store in the mailbox.
+	 * @return <code>true</code> if the message was successfully stored, otherwise <code>false</code>
+	 */
+	synchronized public boolean storeMessage(Message m) {
+		if (m!=null && m.TO!=null) {
+			Queue<Message> queue = this.__queues.get(m.TO);
+			if (queue!=null) {				
+				return queue.offer(m);
+			}
+		}
+		return false ;
+	}
+
+	/** Replies the next available message for the specified agent.
+	 * <p>
+	 * This method consumes the message. It means that the message will
+	 * never be obtain another time.
+	 * 
+	 * @param id is the identifier of the agent for which the message was extracted.
+	 * @return a message or <code>null</code> if none available
+	 */
+	public synchronized Message getNextMessage(AgentIdentifier id) {
+		if (id!=null) {
+			Queue<Message> queue = this.__queues.get(id);
+			if ((queue!=null)&&(queue.size()>0)) {				
+				return queue.poll() ;
+			}
+		}
+
+		return null ;
+	}
+	
+	/** Replies if a message is available for the specified agent.
+	 * <p>
+	 * This method does not consume the message.
+	 * 
+	 * @param id is the identifier of the agent for which the message was extracted.
+	 * @return <code>true</code> if a message is available, otherwise <code>false</code>
+	 */
+	protected synchronized boolean hasMessage(AgentIdentifier id) {
+		if (id!=null) {
+			Queue<Message> queue = this.__queues.get(id);
+			return ((queue!=null)&&(queue.size()>0));				
+		}
+		return false ;
+	}
+	
+}
\ No newline at end of file

Added: trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/MessageTransportService.java
===================================================================
--- trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/MessageTransportService.java	                        (rev 0)
+++ trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/MessageTransportService.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,117 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.core;
+
+
+/** This component permits to route the message between agents.
+ * <p>
+ * The implementation of this MTS assumes that only one kernel
+ * is available. It does not support more than one kernel and
+ * network communication.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ * @author Nicolas GAUD &lt;nicolas.gaud@xxxxxxx&gt;
+ */
+public class MessageTransportService {
+
+	/** Local Message boxes.
+	 */	
+	private final MessageBoxManager __msgboxes = new MessageBoxManager() ;
+	
+	/** Invoked by the kernel when the MTS should stop.
+	 */
+	public void stopMTS() {
+		//
+	}
+	
+	/** Invoked by the kernel when the MTS should start.
+	 */
+	public void startMTS() {
+		//
+	}
+
+	/** Create a local message box for the specified agent.
+	 */	
+	void registerAgent(AgentIdentifier id) {
+		assert(id!=null);
+		this.__msgboxes.registerAgent(id);
+	}
+
+	/** Delete the local message box of the specified agent.
+	 */	
+	void unregisterAgent(AgentIdentifier id) {
+		assert(id!=null);
+		this.__msgboxes.unregisterAgent(id);
+	}
+	
+	/** Send the specified message according to the
+	 * knownledge of this MTS.
+	 */
+	public boolean send(Message m) {
+		assert(m!=null);
+		return registerInLocalBoxes(m);
+	}
+
+	/** Store the specified message inside the local message boxes.
+	 * 
+	 * @return <code>true</code> if the message was successfully stored,
+	 * otherwise <code>false</code>
+	 */
+	protected boolean registerInLocalBoxes(Message m) {
+		assert(m!=null);
+		return this.__msgboxes.storeMessage(m);
+	}
+
+	/** Replies the next available message for the specified agent.
+	 * <p>
+	 * This method consumes the message. It means that the message will
+	 * never be obtain another time.
+	 * 
+	 * @param id is the identifier of the agent for which the message was extracted.
+	 * @return a message or <code>null</code> if none available
+	 */
+	public Message getNextMessage(AgentIdentifier id) {
+		assert(id!=null);
+		return this.__msgboxes.getNextMessage(id);
+	}
+	
+	/** Replies if a message is available for the specified agent.
+	 * <p>
+	 * This method does not consume the message.
+	 * 
+	 * @param id is the identifier of the agent for which the message was extracted.
+	 * @return <code>true</code> if a message is available, otherwise <code>false</code>
+	 */
+	protected boolean hasMessage(AgentIdentifier id) {
+		assert(id!=null);
+		return this.__msgboxes.hasMessage(id);
+	}
+
+	/** Replies the identifier of a kernel.
+	 * <p>
+	 * This method is invoked by the kernel to obtain its own identifier.
+	 */
+	protected KernelIdentifier getKernelId() {
+		return new KernelIdentifier();
+	}
+
+}
\ No newline at end of file

Added: trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/Probe.java
===================================================================
--- trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/Probe.java	                        (rev 0)
+++ trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/Probe.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,155 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.core;
+
+/** A probe permits to obtain information on agents.
+ * <p>
+ * A probe must not be invasive and the agent is
+ * able to ignore them (ie. to not provide information).
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ * @author Nicolas GAUD &lt;nicolas.gaud@xxxxxxx&gt;
+ */
+public interface Probe {
+
+	/** Replies the names of the probed values inside the agent.
+	 * 
+	 * @return the names of the probed values inside the agent.
+	 */
+	public String[] getProbeNames();
+
+	/** Replies a probed value.
+	 * 
+	 * @param <T> is the type of the value to reply.
+	 * @param clazz is the type of the value to reply.
+	 * @param probeName is the name of the probed value
+	 * @return the value
+	 */
+	public <T> T getProbeValue(String probeName, Class<T> clazz);
+
+	/** Replies a probed value.
+	 * <p>
+	 * This method permits to force the type of the value.
+	 * 
+	 * @param <T> is the type of the value to reply.
+	 * @param probeName is the name of the probed value.
+	 * @param clazz is the type of the expected value.
+	 * @return the value or <code>null</code>
+	 */
+	public <T> T[] getProbeArray(String probeName, Class<T> clazz);
+
+	/** Replies a probed value.
+	 * <p>
+	 * This method permits to force the type of the value.
+	 * 
+	 * @param probeName is the name of the probed value.
+	 * @return the value or <code>null</code>
+	 * @throws ProbeValueNotDefinedException
+	 */
+	public int getProbeInt(String probeName) throws ProbeValueNotDefinedException;
+
+	/** Replies a probed value.
+	 * <p>
+	 * This method permits to force the type of the value.
+	 * 
+	 * @param probeName is the name of the probed value.
+	 * @return the value or <code>null</code>
+	 * @throws ProbeValueNotDefinedException
+	 */
+	public long getProbeLong(String probeName) throws ProbeValueNotDefinedException;
+
+	/** Replies a probed value.
+	 * <p>
+	 * This method permits to force the type of the value.
+	 * 
+	 * @param probeName is the name of the probed value.
+	 * @return the value or <code>null</code>
+	 * @throws ProbeValueNotDefinedException
+	 */
+	public float getProbeFloat(String probeName) throws ProbeValueNotDefinedException;
+
+	/** Replies a probed value.
+	 * <p>
+	 * This method permits to force the type of the value.
+	 * 
+	 * @param probeName is the name of the probed value.
+	 * @return the value or <code>null</code>
+	 * @throws ProbeValueNotDefinedException
+	 */
+	public double getProbeDouble(String probeName) throws ProbeValueNotDefinedException;
+
+	/** Replies a probed value.
+	 * <p>
+	 * This method permits to force the type of the value.
+	 * 
+	 * @param probeName is the name of the probed value.
+	 * @return the value or <code>null</code>
+	 * @throws ProbeValueNotDefinedException
+	 */
+	public boolean getProbeBool(String probeName) throws ProbeValueNotDefinedException;
+
+	/** Replies a probed value.
+	 * <p>
+	 * This method permits to force the type of the value.
+	 * 
+	 * @param probeName is the name of the probed value.
+	 * @return the value or <code>null</code>
+	 * @throws ProbeValueNotDefinedException
+	 */
+	public char getProbeChar(String probeName) throws ProbeValueNotDefinedException;
+
+	/** Replies a probed value.
+	 * <p>
+	 * This method permits to force the type of the value.
+	 * 
+	 * @param probeName is the name of the probed value.
+	 * @return the value or <code>null</code>
+	 * @throws ProbeValueNotDefinedException
+	 */
+	public String getProbeString(String probeName) throws ProbeValueNotDefinedException;
+	
+	/** Replies if the agent is alive.
+	 * 
+	 * @return <code>true</code> if the agent associated to this probe is alive, otherwise <code>false</code>
+	 */
+	public boolean isProbedAgentAlive();
+	
+	/** Replies the identifier of the probed agent.
+	 * 
+	 * @return the identifier of the probed agent.
+	 */
+	public AgentIdentifier getProbedAgentId();
+
+	/** Replies if this probe contains a value.
+	 * 
+	 * @return <code>true</code> if a probe value exists, otherwise <code>false</code>
+	 */
+	public boolean hasProbeValues();
+
+	/** Replies if the specified probe value exists.
+	 *
+	 * @param probeName is the value name to test.
+	 * @return <code>true</code> if a probe value exists, otherwise <code>false</code>
+	 */
+	public boolean hasProbeValue(String probeName);
+
+}
\ No newline at end of file

Added: trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/ProbeValueNotDefinedException.java
===================================================================
--- trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/ProbeValueNotDefinedException.java	                        (rev 0)
+++ trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/ProbeValueNotDefinedException.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,41 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.core;
+
+/** A probe value was not found.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ * @author Nicolas GAUD &lt;nicolas.gaud@xxxxxxx&gt;
+ */
+public class ProbeValueNotDefinedException extends Exception {
+
+	private static final long serialVersionUID = -6987643328261463176L;
+
+	public ProbeValueNotDefinedException(String valueName) {
+		super(valueName);
+	}
+	
+	public String getValueName() {
+		return getMessage();
+	}
+	
+}
\ No newline at end of file

Added: trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/Scheduler.java
===================================================================
--- trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/Scheduler.java	                        (rev 0)
+++ trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/Scheduler.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,55 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.core;
+
+import java.util.List;
+
+
+/** Scheduler for agents.
+ * <p>
+ * A scheduler must make the agents alive.
+ * 
+ * @param <AT> is the type of the agents to schedule.
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ * @author Nicolas GAUD &lt;nicolas.gaud@xxxxxxx&gt;
+ */
+public interface Scheduler<AT extends Agent> {
+
+	/** Run the elements of the simulation: environment and agents.
+	 * <p>
+	 * Invoked when the agents AND the environment must be scheduled.
+	 * 
+	 * @param runningKernel is the kernel that has invoked this function.
+	 * @param environment is the environment object associated to this execution
+	 * @param agents is the list of agents to schedule.
+	 */
+	public void schedule(Kernel<AT,?,?,?> runningKernel, Environment<AT> environment, List<AT> agents);
+
+	/** Make the specified agents alive.
+	 * <p>
+	 * Invoked when the only agents must be scheduled.
+	 * 
+	 * @param agents is the list of agents to schedule.
+	 */
+	public void schedule(List<AT> agents);
+
+}
\ No newline at end of file

Added: trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/SimpleIdentifier.java
===================================================================
--- trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/SimpleIdentifier.java	                        (rev 0)
+++ trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/SimpleIdentifier.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,77 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.core;
+
+import java.rmi.server.UID;
+
+/** Basic implementation of an identifier.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ * @author Nicolas GAUD &lt;nicolas.gaud@xxxxxxx&gt;
+ */
+public class SimpleIdentifier implements Identifier {
+
+	private static final long serialVersionUID = 5809385011371117305L;
+	
+	private final String __id;
+	
+	/**
+	 * @param id is the value of the identifier.
+	 */
+	public SimpleIdentifier(String id) {
+		assert((id!=null)&&(!"".equals(id))); //$NON-NLS-1$
+		this.__id = id;
+	}
+
+	/**
+	 * Create a random identifier.
+	 */
+	public SimpleIdentifier() {
+		this.__id = new UID().toString();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public String toString() {
+		return Long.toHexString(serialVersionUID)+":"+this.__id.toString(); //$NON-NLS-1$
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public boolean equals(Object o) {
+		return ((o instanceof Identifier)&&
+				((this==o)||(toString().equals(o.toString()))));
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public int compareTo(Identifier id) {
+		if (id==null) return -1;
+		return toString().compareTo(id.toString());
+	}
+	
+}
\ No newline at end of file

Added: trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/SimulationClock.java
===================================================================
--- trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/SimulationClock.java	                        (rev 0)
+++ trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/SimulationClock.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,76 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.core;
+
+import java.util.concurrent.TimeUnit;
+
+/** Simulation clock that permits to obtain the simulation time.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public interface SimulationClock {
+	
+	/** Replies the current date of simulation.
+	 * 
+	 * @param desired_unit indicates the unit to use
+	 * @return the simulation's time espressed in the specified unit.
+	 */
+	public double getSimulationTime(TimeUnit desired_unit);
+
+	/** Replies the current date of simulation.
+	 * <p>
+	 * The unit depends on the environment's implementation.
+	 * <p>
+	 * <code>simulation_time(t+1) = simulation_time(t) + step_duration</code>
+	 * 
+	 * @return the simulation's time espressed in seconds.
+	 */
+	public double getSimulationTime();
+
+	/** Replies the duration of a simulation loop for this environment.
+	 * <p>
+	 * <code>simulation_time(t+1) = simulation_time(t) + step_duration</code>
+	 * 
+	 * @param desired_unit indicates the unit to use
+	 * @return the simulation's step time.
+	 */
+	public double getSimulationStepDuration(TimeUnit desired_unit);
+
+	/** Replies the duration of a simulation loop for this environment.
+	 * <p>
+	 * <code>simulation_time(t+1) = simulation_time(t) + step_duration</code>
+	 * 
+	 * @return the simulation's step time.
+	 */
+	public double getSimulationStepDuration();
+
+	/** Compute a value expressed in something per time unit into
+	 * something per simulation loop.
+	 */
+	public double perTimeUnit(double value);
+
+	/** Compute a value expressed in something per time unit into
+	 * something per simulation loop.
+	 */
+	public double perTimeUnit(double value, TimeUnit desiredUnit);
+
+}
\ No newline at end of file

Added: trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/TimeManager.java
===================================================================
--- trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/TimeManager.java	                        (rev 0)
+++ trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/TimeManager.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,128 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.core;
+
+import java.util.concurrent.TimeUnit;
+
+/** Time Manager.
+ * <p>
+ * <code>simulation_time(t+1) = simulation_time(t) + step_duration</code>
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ * @author Nicolas GAUD &lt;nicolas.gaud@xxxxxxx&gt;
+ */
+public abstract class TimeManager {
+	
+	/** Set the current simulation time. It is the count of
+	 * seconds since the starting of the simulation.
+	 * <p>
+	 * <code>simulation_time(t+1) = simulation_time(t) + step_duration</code>
+	 * 
+	 * @param time is the new simulation time expresed in seconds.
+	 */
+	protected abstract void setSimulationTime(double time);
+	
+	/** Set the current simulation step duration. It is the duration
+	 * of one simulation step expressed in the simulation time
+	 * coordinate system.
+	 * <p>
+	 * <code>simulation_time(t+1) = simulation_time(t) + step_duration</code>
+	 * 
+	 * @param step_duration is the new simulation time expresed in milliseconds.
+	 */
+	protected abstract void setSimulationStepDuration(double step_duration);
+
+	/** Called by the environment before the scheduling of the agents.
+	 * 
+	 * @param kernel_time is the current kernel date.
+	 * @param last_kernel_step_duration is the duration of the last
+	 * kernel step in milliseconds.
+	 */
+	final void beforeAgentScheduling(long kernel_time, long last_kernel_step_duration) {
+		preAgentScheduling(kernel_time,last_kernel_step_duration);
+	}
+	
+	/** Called by the environment before the scheduling of the agents.
+	 * 
+	 * @param kernel_time is the current kernel date.
+	 * @param last_kernel_step_duration is the duration of the last
+	 * kernel step in milliseconds.
+	 */
+	protected abstract void preAgentScheduling(long kernel_time, long last_kernel_step_duration);
+
+	/** Called by the environment before the scheduling of the agents.
+	 * 
+	 * @param kernel_time is the current kernel date.
+	 * @param last_kernel_step_duration is the duration of the last
+	 * kernel step in milliseconds.
+	 */
+	final void afterAgentScheduling(long kernel_time, long last_kernel_step_duration) {
+		postAgentScheduling(kernel_time,last_kernel_step_duration);
+	}
+
+	/** Called by the environment before the scheduling of the agents.
+	 * 
+	 * @param kernel_time is the current kernel date.
+	 * @param last_kernel_step_duration is the duration of the last
+	 * kernel step in milliseconds.
+	 */
+	protected abstract void postAgentScheduling(long kernel_time, long last_kernel_step_duration);
+
+	/** Replies the current date of simulation.
+	 * 
+	 * @param desired_unit indicates the unit to use
+	 * @return the simulation's time espressed in the specified unit.
+	 */
+	public abstract double getSimulationTime(TimeUnit desired_unit);
+
+	/** Replies the current date of simulation.
+	 * <p>
+	 * The unit depends on the environment's implementation.
+	 * <p>
+	 * <code>simulation_time(t+1) = simulation_time(t) + step_duration</code>
+	 * 
+	 * @return the simulation's time espressed in seconds.
+	 */
+	public final double getSimulationTime() {
+		return getSimulationTime(TimeUnit.SECONDS);
+	}
+
+	/** Replies the duration of a simulation loop for this environment.
+	 * <p>
+	 * <code>simulation_time(t+1) = simulation_time(t) + step_duration</code>
+	 * 
+	 * @param desired_unit indicates the unit to use
+	 * @return the simulation's step time.
+	 */
+	public abstract double getSimulationStepDuration(TimeUnit desired_unit);
+
+	/** Replies the duration of a simulation loop for this environment.
+	 * <p>
+	 * <code>simulation_time(t+1) = simulation_time(t) + step_duration</code>
+	 * 
+	 * @return the simulation's step time.
+	 */
+	public final double getSimulationStepDuration() {
+		return getSimulationStepDuration(TimeUnit.SECONDS);
+	}
+
+}
\ No newline at end of file

Added: trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/WhitePages.java
===================================================================
--- trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/WhitePages.java	                        (rev 0)
+++ trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/WhitePages.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,122 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.core;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.Map.Entry;
+
+/** The white page system is able to list all the agents that exist on a kernel or
+ * on a set of kernel (depending of its implementation).
+ * <p>
+ * The white page system has also the role to compute an unique identifier for
+ * each agent.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ * @author Nicolas GAUD &lt;nicolas.gaud@xxxxxxx&gt;
+ */
+class WhitePages<AT extends Agent> {
+
+	/** Repository
+	 */	
+	private final Map<AgentIdentifier,AT> __annuaire = new TreeMap<AgentIdentifier,AT>() ;
+
+	/** Register an agent and compute its identifier.
+	 */	
+	public synchronized void register(AT a) {
+		assert(a!=null);
+		AgentIdentifier id = new AgentIdentifier();
+		while (this.__annuaire.containsKey(id)) {
+			id = new AgentIdentifier();
+		}
+		this.__annuaire.put(id, a) ;
+		a.setId(id);
+	}
+
+	/** Register an agent and give it the specified identifier.
+	 */	
+	public synchronized void register(AgentIdentifier id, AT a) {
+		assert(id!=null);
+		assert(a!=null);
+		if (!this.__annuaire.containsKey(id)) {
+			this.__annuaire.put(id, a) ;
+			a.setId(id);
+		}
+	}
+
+	/** Unregister an agent.
+	 */
+	public synchronized AT unregister(AgentIdentifier id) {
+		assert(id!=null);
+		AT ag = this.__annuaire.get(id);
+		if (ag!=null) {
+			ag.setId(null);
+		}
+		return this.__annuaire.remove(id) ;
+	}
+
+	/** Replies the count of registered agents.
+	 */
+	public synchronized int size() {
+		return this.__annuaire.size() ;
+	}
+
+	/** Replies the list of the identifiers of the registered agents.
+	 */
+	public synchronized AgentIdentifier[] getAllAgentIdentifiers() {
+		Set<AgentIdentifier> theSet = this.__annuaire.keySet();
+		AgentIdentifier[] tab = new AgentIdentifier[theSet.size()];
+		theSet.toArray(tab);
+		return tab;
+	}
+
+	/** Replies all the agents.
+	 */
+	synchronized Collection<AT> getAllAgents() {
+		return this.__annuaire.values();
+	}
+
+	/** Replies the agent that corresponds to the specified identifier.
+	 */
+	synchronized AT getAgent(AgentIdentifier id) {
+		assert(id!=null);
+		return this.__annuaire.get(id) ;
+	}
+
+	/** Replies the identifier of the specified agent.
+	 */	
+	synchronized AgentIdentifier getId(AT a) {
+		assert(a!=null);
+		Iterator<Entry<AgentIdentifier,AT>> itEntries = this.__annuaire.entrySet().iterator();
+		while(itEntries.hasNext()) {
+			Entry<AgentIdentifier,AT> entry = itEntries.next();
+			if (entry.getValue() == a) {
+				return entry.getKey() ;
+			}
+		}
+		return null ;
+	}
+		
+}
\ No newline at end of file

Added: trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/YellowPages.java
===================================================================
--- trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/YellowPages.java	                        (rev 0)
+++ trunk/tinymas-kernel/src/main/java/org/arakhne/tinyMAS/core/YellowPages.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,185 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.core;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+/** Manager a set of services.
+ * <p>
+ * A service is provided by a set of agents
+ * and is identified by its name.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ * @author Nicolas GAUD &lt;nicolas.gaud@xxxxxxx&gt;
+ */
+public class YellowPages {
+
+	/** Repository
+	 */	
+	private final Map<String,Set<AgentIdentifier>> __annuaire = new TreeMap<String,Set<AgentIdentifier>>() ;
+	
+	/** Register a service provided by the specified agent.
+	 * 
+	 * @param service is the name of the service.
+	 * @param agent is the agent that provides the service
+	 */	
+	public void registerService(String service, AgentIdentifier agent) {
+		assert((service!=null)&&(!"".equals(service))); //$NON-NLS-1$
+		assert(agent!=null);
+		Set<AgentIdentifier> list = this.__annuaire.get(service);
+		if (list==null) {
+			list = new TreeSet<AgentIdentifier>();
+			this.__annuaire.put(service,list);
+		}
+		if (!list.contains(agent)) {
+			list.add(agent);
+		}
+	}
+
+	/** Remove the specified agent-service association. 
+	 * 
+	 * @param service is the name of the service.
+	 * @param agent is the agent that no more provides the service
+	 */
+	public void unregisterService(String service, AgentIdentifier agent) {
+		assert((service!=null)&&(!"".equals(service))); //$NON-NLS-1$
+		assert(agent!=null);
+		Set<AgentIdentifier> list = this.__annuaire.get(service);
+		if (list!=null) {
+			list.remove(agent);
+		}
+	}
+
+	/** Remove a service from the system.
+	 * <p>
+	 * All associated agents will be unlinked to the specified service.
+	 */
+	public void unregisterService(String service) {
+		assert((service!=null)&&(!"".equals(service))); //$NON-NLS-1$
+		this.__annuaire.remove(service);
+	}
+
+	/** Remove the specified agent from the yellow pages.
+	 */
+	public void unregisterServices(AgentIdentifier agent) {
+		assert(agent!=null);
+		Iterator<Set<AgentIdentifier>> itEntry = this.__annuaire.values().iterator();
+		while (itEntry.hasNext()) {
+			Set<AgentIdentifier> list = itEntry.next();
+			if (list!=null) {
+				list.remove(agent);
+			}
+		}
+	}
+
+	/** Replies if the specified agent provides the given service.
+	 */
+	public boolean isRegisteredAgent(String service, AgentIdentifier agent) {
+		assert((service!=null)&&(!"".equals(service))); //$NON-NLS-1$
+		assert(agent!=null);
+		Set<AgentIdentifier> list = this.__annuaire.get(service);
+		if (list!=null) {
+			return list.contains(agent);
+		}
+		return false;
+	}
+
+	/** Replies if the specified service is provided by at least one agent.
+	 */
+	public boolean isRegisteredService(String service) {
+		assert((service!=null)&&(!"".equals(service))); //$NON-NLS-1$
+		return this.__annuaire.containsKey(service);
+	}
+	
+	/** Replies if the specified agent provides a service.
+	 */
+	public boolean isRegisteredAgent(AgentIdentifier agent) {
+		assert(agent!=null);
+		Iterator<Set<AgentIdentifier>> itEntry = this.__annuaire.values().iterator();
+		while (itEntry.hasNext()) {
+			Set<AgentIdentifier> list = itEntry.next();
+			if ((list!=null)&&
+				(list.contains(agent))) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/** Replies all the agents that provide services
+	 */
+	public AgentIdentifier[] getAgents(String service) {
+		assert((service!=null)&&(!"".equals(service))); //$NON-NLS-1$
+		Set<AgentIdentifier> list = this.__annuaire.get(service);
+		if (list!=null) {
+			AgentIdentifier[] tab = new AgentIdentifier[list.size()];
+			list.toArray(tab);
+			return tab;
+		}
+		return new AgentIdentifier[0];
+	}
+	
+	/** Replies an agent that provides the specified service.
+	 * <p>
+	 * The agent is randomly selected inside the list of agents
+	 * that provide the specified service.
+	 */
+	public AgentIdentifier getAgentFor(String service) {
+		assert((service!=null)&&(!"".equals(service))); //$NON-NLS-1$
+		Set<AgentIdentifier> list = this.__annuaire.get(service);
+		if (list!=null) {
+			try {
+				int r = (int)(Math.random()*list.size());
+				return (AgentIdentifier)list.toArray()[r];
+			}
+			catch(IndexOutOfBoundsException _) {
+				//
+			}
+		}
+		return null;
+	}
+
+	/** Replies all the services registered inside this repository.
+	 */
+	public String[] getAllServices() {
+		Set<String> serv = this.__annuaire.keySet();
+		String[] services = new String[serv.size()];
+		serv.toArray(services);
+		return services;
+	}
+
+	@SuppressWarnings("unchecked")
+	protected final <T extends MessageTransportService> T getMTS(Class<T> clazz) {
+		assert(clazz!=null);
+		Kernel<?,?,?,?> kernel = Kernel.getSingleton();
+		if (kernel!=null) {
+			MessageTransportService mts = kernel.getMTS();
+			if (clazz.isInstance(mts)) return (T)mts;
+		}
+		return null;
+	}
+	
+}
\ No newline at end of file

Added: trunk/tinymas-kernel/src/main/resources/AUTHORS
===================================================================
--- trunk/tinymas-kernel/src/main/resources/AUTHORS	                        (rev 0)
+++ trunk/tinymas-kernel/src/main/resources/AUTHORS	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,2 @@
+Stephane GALLAND <galland@xxxxxxxxxxx>
+Nicolas GAUD <gaud@xxxxxxxxxxx>

Added: trunk/tinymas-kernel/src/main/resources/COPYING
===================================================================
--- trunk/tinymas-kernel/src/main/resources/COPYING	                        (rev 0)
+++ trunk/tinymas-kernel/src/main/resources/COPYING	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,165 @@
+		   GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+  This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+  0. Additional Definitions. 
+
+  As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+  "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+  An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+  A "Combined Work" is a work produced by combining or linking an
+Application with the Library.  The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+  The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+  The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+  1. Exception to Section 3 of the GNU GPL.
+
+  You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+  2. Conveying Modified Versions.
+
+  If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+   a) under this License, provided that you make a good faith effort to
+   ensure that, in the event an Application does not supply the
+   function or data, the facility still operates, and performs
+   whatever part of its purpose remains meaningful, or
+
+   b) under the GNU GPL, with none of the additional permissions of
+   this License applicable to that copy.
+
+  3. Object Code Incorporating Material from Library Header Files.
+
+  The object code form of an Application may incorporate material from
+a header file that is part of the Library.  You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+   a) Give prominent notice with each copy of the object code that the
+   Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the object code with a copy of the GNU GPL and this license
+   document.
+
+  4. Combined Works.
+
+  You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+   a) Give prominent notice with each copy of the Combined Work that
+   the Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the Combined Work with a copy of the GNU GPL and this license
+   document.
+
+   c) For a Combined Work that displays copyright notices during
+   execution, include the copyright notice for the Library among
+   these notices, as well as a reference directing the user to the
+   copies of the GNU GPL and this license document.
+
+   d) Do one of the following:
+
+       0) Convey the Minimal Corresponding Source under the terms of this
+       License, and the Corresponding Application Code in a form
+       suitable for, and under terms that permit, the user to
+       recombine or relink the Application with a modified version of
+       the Linked Version to produce a modified Combined Work, in the
+       manner specified by section 6 of the GNU GPL for conveying
+       Corresponding Source.
+
+       1) Use a suitable shared library mechanism for linking with the
+       Library.  A suitable mechanism is one that (a) uses at run time
+       a copy of the Library already present on the user's computer
+       system, and (b) will operate properly with a modified version
+       of the Library that is interface-compatible with the Linked
+       Version. 
+
+   e) Provide Installation Information, but only if you would otherwise
+   be required to provide such information under section 6 of the
+   GNU GPL, and only to the extent that such information is
+   necessary to install and execute a modified version of the
+   Combined Work produced by recombining or relinking the
+   Application with a modified version of the Linked Version. (If
+   you use option 4d0, the Installation Information must accompany
+   the Minimal Corresponding Source and Corresponding Application
+   Code. If you use option 4d1, you must provide the Installation
+   Information in the manner specified by section 6 of the GNU GPL
+   for conveying Corresponding Source.)
+
+  5. Combined Libraries.
+
+  You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+   a) Accompany the combined library with a copy of the same work based
+   on the Library, uncombined with any other library facilities,
+   conveyed under the terms of this License.
+
+   b) Give prominent notice with the combined library that part of it
+   is a work based on the Library, and explaining where to find the
+   accompanying uncombined form of the same work.
+
+  6. Revised Versions of the GNU Lesser General Public License.
+
+  The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+  Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+  If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.

Added: trunk/tinymas-kernel/src/main/resources/Changelog
===================================================================
--- trunk/tinymas-kernel/src/main/resources/Changelog	                        (rev 0)
+++ trunk/tinymas-kernel/src/main/resources/Changelog	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,95 @@
+tinyMAS-6.6
+
+ * First Mavenization of the tinyMAS project.
+ * Bug fix: change the agent's lifecycle for situated environment.
+ * Bug fix: enhance the stability of the network support
+
+ -- Stephane GALLAND <galland@xxxxxxxxxxx> Sat, 04 Apr 2009 10:08:40 +0200
+
+tinyMAS-6.5
+
+ * Bug fix: prevent ConcurrentModificationException exception on the list of the agents.
+ * Enhance the performances of the simulator with calls of the doPerception()
+   and doDecisionAndAction() functions in the same live() invocation. It prevents
+   to call one time live() to retreive the perceptions and one more time to
+   compute the influences.
+ * Fixing several Java warnings.
+
+ -- Stephane GALLAND <galland@xxxxxxxxxxx> Mon, 30 Mar 2009 09:16:51 +0200
+
+tinyMAS-6.4
+
+ * Bug fix: the kernel always use the localhost as IP address.
+
+ -- Stephane GALLAND <galland@xxxxxxxxxxx> Tue, 09 Dec 2008 18:54:35 +0100
+
+tinyMAS-6.3
+
+ * Do not translate to byte array the messages sent by network connexion. Use
+   the Java object serialization insteed.
+ * Bug Fix: accept only one connexion from a remote kernel according to the
+   source code changes in version 6.2.
+
+ -- Stephane GALLAND <galland@xxxxxxxxxxx> Fri, 28 Nov 2008 15:11:22 +0100
+
+tinyMAS-6.2
+
+ * Do not open a socket each time a message must be sent.
+
+ -- Stephane GALLAND <galland@xxxxxxxxxxx> Thu, 27 Nov 2008 10:11:04 +0100
+
+tinyMAS-6.1
+
+ * Make the message box synchronized to avoid as most as possible
+   the ConcurrentSynchronizationError.
+
+ -- Stephane GALLAND <galland@xxxxxxxxxxx> Wed, 10 Jun 2008 14:20:00 +0200
+
+tinyMAS-6.0
+
+ * The getPerceptions() function now returns a list of perceptions
+   instead of an array of perceptions. It avoids array convertion
+   exceptions.
+
+ -- Stephane GALLAND <galland@xxxxxxxxxxx> Wed, 4 Jun 2008 14:50:00 +0200
+
+tinyMAS-5.0
+
+ * Bug fix in SituatedAgent.java and PerceptionInterestFilter.java:
+   when the environment has computed an empty perception, the
+   filter stays in the same state, ie. the old perceptions
+   are leaves unchanged in the filter.
+
+ -- Stephane GALLAND <galland@xxxxxxxxxxx> Thu, 15 May 2008 16:46:00 +0200
+
+tinyMAS-4.0
+
+ * Add SimulationClock.perTimeUnit() functions that permits to
+   adapt a value according to the progression of time on the simulator.
+
+ -- Stephane GALLAND <galland@xxxxxxxxxxx> Fri, 14 Mar 2008 08:26:00 +0100
+
+tinyMAS-3.0
+
+ * Move the environment scheduling algorithm from Kernel to Scheduler.
+ * Add log messages inside the network transport service.
+ * Add the SimulationClock interface that provides a way to obtain the
+   current simulation time.
+ * Remove the simulation time functions from the environment
+ * Rename the kernel step functions to avoid use conflict with simulation time functions
+
+ -- Stephane GALLAND <galland@xxxxxxxxxxx> Mon, 31 Dec 2007 11:32:10 +0100
+
+tinyMAS-2.0
+
+ * Fix the situated environment API
+ * Add the third prey-predator demo based on a situated environment.
+ * Fix the prey-predator behavior in the second demo.
+
+ -- Stephane GALLAND <galland@xxxxxxxxxxx> Sat, 17 Nov 2007 23:11:59 +0100
+
+tinyMAS-1.0
+
+ * First public release.
+
+ -- Stephane GALLAND <galland@xxxxxxxxxxx>

Added: trunk/tinymas-kernel/src/main/resources/LGPL.html
===================================================================
--- trunk/tinymas-kernel/src/main/resources/LGPL.html	                        (rev 0)
+++ trunk/tinymas-kernel/src/main/resources/LGPL.html	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,170 @@
+<!DOCTYPE html PUBLIC "-//IETF//DTD HTML 2.0//EN">
+<html>
+<head>
+  <title>GNU Lesser General Public License</title>
+  <link rev="made" href="mailto:webmasters@xxxxxxxxxxx";>
+</head>
+<body style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);"
+ alink="#ff0000" link="#1f00ff" vlink="#9900dd">
+<h2 style="text-align: center;">GNU LESSER GENERAL PUBLIC LICENSE</h2>
+<p style="text-align: center;">
+Version 2.1, February 1999
+</p>
+<pre>Copyright (C) 1991, 1999 Free Software Foundation, Inc.<br>51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA<br>
+Everyone is permitted to copy and distribute verbatim copies<br>
+of this license document, but changing it is not allowed.<br>
+<br>
+[This is the first released version of the Lesser GPL.<br>
+It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.]<br></pre>
+<h2>Preamble</h2>
+<p> The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users.</p>
+<p> This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below.</p>
+<p> When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things.</p>
+<p> To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it.</p>
+<p> For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights.</p>
+<p> We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library.</p>
+<p> To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others.</p>
+<p> Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license.</p>
+<p> Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs.</p>
+<p> When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library.</p>
+<p> We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances.
+</p>
+<p> For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free oftware only, so we use the Lesser General Public License. 
+</p>
+<p> In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system.
+</p>
+<p> Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library.</p>
+<p> The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run.</p>
+<h2>TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</h2>
+<p>
+<strong>0.</strong>
+This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you".
+</p>
+<p> A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables.</p>
+<p> The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".)
+</p>
+<p> "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library.
+</p>
+<p> Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does.
+</p>
+<p><strong>1.</strong>
+You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library.
+</p>
+<p> You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.
+</p>
+<p><strong>2.</strong>
+You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and  distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:
+</p>
+<ul>
+  <li><strong>a)</strong> The modified work must itself be a software library. </li>
+  <li><strong>b)</strong> You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. </li>
+  <li><strong>c)</strong> You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. </li>
+  <li><strong>d)</strong> If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful.
+    <p> (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) </p>
+    <p> These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. </p>
+    <p> Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. </p>
+    <p> In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. </p>
+  </li>
+</ul>
+<p>
+<strong>3.</strong>
+You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices.
+</p>
+<p> Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy.
+</p>
+<p> This option is useful when you wish to copy part of the code of the Library into a program that is not a library.
+</p>
+<p><strong>4.</strong>
+You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange.
+</p>
+<p> If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code.
+</p>
+<p><strong>5.</strong>
+A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License.
+</p>
+<p> However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables.
+</p>
+<p> When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law.
+</p>
+<p> If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.)
+</p>
+<p> Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself.
+</p>
+<p><strong>6.</strong>
+As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications.
+</p>
+<p> You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things:
+</p>
+<ul>
+  <li><strong>a)</strong> Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) </li>
+  <li><strong>b)</strong> Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. </li>   <li><strong>c)</strong> Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. </li>
+  <li><strong>d)</strong> If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. </li>
+  <li><strong>e)</strong> Verify that the user has already received a copy of these materials or that you have already sent this user a copy.
+  </li>
+</ul>
+<p> For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.
+</p>
+<p> It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute.
+</p>
+<p><strong>7.</strong> You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things:
+</p>
+<ul>
+  <li><strong>a)</strong> Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. </li>
+  <li><strong>b)</strong> Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. </li>
+</ul>
+<p>
+<strong>8.</strong> You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
+</p>
+<p><strong>9.</strong>
+You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it.
+</p>
+<p><strong>10.</strong>
+Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License.
+</p>
+<p><strong>11.</strong>
+If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library.
+</p>
+<p>If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances.
+</p>
+<p>It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of  any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willingto distribute software through any other system and a licensee cannot impose that choice.
+</p>
+<p>This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.
+</p>
+<p><strong>12.</strong>
+If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus  xcluded. In such case, this License incorporates the limitation as if written in the body of this License.
+</p>
+<p><strong>13.</strong>
+The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
+</p>
+<p>Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation.
+</p>
+<p><strong>14.</strong>
+If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.
+</p>
+<p><strong>NO WARRANTY</strong>
+</p>
+<p><strong>15.</strong>
+BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+</p>
+<p><strong>16.</strong>
+IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND  OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+</p>
+<h2>END OF TERMS AND CONDITIONS</h2>
+<h2>How to Apply These Terms to Your New Libraries</h2>
+<p> If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License).
+</p>
+<p> To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.
+</p>
+<pre><var>one line to give the library's name and an idea of what it does.</var><br>Copyright (C) <var>year</var>  <var>name of author</var><br><br>This library is free software; you can redistribute it and/or<br>modify it under the terms of the GNU Lesser General Public<br>License as published by the Free Software Foundation; either<br>version 2.1 of the License, or (at your option) any later version.<br><br>This library is distributed in the hope that it will be useful,<br>but WITHOUT ANY WARRANTY; without even the implied warranty of<br>MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU<br>Lesser General Public License for more details.<br><br>You should have received a copy of the GNU Lesser General Public<br>License along with this library; if not, write to the Free Software<br>Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA<br></pre>
+<p>
+Also add information on how to contact you by electronic and paper mail.
+</p>
+<p>You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names:
+</p>
+<pre>Yoyodyne, Inc., hereby disclaims all copyright interest in<br>the library `Frob' (a library for tweaking knobs) written<br>by James Random Hacker.<br><br><var>signature of Ty Coon</var>, 1 April 1990<br>Ty Coon, President of Vice<br></pre>
+<p>
+That's all there is to it!&nbsp;<!-- timestamp end -->
+</p>
+</body>
+</html>

Added: trunk/tinymas-kernel/src/main/resources/README
===================================================================
--- trunk/tinymas-kernel/src/main/resources/README	                        (rev 0)
+++ trunk/tinymas-kernel/src/main/resources/README	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,32 @@
+The Tiny Multiagent Platform is a very small platform which permits to implement and run multiagent systems.
+
+This platform was written by Stéphane GALLAND and Nicolas GAUD for the multiagent courses of the Computer Science Department of the University of Technology of Belfort-Montbéliard.
+
+------------
+Sub-projects
+------------
+
+The Tiny Multiagent Platform contains the following projects:
+
+ * org.arakhne.tinyMAS.core: the core implementation of the platform including kernel,
+   scheduler, white pages, yellow pages, agents, environment, influence and perception.
+ * org.arakhne.tinyMAS.network: an extension of the tinyMAS platform that supports
+   kernels distributed on a network.
+ * org.arakhne.tinyMAS.situatedEnvironment: an extension of the tinyMAS core platform
+   that provides features for situated environments: environment, body, perception and influence.
+ * org.arakhne.tinyMAS.demo: demos that illustrates several features of the tinyMAS
+   platform. 
+
+-----
+Links
+-----
+
+ * Official webpage: http://www.arakhne.org/tinyMAS/
+ * Javadoc: http://www.arakhne.org/tinyMAS/doc/ 
+
+-------
+License
+-------
+
+TinyMAS is distributed under the GNU Lesser General License.
+Copyright (c) 2005-2007 Stéphane GALLAND and Nicolas GAUD

Added: trunk/tinymas-kernel/src/main/resources/VERSION
===================================================================
--- trunk/tinymas-kernel/src/main/resources/VERSION	                        (rev 0)
+++ trunk/tinymas-kernel/src/main/resources/VERSION	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1 @@
+tinyMAS 6.6

Added: trunk/tinymas-network/pom.xml
===================================================================
--- trunk/tinymas-network/pom.xml	                        (rev 0)
+++ trunk/tinymas-network/pom.xml	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd";>
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+	<artifactId>project</artifactId>
+	<groupId>org.arakhne.tinymas</groupId>
+	<version>1.0-SNAPSHOT</version>
+  </parent>
+
+  <groupId>org.arakhne.tinymas</groupId>
+  <artifactId>tinymas-network</artifactId>
+  <packaging>jar</packaging>
+  <version>${version_tinymas_network}</version>
+  <name>TinyMAS network module</name>
+  <url>http://www.arakhne.org/tinymas/</url>
+
+	<!-- ======================================= -->
+	<!-- ====       Project Information      === -->
+	<!-- ======================================= -->
+		
+	<scm>
+		<url>http://www.arakhne.org/websvn.php?project=tinymas&amp;subproject=network</url>
+	</scm>
+	
+	<dependencies>
+		<dependency>
+			<groupId>org.arakhne.tinymas</groupId>
+			<artifactId>tinymas-kernel</artifactId>
+		</dependency>
+	</dependencies>
+
+</project>

Added: trunk/tinymas-network/src/main/java/org/arakhne/tinyMAS/network/KernelMessage.java
===================================================================
--- trunk/tinymas-network/src/main/java/org/arakhne/tinyMAS/network/KernelMessage.java	                        (rev 0)
+++ trunk/tinymas-network/src/main/java/org/arakhne/tinyMAS/network/KernelMessage.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,76 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.network;
+
+import java.io.Serializable;
+
+import org.arakhne.tinyMAS.core.AgentIdentifier;
+import org.arakhne.tinyMAS.core.Identifier;
+import org.arakhne.tinyMAS.core.KernelIdentifier;
+
+
+/** Low level messages exchanged by kernels.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ * @author Nicolas GAUD &lt;nicolas.gaud@xxxxxxx&gt;
+ */
+class KernelMessage implements Serializable {
+
+	private static final long serialVersionUID = -6655160153599661898L;
+
+	public enum Type {
+		YELLOW_PAGE_REGISTERING,
+		YELLOW_PAGE_UNREGISTERING,
+		KERNEL_PRESENTATION,
+		KERNEL_PRESENTATION_ACK,
+		KERNEL_DELETION;
+	}
+	
+	public final Class<?> TARGET;
+	
+	public final Type TYPE;
+	
+	public final String SERVICE; 
+	
+	public final Identifier IDENTIFIER; 
+
+	public KernelMessage(Class<?> target, Type type, String service, AgentIdentifier agent) {
+		assert(target!=null);
+		assert(type!=null);
+		assert((service!=null)&&(!"".equals(service))); //$NON-NLS-1$
+		assert(agent!=null);
+		this.TARGET = target;
+		this.TYPE = type;
+		this.SERVICE = service;
+		this.IDENTIFIER = agent;
+	}
+		
+	public KernelMessage(Type type, KernelIdentifier kernel) {
+		assert(type!=null);
+		assert(kernel!=null);
+		this.TARGET = null;
+		this.TYPE = type;
+		this.SERVICE = null;
+		this.IDENTIFIER = kernel;
+	}
+
+}
\ No newline at end of file

Added: trunk/tinymas-network/src/main/java/org/arakhne/tinyMAS/network/MTSBasedYellowPages.java
===================================================================
--- trunk/tinymas-network/src/main/java/org/arakhne/tinyMAS/network/MTSBasedYellowPages.java	                        (rev 0)
+++ trunk/tinymas-network/src/main/java/org/arakhne/tinyMAS/network/MTSBasedYellowPages.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,170 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.network;
+
+import org.arakhne.tinyMAS.core.AgentIdentifier;
+import org.arakhne.tinyMAS.core.Kernel;
+import org.arakhne.tinyMAS.core.KernelIdentifier;
+import org.arakhne.tinyMAS.core.YellowPages;
+
+/** This yellow page system uses the Message Transport Service
+ * to synchronise the service's list along a set of kernel.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ * @author Nicolas GAUD &lt;nicolas.gaud@xxxxxxx&gt;
+ */
+public class MTSBasedYellowPages extends YellowPages {
+
+	/** Register a service provided by the specified agent.
+	 * 
+	 * @param service is the name of the service.
+	 * @param agent is the agent that provides the service
+	 */	
+	@Override
+	public void registerService(String service, AgentIdentifier agent) {
+		assert((service!=null)&&(!"".equals(service))); //$NON-NLS-1$
+		assert(agent!=null);
+		super.registerService(service,agent);
+		// Informs the other kernels about this registration
+		Kernel<?,?,?,?> kernel = Kernel.getSingleton();
+		if (!kernel.isOnThisKernel(agent)) {
+			getMTS(NetworkMessageTransportService.class).broadcast(new KernelMessage(YellowPages.class,KernelMessage.Type.YELLOW_PAGE_REGISTERING,service,agent));
+		}
+	}
+
+	/** Remove the specified agent-service association. 
+	 * 
+	 * @param service is the name of the service.
+	 * @param agent is the agent that no more provides the service
+	 */
+	@Override
+	public void unregisterService(String service, AgentIdentifier agent) {
+		assert((service!=null)&&(!"".equals(service))); //$NON-NLS-1$
+		assert(agent!=null);
+		super.unregisterService(service,agent);
+		// Informs the other kernels about this registration
+		Kernel<?,?,?,?> kernel = Kernel.getSingleton();
+		if (!kernel.isOnThisKernel(agent)) {
+			getMTS(NetworkMessageTransportService.class).broadcast(new KernelMessage(YellowPages.class,KernelMessage.Type.YELLOW_PAGE_UNREGISTERING,service,agent));
+		}		
+	}
+
+	/** Remove a service from the system.
+	 * <p>
+	 * All associated agents will be unlinked to the specified service.
+	 */
+	@Override
+	public void unregisterService(String service) {
+		assert((service!=null)&&(!"".equals(service))); //$NON-NLS-1$
+		super.unregisterService(service);
+		// Informs the other kernels about this registration
+		getMTS(NetworkMessageTransportService.class).broadcast(new KernelMessage(YellowPages.class,KernelMessage.Type.YELLOW_PAGE_UNREGISTERING,service,null));
+	}
+
+	/** Remove the specified agent from the yellow pages.
+	 */
+	@Override
+	public void unregisterServices(AgentIdentifier agent) {
+		assert(agent!=null);
+		super.unregisterServices(agent);
+		// Informs the other kernels about this registration
+		Kernel<?,?,?,?> kernel = Kernel.getSingleton();
+		if (!kernel.isOnThisKernel(agent)) {
+			getMTS(NetworkMessageTransportService.class).broadcast(new KernelMessage(YellowPages.class,KernelMessage.Type.YELLOW_PAGE_UNREGISTERING,null,agent));
+		}		
+	}
+
+	/** Invoked by the kernel to treat a low-level message.
+	 */
+	void onKernelMessage(KernelMessage msg) {
+		assert(msg!=null);
+		NetworkMessageTransportService mts = getMTS(NetworkMessageTransportService.class);
+		switch(msg.TYPE) {
+		
+		case YELLOW_PAGE_REGISTERING:
+			if ((msg.IDENTIFIER!=null)&&
+				(msg.SERVICE!=null)&&
+				(!isRegisteredAgent(msg.SERVICE,(AgentIdentifier)msg.IDENTIFIER))) {
+				NetworkKernel.displayKernelMessage("Registration of " //$NON-NLS-1$
+						+msg.IDENTIFIER.toString()
+						+" for service " //$NON-NLS-1$
+						+msg.SERVICE);
+				registerService(msg.SERVICE,(AgentIdentifier)msg.IDENTIFIER);
+				mts.broadcast(msg);
+			}
+			break;
+			
+		case YELLOW_PAGE_UNREGISTERING:
+			if ((msg.IDENTIFIER!=null)&&
+				(msg.SERVICE!=null)&&
+				(isRegisteredAgent(msg.SERVICE,(AgentIdentifier)msg.IDENTIFIER))) {
+				NetworkKernel.displayKernelMessage("Unregistration of " //$NON-NLS-1$
+						+msg.IDENTIFIER.toString()
+						+" for service " //$NON-NLS-1$
+						+msg.SERVICE);
+				unregisterService(msg.SERVICE,(AgentIdentifier)msg.IDENTIFIER);
+				mts.broadcast(msg);
+			}
+			else if ((msg.IDENTIFIER==null)&&
+					 (msg.SERVICE!=null)&&
+					 (isRegisteredService(msg.SERVICE))) {
+				NetworkKernel.displayKernelMessage("Unregistration of the service " //$NON-NLS-1$
+						+msg.SERVICE);
+				unregisterService(msg.SERVICE);
+				mts.broadcast(msg);
+			}
+			else if ((msg.IDENTIFIER!=null)&&
+					 (msg.SERVICE==null)&&
+					 (isRegisteredAgent((AgentIdentifier)msg.IDENTIFIER))) {
+				NetworkKernel.displayKernelMessage("Unregistration of the agent " //$NON-NLS-1$
+						+msg.SERVICE
+						+" for all there services"); //$NON-NLS-1$
+				unregisterServices((AgentIdentifier)msg.IDENTIFIER);
+				mts.broadcast(msg);
+			}
+			break;
+			
+		case KERNEL_PRESENTATION:
+			if (msg.IDENTIFIER!=null) {
+				NetworkKernel.displayKernelMessage("Forwarding service definitions to " //$NON-NLS-1$
+						+msg.IDENTIFIER.toString());
+				String[] services = getAllServices();
+				for(int idxServ=0; idxServ<services.length; idxServ++) {
+					AgentIdentifier[] agents = getAgents(services[idxServ]);
+					for(int idxAg=0; idxAg<agents.length; idxAg++) {
+						KernelMessage m = new KernelMessage(
+								YellowPages.class,
+								KernelMessage.Type.YELLOW_PAGE_REGISTERING,
+								services[idxServ],
+								agents[idxAg]);
+						mts.send((KernelIdentifier)msg.IDENTIFIER,m);
+					}
+				}
+			}
+			break;
+
+		default:
+			// Ignore all other kernel messages
+		}
+	}
+
+}
\ No newline at end of file

Added: trunk/tinymas-network/src/main/java/org/arakhne/tinyMAS/network/NetworkKernel.java
===================================================================
--- trunk/tinymas-network/src/main/java/org/arakhne/tinyMAS/network/NetworkKernel.java	                        (rev 0)
+++ trunk/tinymas-network/src/main/java/org/arakhne/tinyMAS/network/NetworkKernel.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,124 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2007 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.network;
+
+
+import java.net.InetAddress;
+
+import org.arakhne.tinyMAS.core.Agent;
+import org.arakhne.tinyMAS.core.DefaultScheduler;
+import org.arakhne.tinyMAS.core.Environment;
+import org.arakhne.tinyMAS.core.Kernel;
+import org.arakhne.tinyMAS.core.Scheduler;
+
+/** Kernel of the TinyMAS application.
+ * <p>
+ * The kernel supports network communications.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public class NetworkKernel<AT extends Agent, ET extends Environment<AT>, YP extends MTSBasedYellowPages, MTS extends NetworkMessageTransportService> extends Kernel<AT, ET, YP, MTS> {
+
+	/** Create a kernel with the default components.
+	 */
+	@SuppressWarnings("unchecked")
+	public NetworkKernel(int socketPort) {
+		super(
+				(MTS)new NetworkMessageTransportService(socketPort), 
+				(YP)new MTSBasedYellowPages(), 
+				new DefaultScheduler<AT>());
+	}
+
+	/** Create a kernel with the default components.
+	 */
+	@SuppressWarnings("unchecked")
+	public NetworkKernel(int socketPort, InetAddress otherKernelAdr, int otherKernelPort) {
+		super(
+				(MTS)new NetworkMessageTransportService(socketPort, otherKernelAdr, otherKernelPort), 
+				(YP)new MTSBasedYellowPages(), 
+				new DefaultScheduler<AT>());
+	}
+
+	/** Create a kernel with the default components.
+	 */
+	@SuppressWarnings("unchecked")
+	public NetworkKernel(int socketPort, Scheduler<AT> scheduler) {
+		super(
+				(MTS)new NetworkMessageTransportService(socketPort), 
+				(YP)new MTSBasedYellowPages(), 
+				scheduler);
+	}
+
+	/** Create a kernel with the default components.
+	 */
+	@SuppressWarnings("unchecked")
+	public NetworkKernel(int socketPort, InetAddress otherKernelAdr, int otherKernelPort, Scheduler<AT> scheduler) {
+		super(
+				(MTS)new NetworkMessageTransportService(socketPort, otherKernelAdr, otherKernelPort), 
+				(YP)new MTSBasedYellowPages(), 
+				scheduler);
+	}
+
+	/** Create a kernel with the default components.
+	 */
+	public NetworkKernel(MTS netMTS, YP yellowPages, Scheduler<AT> scheduler) {
+		super(netMTS, yellowPages, scheduler);
+	}
+	
+	/** Create a kernel with the default components.
+	 */
+	public NetworkKernel(MTS netMTS, YP yellowPages) {
+		super(netMTS, yellowPages, new DefaultScheduler<AT>());
+	}
+
+	/** Create a kernel with the specified scheduler and message transport service.
+	 */
+	@SuppressWarnings("unchecked")
+	public NetworkKernel(MTS mts) {
+		super(
+				mts,
+				(YP)new MTSBasedYellowPages(),
+				new DefaultScheduler<AT>());
+	}
+
+	/** Create a kernel with the specified scheduler and message transport service.
+	 */
+	@SuppressWarnings("unchecked")
+	public NetworkKernel(MTS mts, Scheduler<AT> scheduler) {
+		super(
+				mts,
+				(YP)new MTSBasedYellowPages(),
+				scheduler);
+	}
+
+	/** Kernel log.
+	 */
+	protected static void displayKernelMessage(String msg) {
+		Kernel.displayKernelMessage(msg);
+	}
+	
+	@SuppressWarnings("unchecked")
+	public static NetworkKernel<?,?,? extends MTSBasedYellowPages, ? extends NetworkMessageTransportService> getSingleton() {
+		return (NetworkKernel<?,?,? extends MTSBasedYellowPages, ? extends NetworkMessageTransportService>)Kernel.getSingleton();
+	}
+
+}
\ No newline at end of file

Added: trunk/tinymas-network/src/main/java/org/arakhne/tinyMAS/network/NetworkMessageTransportService.java
===================================================================
--- trunk/tinymas-network/src/main/java/org/arakhne/tinyMAS/network/NetworkMessageTransportService.java	                        (rev 0)
+++ trunk/tinymas-network/src/main/java/org/arakhne/tinyMAS/network/NetworkMessageTransportService.java	2009-05-04 18:29:24 UTC (rev 1)
@@ -0,0 +1,340 @@
+/* 
+ * $Id$
+ * 
+ * Copyright (C) 2004-2009 St&eacute;phane GALLAND, Nicolas GAUD
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This program is free software; you can redistribute it and/or modify
+ */
+
+package org.arakhne.tinyMAS.network;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+
+import org.arakhne.tinyMAS.core.Kernel;
+import org.arakhne.tinyMAS.core.KernelIdentifier;
+import org.arakhne.tinyMAS.core.Message;
+import org.arakhne.tinyMAS.core.MessageTransportService;
+import org.arakhne.tinyMAS.core.YellowPages;
+
+/** This components extends the basic Message Transport Service
+ * with a network support.
+ * <p>
+ * This implementation of a MTS is able to communicated with
+ * other network MTS, ie other kernels.
+ * 
+ * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+ */
+public class NetworkMessageTransportService extends MessageTransportService {
+
+	protected final List<KernelIdentifier> __other_kernels = new ArrayList<KernelIdentifier>();
+	
+	private final InetAddress __other_kernel_adr;
+	private final int __other_kernel_port;
+	
+	protected final ServerSocket __server_socket;
+	protected final ExecutorService __server_thread;
+	
+	protected volatile boolean __mts_presented = false;
+	
+	private Map<String, Socket> sockets = new TreeMap<String, Socket>();
+
+	public NetworkMessageTransportService(int socket_port) {
+		this(socket_port,null,0);
+	}
+		
+	public NetworkMessageTransportService(int socket_port, InetAddress other_kernel_adr, int other_kernel_port) {
+		try {
+			this.__server_socket = new ServerSocket(socket_port);
+		}
+		catch (IOException e) {
+			throw new RuntimeException(e);
+		}
+		ThreadFactory factory = new ThreadFactory() {
+			public Thread newThread(Runnable r) {
+				Thread th = new Thread(r,
+						(r instanceof ConnexionListener) ?
+								"MTS listener" : //$NON-NLS-1$
+								"MTS message parser"); //$NON-NLS-1$
+				th.setDaemon(true);
+				return th;
+			}
+			
+		};
+		this.__server_thread = Executors.newCachedThreadPool(factory);
+		this.__other_kernel_adr = other_kernel_adr;
+		this.__other_kernel_port = other_kernel_port;
+	}
+
+	/** {@inheritDoc}
+	 */
+	@Override
+	protected KernelIdentifier getKernelId() {
+		return new KernelIdentifier(this.__server_socket.getLocalPort());
+	}
+
+	/** {@inheritDoc}
+	 */
+	void broadcast(KernelMessage m) {
+		assert(m!=null);
+		KernelIdentifier[] tab = new KernelIdentifier[this.__other_kernels.size()];
+		this.__other_kernels.toArray(tab);
+		
+		for(int i=0; i<tab.length; i++) {
+			send(tab[i],m);
+		}
+		
+		tab = null;
+	}
+
+	/** {@inheritDoc}
+	 */
+	boolean send(KernelIdentifier kernel, KernelMessage m) {
+		assert(kernel!=null);
+		assert(m!=null);
+		return sendSocket(
+				kernel.getKernelAddress().getAddress(),
+				kernel.getKernelAddress().getPort(),
+				m);
+	}
+
+	/** {@inheritDoc}
+	 */
+	@Override
+	public boolean send(Message m) {
+		assert(m!=null);
+		KernelIdentifier target_kernel = m.TO.getKernelId();
+		
+		// Check if the message is for a "local" agent
+		if (target_kernel.equals(Kernel.getSingleton().getKernelId())) {
+			return super.send(m);
+		}
+		
+		return sendSocket(
+				target_kernel.getKernelAddress().getAddress(),
+				target_kernel.getKernelAddress().getPort(),
+				m);
+	}
+
+	/** Send a message with a socket.
+	 */
+	protected boolean sendSocket(InetAddress adr, int port, Serializable m) {
+		assert(adr!=null);
+		String socketId = adr.getHostAddress()+":"+port; //$NON-NLS-1$
+		try {
+			//Get the kernel address of the kernel on which the target agent is located
+			//and open a socket to the other kernel
+			Socket socket = this.sockets.get(socketId);
+			if (socket==null) {
+				socket = new Socket(adr,port);
+				socket.shutdownInput();
+				this.sockets.put(socketId, socket);
+			}
+			
+			// Serialize the message
+			ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
+			oos.writeObject(m);
+			oos.flush();
+			
+			return true;
+		}
+		catch (IOException e) {
+			e.printStackTrace();
+			// Close the socket
+			this.sockets.remove(socketId);
+		}
+		return false;
+	}
+
+	/** {@inheritDoc}
+	 */
+	@Override
+	public void stopMTS() {
+		this.__server_thread.shutdownNow();
+		broadcast(new KernelMessage(KernelMessage.Type.KERNEL_DELETION,Kernel.getSingleton().getKernelId()));
+		this.__other_kernels.clear();
+	}
+	
+	/** {@inheritDoc}
+	 */
+	@Override
+	public void startMTS() {
+		NetworkKernel.displayKernelMessage("\tMTS listening on port " //$NON-NLS-1$
+				+this.__server_socket.getLocalPort());
+		this.__server_thread.submit(new ConnexionListener());
+		
+		
+		if (this.__other_kernel_adr!=null) {
+			NetworkKernel.displayKernelMessage("\twaiting for the ack of the community"); //$NON-NLS-1$
+			
+			sendSocket(
+					this.__other_kernel_adr,this.__other_kernel_port,
+					new KernelMessage(KernelMessage.Type.KERNEL_PRESENTATION,Kernel.getSingleton().getKernelId()));
+			while (!this.__mts_presented) {
+				// waiting
+				Thread.yield();
+			}
+		}
+	}
+
+	/** Socket server waiting for agent's messages.
+	 * 
+	 * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+	 * @author Nicolas GAUD &lt;nicolas.gaud@xxxxxxx&gt;
+	 */
+	class ConnexionListener implements Runnable {
+
+		public ConnexionListener() {
+			//
+		}
+		
+		public void run() {
+			while(true) {
+				try {
+					Socket client = NetworkMessageTransportService.this.__server_socket.accept();
+					
+					if (client!=null) {
+						NetworkMessageTransportService.this.__server_thread.submit(
+								new RemoteKernelListener(client));
+						client = null;
+					}
+				}
+				catch (IOException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+
+	}
+
+	/** Component that treat messages arriving form another kernel.
+	 * 
+	 * @author St&eacute;phane GALLAND &lt;galland@xxxxxxxxxxx&gt;
+	 * @author Nicolas GAUD &lt;nicolas.gaud@xxxxxxx&gt;
+	 */
+	class RemoteKernelListener implements Runnable {
+
+		private final Socket __client;
+		
+		public RemoteKernelListener(Socket client) {
+			assert(client!=null);
+			this.__client = client;
+		}
+		
+		public void run() {
+			try {
+				while (true) {
+			
+					// UnSerialize the message
+					ObjectInputStream oos = new ObjectInputStream(this.__client.getInputStream());
+					Object obj = oos.readObject();
+				
+					// Treat the red object
+					if ((obj!=null)&&
+						(obj instanceof Message)) {
+						treatAgentMessage((Message)obj);
+					}
+					else if ((obj!=null)&&
+							 (obj instanceof KernelMessage)) {
+						treatKernelMessage((KernelMessage)obj);
+					}
+				}
+			}
+			catch(Throwable _) {
+				// close the connexion silently
+				try {
+					this.__client.close();
+				}
+				catch(Throwable __) {
+					//
+				}
+			}
+		}
+		
+		/** Treating agent's message.
+		 */
+		@SuppressWarnings("synthetic-access")
+		protected void treatAgentMessage(Message msg) {
+			assert(msg!=null);
+			if (msg.TO.getKernelId().equals(Kernel.getSingleton().getKernelId())) {
+				// The message is for this kernel
+				NetworkMessageTransportService.this.registerInLocalBoxes(msg);
+			}
+			else {
+				NetworkKernel.displayKernelMessage("Ignoring network message from:"+msg.FROM.toString()); //$NON-NLS-1$
+			}
+		}
+
+		/** Treating low-level message.
+		 */
+		protected void treatKernelMessage(KernelMessage msg) {
+			assert(msg!=null);
+			switch(msg.TYPE) {
+			
+			case KERNEL_DELETION:
+				NetworkKernel.displayKernelMessage("Shutdown of the kernel " //$NON-NLS-1$
+						+msg.IDENTIFIER.toString());
+				NetworkMessageTransportService.this.__other_kernels.remove(msg.IDENTIFIER);
+				break;
+				
+			case KERNEL_PRESENTATION:
+				NetworkKernel.displayKernelMessage("Presentation of the kernel " //$NON-NLS-1$
+						+msg.IDENTIFIER.toString());
+				KernelIdentifier ki = (KernelIdentifier)msg.IDENTIFIER;
+				NetworkMessageTransportService.this.__other_kernels.add(ki);
+				NetworkMessageTransportService.this.sendSocket(
+						ki.getKernelAddress().getAddress(),
+						ki.getKernelAddress().getPort(),
+						new KernelMessage(KernelMessage.Type.KERNEL_PRESENTATION_ACK,
+								Kernel.getSingleton().getKernelId()));
+				NetworkKernel.getSingleton().getYellowPageSystem().onKernelMessage(msg);
+				break;
+				
+			case KERNEL_PRESENTATION_ACK:
+				NetworkKernel.displayKernelMessage("\tI'm beeing presented to the community"); //$NON-NLS-1$
+				NetworkMessageTransportService.this.__other_kernels.add((KernelIdentifier)msg.IDENTIFIER);
+				NetworkMessageTransportService.this.__mts_presented = true;
+				break;
+				
+			default:
+				try {
+					if ((msg.TYPE!=null)&&
+						(YellowPages.class.asSubclass(msg.TARGET)!=null)) {
+						NetworkKernel.getSingleton().getYellowPageSystem().onKernelMessage(msg);
+					}
+				}
+				catch(Exception _) {
+					//
+				}
+				break;
+			}
+		}
+
+	}
+
+}
\ No newline at end of file


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/